On Friday 09 September 2005 2:19 am, David Hampton wrote: > At the moment I know of no logic in the GUI that is not also enforced in > the engine.
It is only enforced by custom, not by code. e.g. It is perfectly possible to create an entity that has incomplete data and it is also perfectly acceptable to do so in certain situations. It is because each parameter of an instance can be set individually. The current GUI uses in-situ rules to validate the input - I'm looking at ideas on how this can be shared with the CLI, if only to prevent duplication. > These reason that these checks have been embedded in the > GUI code to enhance the user experience by providing immediate feedback. True - and I need the same in the CLI, not only to provide a familiar user experience but primarily to provide data integrity assurance. (Something that is clearly lacking in the current CashUtil.) > For example, a "bank" account must have a name and be denominated in a > currency not a stock. This is not coded in any part of the current Account object, it is coded in some internal functions but generally raises an assertion failure rather than a user error. > The account creation code in the engine should > enforce this (I have no idea if it does), It never has. It's back again to QOF not knowing the difference between accounts and watermelons. Only the object knows what an Account should contain and this is currently not tested by the engine. As CashUtil only *has* the engine and the objects, some of the logic in the current dialogs should be available in the object. Other rules may require different solutions. > but there's absolutely no > reason to wait until the user has filled out the entire dialog and > clicked the OK button before informing them about these restrictions. > It should be integrated into the dialog the user is filling out. For > example, the OK button on the dialog should not be enabled until after > the user has entered an account name. As far as I'm concerned, Gnucash > needs to do more of this, not less. OK - the same logic handler could be used for this validation. In the GUI it wouldn't have to wait for OK, it could -as now - be used to *enable* the button. That would provide a simple interface to maybe add the same principle to other dialogs. > > This is the extra layer that was discussed here some time ago > > Got a pointer? https://lists.gnucash.org/pipermail/gnucash-devel/2005-July/013379.html https://lists.gnucash.org/pipermail/gnucash-devel/2005-July/013397.html https://lists.gnucash.org/pipermail/gnucash-devel/2005-July/013378.html In time, I'll put some form of flow or control diagram together that we can pass round and improve. > Why would you want to allow incomplete objects to exist in the first > place? Data mining. This is implicit in the idea of partial books - a book that contains insufficient data for GnuCash to render as an account tree. This *could* just mean that it contains no AccountGroup objects. At the other extreme it could mean a book containing all transactions that match a SQL query and no accounts, groups or anything else. Merging this data back into GnuCash requires some form of data validation at the very least. I first came across this problem with qof_book_merge and it isn't fully solved. I had to implement two specific functions to iterate over the book after the merge and try to sort out the AccountGroup references. > All the required parameters for an object should be supplied > with the object is first created. In the GUI they are and always have been. However, this kind of validation could also be useful with other import mechanisms like QIF and OFX. > Cashutil doesn't accept multiple parameters at the same time? Not yet. It could accept a couple but it's still early days and the interface is not sufficiently complex yet. I'm trying to keep the underpinning shell generic (so that other QOF programs can use it) and CashUtil will then add specialised functions that support this kind of data entry: > E.G. > "create account type bank currency GBP parent xyz"? There is an implicit assumption in that line: You know that both currency and parent are considered "required". If you break that command down, it is: <command> <object> <parameter> data <parameter> data <parameter> data. What is missing is WHICH parameters are important: add account desc "test account" notes "dummy" code "why not?" Doesn't do the same job but - to the command parser - looks just the same. I want to add that functionality to CashUtil and it is exactly these assumptions and implicit "required" fields that need to be identifiable. I feel it best that the objects define such things themselves. The "required fields" for any object are completely object-specific and I'd like some generic way of defining such rules. It's not necessarily difficult - but it does require that all these rules are identified clearly. In order to make a sensible mechanism for such declarations, I need clear examples of this kind of rule - the more the merrier. I can do so much from direct observation of the current GUI but I'd like to provide some method of categorising and organising each one - if only to help express rules in other objects. > That command should > give you an object that passes the integrity checks for an account. All > other account fields are optional and can be checked when they are > added. Agreed. At present, none of this is known to QOF. Any parameter of any object is equally valid as any other, whether it contains a NULL or not. I'm seeking to be clear on what does and does not constitute a "required" parameter for each object. > I have no problem if you want to add validation functions for objects, > but I will object to any changes that make the GUI less responsive to > users. I'm seeking to help you make it MORE responsive, use validation more frequently in a standard and common manner so that you have a single function to call for each instance you want to verify - no matter what *type*. The UI developer should never have to worry whether their data integrity check has missed some inherent component of the object. Equally, these tests should NOT be re-implemented in multiple places - if the object is updated, it would be best to have the tests in one place. Also, the object is uniquely placed to do the tests themselves as many would involve access to private object variables. > If the handler is capable of eliciting more data from the user, then you > need two handlers. One for Gnucash and another for Cashutil. Each application uses their own. > How is > this any different that having the logic in the GUI and also in the > cashutil cli? The differences are: 1. The validation is always performed over the same parameters in all applications using the object. 2. The validation is performed in the same manner, using the same tests (as the tests live in the objects in this case) 3. It is the user feedback that is implemented differently in each case. The validation would return some kind of data struct that tells the UI what is wrong, if anything, and some information on what can be done to fix it. The application takes the data - from the object definition - and uses it to communicate with the user. In the case of the GUI by e.g. enabling a disabled OK button if successful etc. The logic itself - in the example of the account above - is specific to the Account object and can be handled in the object. It is not currently. > If you want consistency the handler should only validate > the object, not validate it and try to elicit missing information. Did I say that? I didn't mean that. The handler is in the application and it calls the object (with the instance) and asks if this constitutes a valid object - according to the logic inherent within the object. What I would like is that this is more than a simple gboolean - the object test routine should list the parameters or tests that failed and thereby provide some useful context for the handler (in the application) to use. UI -> data input Handler -> this is an instance of X object, call the logic test routine for X. Object -> receive the entity as is and run internal tests on validity. Object -> return success or data on reasons for failure Handler -> communicate any reasons for failure to the user or allow user to proceed. UI -> wait for next input. No matter where the data is entered, it should be easy to use exactly the same tests. > If > the object isn't valid the handler should return an error code to > indicate failure (or an bitmask to indicate what failed). Leave the > eliciting of data to the appropriate UI code. I was thinking of a little more data than just a bitmask - this could be enough when the application understands the object natively (i.e. the application developers understand the object) but I'd like to make it so that the same validation could be performed on a generic object. Let the object developer define the test routines and use those. It's much like the current test routines that are part of the build itself - whereas currently we have to think how to test each operation/object individually, these tests could be re-implemented and used within the program itself. -- Neil Williams ============= http://www.data-freedom.org/ http://www.nosoftwarepatents.com/ http://www.linux.codehelp.co.uk/
pgpyzkvYwGejo.pgp
Description: PGP signature
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel