Subject Re: [firebird-support] Re: server-side number formatting
Author David Johnson
On Tue, 2005-07-19 at 10:48 +0700, t.s. wrote:
> > Actually, in my opinion, you opened a rats nest...
> > A field should hold only one value. Not multiple values
> > depending on another column.
> Normally, I'd agree with this pov. But do you have a better suggestion
> on the Discount data model example ?
> I'm all ears.
>
> Thanks in advance,
> sugi.

At this point, it is moot. You have a framework that works for you.

The generic form of a contract line item is:

<<line item>> :: (<<direct cost>> * (1+<<percentage markup>>)) +
(<<fixed fee>>)

Where every clause of the formula is optional.


A transaction then becomes:

<<transaction>> :: list of ((<<direct cost>> * (1+<<percentage
markup>>)) + (<<fixed fee>>))

<<transaction value>> :: sum of ((<<direct cost>> * (1+<<percentage
markup>>)) + (<<fixed fee>>))


The phrasing of the formulation is indicative that the creator intended
it to be used for markup purposes, but it holds true as the general case
for discounting also, when either the <<percentage markup>> or the
<<fixed fee>> is negative.

The "Discount Data Model" merges the two terms for markup/down into a
single physical entity, which does not allow the possibility that all
terms may apply for a given line item. While this may hold true in the
pizza business, it is not true in the construction business. There are
businesses where the current datamodel will not be able to function.
The only question is are you interested in pursuing those businesses?
If not, then it comes down to mathematical purity versus money.
Generally speaking, money wins out.

During add/edit operations, these two fields are exposed directly via
> the table, with data aware controls. In this case, we're talking about
> one (db) edit box, and one (db) checkbox. Actually, the editing screen
> is created automatically by the framework, so no manual mucking around
> is required, which is part of the reason why the 'using non data aware
> control and override the behaviour' is considered 'too much work'.
>

You could have used a TClientDataset in briefcase mode with data aware
controls to buffer the Delphi app from the transactions. For display,
you do this (approximately):

transaction.start
try
fetch all rows into client dataset
transaction.commit
except
transaction.rollback
notify of error
end;


You now do all of your edits against the TClientDataset, which is an in-
memory copy of the information from the database that looks and behaves
like a TTABLE object, but it is much faster reacting. When the
transaction is ready to commit ...

transaction.start
try
post all row insert/update/deletes from TClientDataset into database

transaction.commit
except
transaction.rollback
notify of error
end;

With this application model, placing a buffer between you and the DBMS,
no manual "mucking around" is required and you never hold a transaction
open any longer than the minimum necessary to get the work done. You
can support many thousands of concurrent users with the application
instead of a few dozen (best guess).

Working directly with the TClientDataset delta property is sometimes
tricky because it's not well documented. But it's not too bad - the
"post all rwo ...." operation is a for loop with a nested case
statement.

Numerics are formatted for display only, in accordance with the client's
configured localization rules (aka Windows preferences). Otherwise,
they are numbers.