Thread: [Openledger-developer] Random jottings
Brought to you by:
klavs
From: Jacques C. <ja...@ch...> - 2005-03-19 00:49:30
|
Hello everyone; Some notes on OpenLedger. A: Project aims. Seem to be several, partly incompatible goals: 1. Improve SQL-Ledger development process and culture; 2. Separate SQL-Ledger frontend and backend code; 3. Create new Perl accounting API, using SQL-Ledger as backend, or as supply of snippets for backend; 4. Create new accounting applications. I would suggest that a final endgoal should be adopted. Is it: 1. A fully realised accounting suite - complete with front end implementation, 2. Backend modules for Perl, for accounting purposes, or 3. Pure SQL-Ledger fork. I suggest that your long term goal would be the full suite, probably implemented as a website and maybe in other forms for interested parties. An intermediate goal would be the creation of a Perl API for accounting software. I'm uncertain that purely forking SQL-Ledger code will be successful; you carry a lot of complexity across. Should an API map to SQL-L objects directly, or indirectly? B: On names and namespace issues I would say that "OpenLedger" would be used to name the project generally, and perhaps any complete "turnkey" suite produced in future. I would suggest that as an aid to understanding, backend Perl modules should not keep the OpenLedger name. I saw Business::Ledger and Business::Accounting suggested. These would fit with the subject-function naming convention common to many CPAN modules. C: On not reinventing wheels. It's customary in the early stages of new projects for everyone to spruik their favourite pet technology. Since I am a stickler for tradition, I would suggest that development take place using Chris Winter's OpenInteract2 perl application framework. OI2, which is nearly its point-oh release, is a heavyweight framework for perl applications, with a particular emphasis on web applications. The framework includes "free" logging, template support (for multiple templating engines), url-to-action resolution, a full MVC design pattern, CPAN-distributable plugins and applications, database persistance (included limited SQL abstraction), per-object security, and so much other neat stuff that my head hurts thinking about. Essentially it takes a lot of the useless grunt work out of writing perl applications. I've been tinkering with it a little, but I'll admit I'm no code god. It's been used for a few perl apps, but most of the work has been trivial example programs. I bet Chris would leap at the chance to help out on a more ambitious project to really put the system through its paces. Chris does most of the work on his own and is very, very well organised. He's written pages and pages of documentation, discusses his design decisions at length, and meticulously logs bugs and feature requests. http://www.openinteract.org/ The downside, as I intimated above, is that the framework is "heavyweight". That's enough from me. JC. |
From: David P. <dp...@he...> - 2005-03-19 01:30:09
|
On Sat, 2005-03-19 at 10:19 +0930, Jacques Chester wrote: > I suggest that your long term goal would be the full suite, > probably implemented as a website and maybe in other forms for > interested parties. Jacques, I appreciated the thoughtful analysis and suggests, I'd like to comment on them a bit later. The pronoun "your" was a bit off-putting at first and then a bit disappointing. I guess my question is what you see your role in the project as? And if not a role, than what your interest is, since I doubt you'd be reading the threads if you didn't have some interest. Thanks again though for the commentary, I think the project needs to do both code development and project self-management at the same time. David |
From: Jacques C. <ja...@ch...> - 2005-03-19 07:16:30
|
David Pool wrote: > On Sat, 2005-03-19 at 10:19 +0930, Jacques Chester wrote: > > >>I suggest that your long term goal would be the full suite, >>probably implemented as a website and maybe in other forms for >>interested parties. > > > Jacques, > > I appreciated the thoughtful analysis and suggests, I'd like to comment > on them a bit later. The pronoun "your" was a bit off-putting at first > and then a bit disappointing. I apologise if it was seen as talking down to anyone. I wrote in this sense: "Your common or garden variety daisy is white", rather than "Your daughter is troublesome". The former emphasis (where "Your" replaces "The" or "a") is common in Australian English, and is usually clear from the spoken context. The fault in communication is entirely mine. > I guess my question is what you see your > role in the project as? Interested commentator and loud smartypants. I'm involved in some clubs and societies, and I've occasionally looked for a better book keeping solution than our current spreadsheets, paper and the odd spot of gum and sticky tape. It would be nice to have a reasonable computer accounting package which was affordable and could integrate with existing and future systems. Further, for certain clubs the question of opensource licensing is important or even central. The thing that has always kept me back from SQL-Ledger is that it does not play well with other systems. As I say, I'm no coding guru but I like to tinker. The idea that I'll be stranded with little island fortresses of data bugs me. I'd rather not have to put up with it if I can. A decent API to SQL-Ledger, or in general, would make it possible to remove redundant information from various systems. > And if not a role, than what your interest is, > since I doubt you'd be reading the threads if you didn't have some > interest. I've toyed around with the idea of beating SQL-Ledger into a more CPANesque beast - in the context of my comments above - usually with OpenInteract as my preferred environment for doing so. Since this is a project well beyond my abilities, I figured it would be smarter to see if anyone else was doing similar. Here you are! :) > Thanks again though for the commentary, I think the project needs to do > both code development and project self-management at the same time. Maybe. The creation of code, any code, often forms the catalysing ingredient for success. As a casual perusal of Sourceforge demonstrates, projects which don't produce useful code early in life tend to fail. Opensource has a very strong Second System effect. JC. |
From: Klavs K. <kl...@vs...> - 2005-03-19 08:59:15
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/19/05 01:49 Jacques Chester wrote: | Hello everyone; | | Some notes on OpenLedger. | Always happy to hear feedback - and even more to receive code ;) | | A: Project aims. | | Seem to be several, partly incompatible goals: | | 1. Improve SQL-Ledger development process and culture; | 2. Separate SQL-Ledger frontend and backend code; | 3. Create new Perl accounting API, using SQL-Ledger as backend, or as | supply of snippets for backend; | 4. Create new accounting applications. | | I would suggest that a final endgoal should be adopted. Is it: | | 1. A fully realised accounting suite - complete with front end | implementation, | 2. Backend modules for Perl, for accounting purposes, or To me, those goals are not conflicting. | 3. Pure SQL-Ledger fork. | Pls. define a "pure" SQL-Ledger fork. IMHO it's simply taking the SL code and rewriting it. If that is what you mean, that has never been the goal of this project (in my mind :) IMHO SL is simply to weaved with the web-gui for it to be fixed. Therefore I've begun reimplementing the needed features in OpenLedger - and then anyone can do a SOAP, Web or other interface, which uses the OpenLedger functions. IMHO SL could be forked into a webinterface ONLY. | I suggest that your long term goal would be the full suite, | probably implemented as a website and maybe in other forms for | interested parties. Indeed it is. Especially if we want to expand the SL functionality (by enabling modules etc.) we need our own Web interface :) | | An intermediate goal would be the creation of a Perl API for | accounting software. | There is no way to make a "general Perl API for for accounting software" - - every accounting package differs, so it is only possible to write a Perl API for certain accounting packages. | I'm uncertain that purely forking SQL-Ledger code will be | successful; you carry a lot of complexity across. Should an API | map to SQL-L objects directly, or indirectly? | Agreed. That's why (as you can see clearly in CVS) I've begun reimplementing the features, reusing the parts of the code from SL, which belongs in the API. | B: On names and namespace issues | | I would say that "OpenLedger" would be used to name the project | generally, and perhaps any complete "turnkey" suite produced | in future. | | I would suggest that as an aid to understanding, backend Perl | modules should not keep the OpenLedger name. I saw | Business::Ledger and Business::Accounting suggested. These | would fit with the subject-function naming convention common to | many CPAN modules. IMHO in this case, that is a misleading naming policy, as there can be more than one Business::Ledger. OpenLedger or SL or any other, is not the only thing in the market - what is now OpenLedger.pm (API to SL "similar" DB/data) will never support every accounting package on earth - - and should as such, not be named as if it did. | | C: On not reinventing wheels. | | It's customary in the early stages of new projects for everyone | to spruik their favourite pet technology. Since I am a stickler | for tradition, I would suggest that development take place using | Chris Winter's OpenInteract2 perl application framework. | | OI2, which is nearly its point-oh release, is a heavyweight | framework for perl applications, with a particular emphasis on | web applications. | | The framework includes "free" logging, template support (for | multiple templating engines), url-to-action resolution, a | full MVC design pattern, CPAN-distributable plugins and | applications, database persistance (included limited SQL | abstraction), per-object security, and so much other neat stuff | that my head hurts thinking about. Essentially it takes a lot of | the useless grunt work out of writing perl applications. I've been | tinkering with it a little, but I'll admit I'm no code god. | | It's been used for a few perl apps, but most of the work | has been trivial example programs. I bet Chris would leap at | the chance to help out on a more ambitious project to really | put the system through its paces. | | Chris does most of the work on his own and is very, very | well organised. He's written pages and pages of documentation, | discusses his design decisions at length, and meticulously logs | bugs and feature requests. | | http://www.openinteract.org/ | | The downside, as I intimated above, is that the framework is | "heavyweight". | Currently I only have time to care about the API itself, upon which a web-gui, CRM/etc. systems integration etc. should happen. I would be very pleased if you would like to begin implementing a Web-frontend for the OpenLedger API. We could definetely use it - and perhaps with a GUI, ready to make use of features in the API - implementing the needed OpenLedger API features, would go faster :) - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCO+nnPToLeX4GPGIRAnJBAJ9DDsbQz2CyxKrTiX+IMhbqcBbpkgCgj1ch swDsMe3q5tLFRG8t2vNtSmA= =X38E -----END PGP SIGNATURE----- |
From: Klavs K. <kl...@vs...> - 2005-03-19 09:28:44
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/19/05 09:59 Klavs Klavsen wrote: [SNIP] | | I would suggest that as an aid to understanding, backend Perl | | modules should not keep the OpenLedger name. I saw | | Business::Ledger and Business::Accounting suggested. These | | would fit with the subject-function naming convention common to | | many CPAN modules. | | IMHO in this case, that is a misleading naming policy, as there can be | more than one Business::Ledger. OpenLedger or SL or any other, is not | the only thing in the market - what is now OpenLedger.pm (API to SL | "similar" DB/data) will never support every accounting package on earth | - and should as such, not be named as if it did. | I forgot to mention, that the Invoice, Item etc. objects could be used as general Business::Accounting::Invoice etc. module - as they should be generic. Also the fact that they are objects, would make them easier to expand, without disrupting others who use earlier versions, or less of their data/features :) [SNIP] - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCO/DAPToLeX4GPGIRAuHfAJ9KWesEpH83xYRVszzz1qM+9GNyZgCfTiaa TDYYpOF0IO/mdSwXPO3lMEs= =chm1 -----END PGP SIGNATURE----- |
From: Jacques C. <ja...@ch...> - 2005-03-19 11:04:37
|
Klavs Klavsen wrote: > I forgot to mention, that the Invoice, Item etc. objects could be used > as general Business::Accounting::Invoice etc. module - as they should be > generic. Also the fact that they are objects, would make them easier to > expand, without disrupting others who use earlier versions, or less of > their data/features :) Klav; This is what I was driving at - a generic namespace for modules of this type. Business::Accounts::Invoice is a good example. Eventually you could frame it as a DBD/DBI style thing, with drivers. For instance, you might write a Business::Accounts::Driver::SQL-Ledger which would be geared towards using SQL-L modules or even the database. This kind of architecture might encourage development in this field by presenting a uniform API for accounting information. Others might be left to introduce driver code for GNU Cash, and to some extent commercial packages such as Quickbooks. This would be a great boon to Perl programmers working in business environments. More glue, as it were. JC. |
From: Klavs K. <kl...@vs...> - 2005-03-19 11:21:18
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/19/05 12:04 Jacques Chester wrote: [SNIP] | Eventually you could frame it as a DBD/DBI style thing, | with drivers. For instance, you might write a | Business::Accounts::Driver::SQL-Ledger which would be | geared towards using SQL-L modules or even the database. | This kind of architecture might encourage development | in this field by presenting a uniform API for accounting | information. Others might be left to introduce driver | code for GNU Cash, and to some extent commercial | packages such as Quickbooks. | | This would be a great boon to Perl programmers working | in business environments. More glue, as it were. | Agreed. Perhaps you'd like to start this restructuring? Once it is done, we can register it on CPAN :) - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCPAsgPToLeX4GPGIRAqkqAJ4t/AIYoGyBcaLyv+k+dcFgeNSjMACdGAl/ rN0ag8KMqt7OQfS4sNreM7k= =ptbX -----END PGP SIGNATURE----- |
From: Jacques C. <ja...@ch...> - 2005-03-19 11:49:45
|
Klavs Klavsen wrote: > Perhaps you'd like to start this restructuring? > Once it is done, we can register it on CPAN :) Is this the bit where I turn out to be a flake who talks too much? Probably. :) Just spit balling a rough hierarchy (someone with more accounting nous would be a help in this bit) Business::Accounts:: Account ::Group ::Payable ::Receivable Chart Invoice Quote Order Transaction User ... Ledger:: Driver:: SQL-Ledger GNU-Cash ... In particular, the Ledger module (or Storage, or Backend, or whatever it should be called) would provide a generic interface for storage. So: Account ...Ledger ...Driver::SQL-Ledger | | | | | | ->commit() | | | | | +------------>commit($self) | | | | | +--------------->commit($account) . . . Most of the magic involved in a driver is mapping the internal data of a given object to its particular backend. For SQL-Ledger that would involve, one can suppose, direct intervention with the database. For GNU cash it would spit out XML, and so on. The later advantage of this overall approach is that it would provide a rough n ready migration path between accounting tools. Load data from system A, switch drivers, commit everything to B. Some of this might reusable from existing persistence frameworks. OpenInteract relies on SPOPS, but there are other ones around (like Class::DBI). JC. |
From: Tony F. <to...@sy...> - 2005-03-19 21:27:58
|
On Sat, 2005-03-19 at 03:49, Jacques Chester wrote: > Klavs Klavsen wrote: > > Perhaps you'd like to start this restructuring? > > Once it is done, we can register it on CPAN :) > > Is this the bit where I turn out to be a flake who talks > too much? Probably. :) hmm... I guess this is the place where I get off my butt and get around to contributing the UML I said I would ages ago. I finally uploaded it. You can have quick look here: http://openledger.sf.net/Business-Ledger/class_diagram.png Or you can download the Dia source here: http://openledger.sf.net/Business-Ledger/class_diagram.dia > Just spit balling a rough hierarchy (someone with more > accounting nous would be a help in this bit) > > > Business::Accounts:: > Account > ::Group > ::Payable > ::Receivable > Chart > Invoice > Quote > Order > Transaction > User > ... > Ledger:: > Driver:: > SQL-Ledger > GNU-Cash > ... > > In particular, the Ledger module (or Storage, or Backend, > or whatever it should be called) would provide a generic > interface for storage. So: > > > Account ...Ledger ...Driver::SQL-Ledger > | | | > | | | > ->commit() | | > | | | > +------------>commit($self) | > | | | > | +--------------->commit($account) > . . . > > Most of the magic involved in a driver is mapping the > internal data of a given object to its particular backend. > For SQL-Ledger that would involve, one can suppose, direct > intervention with the database. For GNU cash it would > spit out XML, and so on. This is basically the same approach I took. I just have a few slightly different names. Like I chose Backend instead of Driver. -- Tony Fraser to...@sy... Sybaspace Internet Solutions System Administrator phone: (250) 246-5368 fax: (250) 246-5398 |
From: Tony F. <to...@sy...> - 2005-03-20 21:14:23
|
On Sat, 2005-03-19 at 13:27, Tony Fraser wrote: > hmm... I guess this is the place where I get off my butt and get around > to contributing the UML I said I would ages ago. > > I finally uploaded it. You can have quick look here: > > http://openledger.sf.net/Business-Ledger/class_diagram.png > > Or you can download the Dia source here: > > http://openledger.sf.net/Business-Ledger/class_diagram.dia As has been brought up on this list before, sometimes code is the best description. Here is an example script that posts a GL transaction using my fictional Business::Ledger API. #!/usr/bin/perl use strict; our $acct = Businss::Ledger->new( BACKEND => Business::Ledger::SQL_Ledger, OPTIONS => { PATH => /usr/local/sql-ledger } ); our $chart = $acct->get_coa(); # Open a GL Transaction my $gl_trans = $acct->start_transaction('Business::Ledger::Transaction::GL'); $gl_trans->reference('test'); $gl_trans->date('1-1-2005'); $gl_trans->description('This is a test GL entry'); # Add some amounts $gl_trans->post_debit($chart->find_account( number => '1820' ), '55.00'); $gl_trans->post_debit($chart->find_account( number => '5700' ), '40.00'); $gl_trans->post_credit($chart->find_account( number => '1060' ), '95.00'); # Now all that's left is to post it. $gl_trans->post; -- Tony Fraser to...@sy... Sybaspace Internet Solutions System Administrator phone: (250) 246-5368 fax: (250) 246-5398 |
From: Klavs K. <kl...@vs...> - 2005-03-21 08:30:19
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/20/05 22:14 Tony Fraser wrote: | On Sat, 2005-03-19 at 13:27, Tony Fraser wrote: | |>hmm... I guess this is the place where I get off my butt and get around |>to contributing the UML I said I would ages ago. |> |>I finally uploaded it. You can have quick look here: |> |>http://openledger.sf.net/Business-Ledger/class_diagram.png |> |>Or you can download the Dia source here: |> |>http://openledger.sf.net/Business-Ledger/class_diagram.dia | | | As has been brought up on this list before, sometimes code is the best | description. Here is an example script that posts a GL transaction using | my fictional Business::Ledger API. | | | #!/usr/bin/perl | | use strict; | | | | our $acct = Businss::Ledger->new( | BACKEND => Business::Ledger::SQL_Ledger, | OPTIONS => { | PATH => /usr/local/sql-ledger | } | ); | our $chart = $acct->get_coa(); | Not bad. | | # Open a GL Transaction | my $gl_trans = $acct->start_transaction('Business::Ledger::Transaction::GL'); | hmm dividing them into GL etc. transactions.. I guess this is ok from the users point of view. Connecting/binding the transaction to the $acct object (which you do here - otherwise $gl_trans->post would not have known where to post) is IMHO bad. What if I have a transaction, I'd like to post in two different accounting systems? Or perhaps I have some code that uses the transaction object for "something else" (like generating a receipt or whatever)? I'd prefer having GL etc. as seperate objects (as we have now) - which the user who creates the objects, can decide to use for whatever they see fit - and then accept these as parameters for f.ex. post_transaction - - which could be made to accept both AR,AP and GL transactions. | $gl_trans->reference('test'); | $gl_trans->date('1-1-2005'); | $gl_trans->description('This is a test GL entry'); | | # Add some amounts | $gl_trans->post_debit($chart->find_account( number => '1820' ), '55.00'); | $gl_trans->post_debit($chart->find_account( number => '5700' ), '40.00'); | $gl_trans->post_credit($chart->find_account( number => '1060' ), '95.00'); Why not just use the accountnumber as referencenr.? Instead of having to find the account based on the accountnr.? The accountnr. is afterall always unique. If it wasn't unique, you couldn't trust find_account to find only one, and thus couldn't use it in the context you do here - as you wouldn't be sure which one you'd get. - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCPoYcPToLeX4GPGIRApEPAJ99XYDuRup4A8KTpS7JeyXotlIXmgCfSfq8 TMdbOA5DxIpOv4gLz+92dCw= =VTkl -----END PGP SIGNATURE----- |
From: Tony F. <to...@sy...> - 2005-03-21 20:50:15
|
On Mon, 2005-03-21 at 00:30, Klavs Klavsen wrote: > | > | # Open a GL Transaction > | my $gl_trans = > $acct->start_transaction('Business::Ledger::Transaction::GL'); > | > hmm dividing them into GL etc. transactions.. I guess this is ok from > the users point of view. Connecting/binding the transaction to the $acct > object (which you do here - otherwise $gl_trans->post would not have > known where to post) is IMHO bad. Bad? I would argue that it is good. In a web-gui environment it wouldn't matter one way or the other. HTTP is stateless and can't maintain things like DB connections between requests. Think of a Perl-Gtk app though, it would make sense to maintain a DB connection for each transaction, actually it would be mandatory in order to maintain transaction isolation. > What if I have a transaction, I'd like to post in two different > accounting systems? Or perhaps I have some code that uses the > transaction object for "something else" (like generating a receipt or > whatever)? Copying transactions from system to system would have to be allowed for. Using them for "something else" is fine What does the API care what you do with an object. > I'd prefer having GL etc. as seperate objects (as we have now) - which > the user who creates the objects, can decide to use for whatever they > see fit - and then accept these as parameters for f.ex. post_transaction > - - which could be made to accept both AR,AP and GL transactions. So you plan on putting the whole 20,000 lines of code that makes up the backend of SL (SL/*.pm) into one package? That sounds like an even worse maintenance problem than SL has now to me. BTW, I was looking at your code in CVS, Why don't you use Class::Accessor? You could write TransactionLine.pm as: -SNIP- package TransactionLine; use strict; use vars qw($VERSION); $VERSION = "0.1"; sub Version { $VERSION } use Class::Accessor; use base qw/Class::Accessor/; sub new { bless { }, shift; } TransactionLine->mk_accessors(qw/debit credit accNo/); 1; __END__ -SNIP- You get the idea (Copyright info removed for brevity). > | $gl_trans->reference('test'); > | $gl_trans->date('1-1-2005'); > | $gl_trans->description('This is a test GL entry'); > | > | # Add some amounts > | $gl_trans->post_debit($chart->find_account( number => '1820' ), '55.00'); > | $gl_trans->post_debit($chart->find_account( number => '5700' ), '40.00'); > | $gl_trans->post_credit($chart->find_account( number => '1060' ), '95.00'); > > Why not just use the accountnumber as referencenr.? Instead of having to > find the account based on the accountnr.? The accountnr. is afterall > always unique. > If it wasn't unique, you couldn't trust find_account to find only one, > and thus couldn't use it in the context you do here - as you wouldn't be > sure which one you'd get. The reason is because post_debit would take a reference to a account object and how that object reference is found is up to the user of the API. I could just have easily said: ( $chart->find_account( type => ASSET, name => "%Office Equipment%") )[0] to use the first account that is an asset account with "Office Equipment" in its name. -- Tony Fraser to...@sy... Sybaspace Internet Solutions System Administrator phone: (250) 246-5368 fax: (250) 246-5398 |
From: Klavs K. <kl...@vs...> - 2005-03-22 08:30:12
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/21/05 21:50 Tony Fraser wrote: [SNIP] | Bad? I would argue that it is good. In a web-gui environment it | wouldn't matter one way or the other. HTTP is stateless and can't | maintain things like DB connections between requests. Think of a | Perl-Gtk app though, it would make sense to maintain a DB | connection for each transaction, actually it would be mandatory in | order to maintain transaction isolation. To me it seems I'm doing the exact same thing? the client creates a new OpenLedger object, and at that point the a unique db connection is opened for that client. Used in a webgui environment, I agree that "almost" everytime it will not matter, as the webgui will only make 1 transaction pr. request. But it could do more than that - depending on the design. [SNIP] | Copying transactions from system to system would have to be allowed | for. Using them for "something else" is fine What does the API care | what you do with an object. But embedding the transaction object inside the $acct object, means the program that reuses the transaction object, has to use the $acct object too - and IMHO that is unnecessary. I see no advantage to embedding the transaction/invoice etc. objects inside the accounting object (so that you have to call the accounting object to create a transaction object) and IMHO it is a lot nicer, if I have the freedom to create a transaction, and then use the same object to post transactions to f.ex. two OpenLedger DB's. In your design, I do not have that freedom. My reasoning for creating seperate invoice/transaction/etc. objects, is also that programs interfacing with OpenLedger, could use the same objects for representing their "accounting" data internally - and thus make it much easier for them to use OpenLedger. An invoice is an invoice - no matter which system uses it :) |> I'd prefer having GL etc. as seperate objects (as we have now) - |> which the user who creates the objects, can decide to use for |> whatever they see fit - and then accept these as parameters for |> f.ex. post_transaction - - which could be made to accept both |> AR,AP and GL transactions. | | | So you plan on putting the whole 20,000 lines of code that makes up | the backend of SL (SL/*.pm) into one package? That sounds like an | even worse maintenance problem than SL has now to me. It could be seperate functions - or we could internally in OpenLedger - - split it out into sub-packages. To the user - it should IMHO be as simple as creating an OpenLedger object - and then calling it's methods/functions to do whatever they see fit. I see no reason to tie the data-structures (invoice, transaction etc.) to the OpenLedger object. | | BTW, I was looking at your code in CVS, Why don't you use | Class::Accessor? You could write TransactionLine.pm as: | | -SNIP- package TransactionLine; | | use strict; use vars qw($VERSION); | | $VERSION = "0.1"; sub Version { $VERSION } | | use Class::Accessor; use base qw/Class::Accessor/; | | sub new { bless { }, shift; } | | TransactionLine->mk_accessors(qw/debit credit accNo/); | | 1; __END__ -SNIP- | | You get the idea (Copyright info removed for brevity). Looks very interesting. I definetely agree that we should embrace that we are using GPL, and reuse every bit of code that is sensible to reuse. This def. seems to make the data objects smaller :) If you'd convert one of the objects - then I could use that as a working example :) [SNIP] | | The reason is because post_debit would take a reference to a | account object and how that object reference is found is up to the | user of the API. I could just have easily said: | | ( $chart->find_account( type => ASSET, name => "%Office | Equipment%") )[0] | | to use the first account that is an asset account with "Office | Equipment" in its name. I'll buy that - so have we an accountobject too :) - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCP9ePPToLeX4GPGIRAsSxAJ9MXXf4+ykhKok6d8HRV1+4RALPsACfRx8y HhcU3SIDSmim44zBnxKNddE= =2thp -----END PGP SIGNATURE----- |
From: Tony F. <to...@sy...> - 2005-03-22 17:15:56
|
On Tue, 2005-03-22 at 00:30, Klavs Klavsen wrote: > | Bad? I would argue that it is good. In a web-gui environment it > | wouldn't matter one way or the other. HTTP is stateless and can't > | maintain things like DB connections between requests. Think of a > | Perl-Gtk app though, it would make sense to maintain a DB > | connection for each transaction, actually it would be mandatory in > | order to maintain transaction isolation. > > To me it seems I'm doing the exact same thing? the client creates a > new OpenLedger object, and at that point the a unique db connection is > opened for that client. > Used in a webgui environment, I agree that "almost" everytime it will > not matter, as the webgui will only make 1 transaction pr. request. > But it could do more than that - depending on the design. > [SNIP] So if I'm using your API in a persistent environment (Gtk App, App Server, whatever) I would have to create a new OpenLedger object for each concurrent transaction I have running? > | Copying transactions from system to system would have to be allowed > | for. Using them for "something else" is fine What does the API care > | what you do with an object. > > But embedding the transaction object inside the $acct object, means > the program that reuses the transaction object, has to use the $acct > object too - and IMHO that is unnecessary. I see no advantage to > embedding the transaction/invoice etc. objects inside the accounting > object (so that you have to call the accounting object to create a > transaction object) and IMHO it is a lot nicer, if I have the freedom > to create a transaction, and then use the same object to post > transactions to f.ex. two OpenLedger DB's. In your design, I do not > have that freedom. > My reasoning for creating seperate invoice/transaction/etc. objects, > is also that programs interfacing with OpenLedger, could use the same > objects for representing their "accounting" data internally - and thus > make it much easier for them to use OpenLedger. An invoice is an > invoice - no matter which system uses it :) Ahh... Now I see your concern. It is IMHO unfounded but I see. If you look at the UML I posted Business::Ledger::Transaction::GL would be a standalone class and you are free to use it as such. Code is always good, here's a sudo implementation of the start_transaction sub: sub start_transaction { my $self = shift; my $trans_class = shift; UNIVERSAL::require($trans_class); my $trans_obj = new $trans_class ( BACKEND => $self->{_BACKEND}, ); return $trans_obj; } So you see, start_transaction would just be a convenience that passes standard parameters to the transactions constructor. > | So you plan on putting the whole 20,000 lines of code that makes up > | the backend of SL (SL/*.pm) into one package? That sounds like an > | even worse maintenance problem than SL has now to me. > > It could be seperate functions - or we could internally in OpenLedger > - - split it out into sub-packages. > To the user - it should IMHO be as simple as creating an OpenLedger > object - and then calling it's methods/functions to do whatever they > see fit. > I see no reason to tie the data-structures (invoice, transaction etc.) > to the OpenLedger object. > > | > | BTW, I was looking at your code in CVS, Why don't you use > | Class::Accessor? You could write TransactionLine.pm as: > | > | -SNIP- package TransactionLine; > | > | use strict; use vars qw($VERSION); > | > | $VERSION = "0.1"; sub Version { $VERSION } > | > | use Class::Accessor; use base qw/Class::Accessor/; > | > | sub new { bless { }, shift; } > | > | TransactionLine->mk_accessors(qw/debit credit accNo/); > | > | 1; __END__ -SNIP- > | > | You get the idea (Copyright info removed for brevity). > > Looks very interesting. I definetely agree that we should embrace that > we are using GPL, and reuse every bit of code that is sensible to > reuse. This def. seems to make the data objects smaller :) > If you'd convert one of the objects - then I could use that as a > working example :) I'll see if I have time to check something into CVS but the code above is a completely functional TransactionLine.pm. It is functionally identical to the one that is in CVS now I just removed the comments/copyright to make it more email friendly. Class::Accessor is a CPAN module you will have to install before it will work though. -- Tony Fraser to...@sy... Sybaspace Internet Solutions System Administrator phone: (250) 246-5368 fax: (250) 246-5398 |
From: Klavs K. <kl...@vs...> - 2005-03-23 08:18:11
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/22/05 18:15 Tony Fraser wrote: [SNIP] |So if I'm using your API in a persistent environment (Gtk App, App |Server, whatever) I would have to create a new OpenLedger object for |each concurrent transaction I have running? Yes (but usually in accounting each GUI has one user, there may be several computers running the same GUI - but then they'll have seperate objects/connections anyways, and thus performs one action at a time). IMHO that is better than having a connection for each transaction/invoice object. When searching for invoices, I was planning on returning an array of invoice-objects - ie. the resulting invoices. If we did that, a DB connection for each of them would be inevitable, and very ressource consuming. Ofcourse one could argue, we should define some sort of result-subset - - but, as the user needs to be able to define which data they want shown from the search, a function that either retrives it all - or a subset, as defined in the function call will be required. So the result-set needs to be able to represent everything from 1 to every data in an invoice/transaction/item etc., and thus it is IMHO best to just return an array of the objects in question. [SNIP] | |Ahh... Now I see your concern. It is IMHO unfounded but I see. | |If you look at the UML I posted Business::Ledger::Transaction::GL would |be a standalone class and you are free to use it as such. Code is always |good, here's a sudo implementation of the start_transaction sub: | |sub start_transaction { | my $self = shift; | my $trans_class = shift; | | UNIVERSAL::require($trans_class); | my $trans_obj = new $trans_class ( | BACKEND => $self->{_BACKEND}, | ); | | return $trans_obj; |} | |So you see, start_transaction would just be a convenience that passes |standard parameters to the transactions constructor. Ahh - Then I have no problem with that - except for one thing. The fact that you define a BACKEND on the invoice/transaction etc. object. But that I've argued in the above segment :) Having the BACKEND there, also means you can't just post the object to another OpenLedger object (or crm or whatever uses the same objects), as you'd have to redefine the BACKEND var in the object then. This can be done, but is IMHO object-orientation. I see no reason for the data-object to know anything about who uses it (ie. the BACKEND to which is from or will be posted too). [SNIP] | |I'll see if I have time to check something into CVS but the code above |is a completely functional TransactionLine.pm. It is functionally |identical to the one that is in CVS now I just removed the |comments/copyright to make it more email friendly. Class::Accessor is a |CPAN module you will have to install before it will work though. No problem. Just checkout the openledger source from CVS and alter as you see fit - - and do a cvs commit :) If any of you have problems with handling the CVS - pls. ask on the list, so I can help you. Remember to read the relevant parts of the SF cvs howto - it's very good and you can use their examples almost ad verbatim :) - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCQSY8PToLeX4GPGIRAhN3AJ917TxaPVS1BNSpkXbRCtGIu4bzlQCgjm+o nxwCof/bYVU3MsVQqoapqPM= =njVI -----END PGP SIGNATURE----- |
From: Tony F. <to...@sy...> - 2005-03-23 18:08:15
|
On Wed, 2005-03-23 at 00:18, Klavs Klavsen wrote: > |So if I'm using your API in a persistent environment (Gtk App, App > |Server, whatever) I would have to create a new OpenLedger object for > |each concurrent transaction I have running? > > Yes (but usually in accounting each GUI has one user, there may be > several computers running the same GUI - but then they'll have > seperate objects/connections anyways, and thus performs one action at > a time). IMHO that is better than having a connection for each > transaction/invoice object. So, say I'm writing a Tk based POS because I'm unhappy with the data entry rate of a web interface. Each POS machine is making conntions directly to the DB. Now, because customers are unpredictable creatures and often change their mind half way through a POS transaction I create a hold function. ie. Take the current transaction and set it aside and start a new transaction so the clerk can help the next person in line. Your saying that I would have to create a OpenLedger.pm object when I put a transaction on hold? > When searching for invoices, I was planning on returning an array of > invoice-objects - ie. the resulting invoices. If we did that, a DB > connection for each of them would be inevitable, and very ressource > consuming. That would be fine but the objects would have to be read only. And hence wouldn't have to have a backing DB connection. When the user decides on a particular invoice to edit, a new connection should be opened and an new DB transaction started by re-retrieving the invoice. Or you could just use a different (generic) ResultSet type object that only retrieves the fields that the user requests for the search in the fist place. > Ofcourse one could argue, we should define some sort of result-subset > - - but, as the user needs to be able to define which data they want > shown from the search, a function that either retrives it all - or a > subset, as defined in the function call will be required. So the > result-set needs to be able to represent everything from 1 to every > data in an invoice/transaction/item etc., and thus it is IMHO best to > just return an array of the objects in question. See above. -- Tony Fraser to...@sy... Sybaspace Internet Solutions System Administrator phone: (250) 246-5368 fax: (250) 246-5398 |
From: Klavs K. <kl...@vs...> - 2005-03-24 09:03:33
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 on 03/23/05 19:08 Tony Fraser wrote: [SNIP] | | So, say I'm writing a Tk based POS because I'm unhappy with the | data entry rate of a web interface. Each POS machine is making | conntions directly to the DB. Now, because customers are | unpredictable creatures and often change their mind half way | through a POS transaction I create a hold function. ie. Take the | current transaction and set it aside and start a new transaction so | the clerk can help the next person in line. | | Your saying that I would have to create a OpenLedger.pm object when | I put a transaction on hold? Ehh - why would that have ANYTHING to do with OpenLedger transactions? situations like that is helped, because the clerk is NOT going to "post" the transaction, before he actually finishes defining it (ie. filling the object) and has received payment from the customer. And if he puts a case on hold -that just means he'll put that "invoice/whatever-POS" object aside, and then perhaps post it to OpenLedger, when he finalizes the transaction. Starting a db-transaction at all, before every data has been collected, and the clerk is actually certain it needs to be done, is simply a waste of time, and IMHO bad practice. |> When searching for invoices, I was planning on returning an array |> of invoice-objects - ie. the resulting invoices. If we did that, |> a DB connection for each of them would be inevitable, and very |> ressource consuming. | | | That would be fine but the objects would have to be read only. And | hence wouldn't have to have a backing DB connection. When the user | decides on a particular invoice to edit, a new connection should be | opened and an new DB transaction started by re-retrieving the | invoice. | I don't like that the object should have it's own db-connection, and if it hasn't, there's no need for the code to re-retrive the invoice once it is seeked to be editted. I would prefer it be posted to an "invoiceEdit" function, and then the invoicenr is used as the ref. and the old invoice is removed, and the new one posted. Making the code having to re-retrive the invoice, and then do the exact same thing they could have done to the original object makes no sense. The code using the OpenLedger API should be able to alter the invoices, as they see fit. Even if you "try" to make it more troublesome, by forcing them to re-retrive it, they can still do the exact same things, which just means its a waste of code, and unnecessarily troublesome to work with. | Or you could just use a different (generic) ResultSet type object | that only retrieves the fields that the user requests for the | search in the fist place. We could. But seeing as how we need to fetch and search the DB anyways, and chances are they need the invoice-object, we might as well fetch them all as invoice-objects, and then they can simply pull out the invoice from the array, that they want to work with. Don't like to have more datatypes or different types of resultsets, if it isn't necessary. In short, I'd like to make it as simple as possible - and don't force complexity on it, that does not need to be there. Then we can always alter/enhance the code, if we find something needs to be rethought, but I doubt we'll actually see the "right way" before having tried and learned - and that's why I prefer the KISS approach :) - a simple design (and mind you, simple is not necessarily bad - it is most often - - also in security, a good thing) will also make it easier/quicker for us to get OpenLedger off the ground. You totally missed commenting on: Ahh - Then I have no problem with that - except for one thing. The fact that you define a BACKEND on the invoice/transaction etc. object. But that I've argued in the above segment :) Having the BACKEND there, also means you can't just post the object to another OpenLedger object (or crm or whatever uses the same objects), as you'd have to redefine the BACKEND var in the object then. This can be done, but is IMHO object-orientation. I see no reason for the data-object to know anything about who uses it (ie. the BACKEND to which is from or will be posted too). - -- Regards, Klavs Klavsen, GSEC - kl...@vs... - http://www.vsen.dk PGP: 7E063C62/2873 188C 968E 600D D8F8 B8DA 3D3A 0B79 7E06 3C62 "Those who do not understand Unix are condemned to reinvent it, poorly." ~ --Henry Spencer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCQoJrPToLeX4GPGIRAouHAJ9VIbms5kk9gpMYjVWOLeW+4sRylwCfalHX 4mvTrYS21Q1x3VlmvD3Zr9I= =1ipI -----END PGP SIGNATURE----- |