File Coverage

blib/lib/Business/AU/Ledger.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Business::AU::Ledger;
2              
3 1     1   25976 use base 'CGI::Application';
  1         2  
  1         1292  
4 1     1   15038 use strict;
  1         2  
  1         31  
5 1     1   5 use warnings;
  1         3  
  1         28  
6              
7 1     1   770 use Business::AU::Ledger::Database;
  0            
  0            
8             use Business::AU::Ledger::Util::Config;
9             use Business::AU::Ledger::View;
10              
11             use CGI::Session;
12             use DBIx::Simple;
13              
14             use Hash::FieldHash qw(:all);
15              
16             fieldhash my %config => 'config';
17             fieldhash my %db => 'db';
18             fieldhash my %session => 'session';
19             fieldhash my %simple => 'simple';
20             fieldhash my %view => 'view';
21              
22             our $VERSION = '0.88';
23              
24             # -----------------------------------------------
25              
26             sub initialize_payments
27             {
28             my($self) = @_;
29              
30             $self -> log(__PACKAGE__ . '. Leaving initialize_payments');
31              
32             return $self -> view -> payment -> initialize;
33              
34             } # End of initialize_payments.
35              
36             # -----------------------------------------------
37              
38             sub initialize_receipts
39             {
40             my($self) = @_;
41              
42             $self -> log(__PACKAGE__ . '. Leaving initialize_receipts');
43              
44             return $self -> view -> receipt -> initialize;
45              
46             } # End of initialize_receipts.
47              
48             # -----------------------------------------------
49              
50             sub initialize_reconciliation
51             {
52             my($self) = @_;
53              
54             $self -> log(__PACKAGE__ . '. Leaving initialize_reconciliation');
55              
56             return $self -> view -> reconciliation -> initialize;
57              
58             } # End of initialize_reconciliation.
59              
60             # -----------------------------------------------
61              
62             sub log
63             {
64             my($self, $s) = @_;
65              
66             $self -> db -> log($s);
67              
68             } # End of log.
69              
70             # -----------------------------------------------
71              
72             sub setup
73             {
74             my($self) = @_;
75             my($q) = $self -> query;
76              
77             $self -> run_modes([qw/initialize_payments initialize_receipts initialize_reconciliation submit_payment submit_receipt tab_set update_context update_payments update_receipts/]);
78             $self -> start_mode('tab_set');
79              
80             $self -> config(Business::AU::Ledger::Util::Config -> new -> config);
81              
82             my($config) = $self -> config;
83             my($attr) =
84             {
85             AutoCommit => $$config{'AutoCommit'},
86             RaiseError => $$config{'RaiseError'},
87             };
88              
89             $self -> simple(DBIx::Simple -> connect($$config{'dsn'}, $$config{'username'}, $$config{'password'}, $attr) );
90             $self -> db(Business::AU::Ledger::Database -> new(simple => $self -> simple) );
91              
92             $self -> session
93             (
94             CGI::Session -> new
95             (
96             $$config{'session_driver'},
97             $q,
98             {
99             Handle => $self -> simple -> dbh,
100             TableName => $$config{'session_table_name'},
101             },
102             {
103             name => 'sid',
104             }
105             )
106             );
107              
108             $self -> log('.' x 50);
109             $self -> log('sid => ' . $self -> session -> id);
110             $self -> log('.' x 50);
111             $self -> log("Param: $_ => " . $q -> param($_) ) for $q -> param;
112             $self -> log(__PACKAGE__ . '. Leaving setup');
113              
114             $self -> view(Business::AU::Ledger::View -> new
115             (
116             config => $self -> config,
117             db => $self -> db,
118             form_action => $self -> query -> url(-absolute => 1),
119             query => $q,
120             session => $self -> session,
121             ) );
122              
123             } # End of setup.
124              
125             # -----------------------------------------------
126              
127             sub submit_payment
128             {
129             my($self) = @_;
130              
131             $self -> log(__PACKAGE__ . '. Leaving submit_payment');
132              
133             return $self -> view -> payment -> submit;
134              
135             } # End of submit_payment.
136              
137             # -----------------------------------------------
138              
139             sub submit_receipt
140             {
141             my($self) = @_;
142              
143             $self -> log(__PACKAGE__ . '. Leaving submit_receipt');
144              
145             return $self -> view -> receipt -> submit;
146              
147             } # End of submit_receipt.
148              
149             # -----------------------------------------------
150              
151             sub tab_set
152             {
153             my($self) = @_;
154              
155             $self -> log(__PACKAGE__ . '. Leaving tab_set');
156              
157             return $self -> view -> build_tab_set;
158              
159             } # End of tab_set.
160              
161             # -----------------------------------------------
162              
163             sub update_context
164             {
165             my($self) = @_;
166              
167             $self -> log(__PACKAGE__ . '. Leaving update_context');
168              
169             return $self -> view -> context -> update;
170              
171             } # End of update_context.
172              
173             # -----------------------------------------------
174              
175             1;
176              
177             =head1 NAME
178              
179             C<Business::AU::Ledger> - A simple, web-based, payments/receipts manager
180              
181             =head1 Synopsis
182              
183             A CGI script:
184              
185             #!/usr/bin/perl
186              
187             use Business::AU::Ledger;
188              
189             Business::AU::Ledger -> new -> run;
190              
191             =head1 Description
192              
193             C<Business::AU::Ledger> is a pure Perl module.
194              
195             It is based on C<CGI::Application>.
196              
197             It provides a web-based interface to a database of payment, receipt and reconciliation transactions.
198              
199             The database schema is shipped in docs/schema.png.
200              
201             =head1 TODO
202              
203             This version is being released as 0.80 rather than the 1.00 I wanted, because of the following
204             missing features.
205              
206             AFAICT, the transactions themselves are reliably stored and retrieved from the database.
207              
208             Nevertheless, I do not regard this code as production-ready, because of this TODO list.
209              
210             These items are not listed in any particular order:
211              
212             =over 4
213              
214             =item Reconciliations
215              
216             These are simply not coded yet.
217              
218             =item REST-style usage
219              
220             The code uses the CGI::Application standard way of specifying state via the 'rm' hidden CGI form
221             field.
222              
223             I would prefer to switch to REST-style usage of the path info to transmit such information.
224              
225             This would make it easy to use FCGI::ProcManager to speed things up.
226              
227             =item Allow specific transactions to be deleted
228              
229             There is no Delete button displayed. You need to blank out all fields and submit the transaction.
230              
231             Another column containing Delete buttons makes the display wider :-(.
232              
233             =item Handle split cheques
234              
235             Another tab on the screen needs to be designed and coded for these.
236              
237             =item Categories and Types
238              
239             The lists for Category and Type of transaction are loaded into the database at initialization time
240             from text files.
241              
242             There is no way for the user to update these lists.
243              
244             =item Petty Cash
245              
246             How, exactly, to handle Petty Cash?
247              
248             I personally don't use it, but I assume some people do.
249              
250             =item Co-dependent fields
251              
252             Given one of the Private Use % and $ columns, the other can be calculated. Perhaps only get user input
253             for one of them.
254              
255             =item In-situ Updates
256              
257             Performing an in-situ update of a displayed transaction requires knowing the id of each.
258              
259             =item Test Data
260              
261             It would be good to have a command-line script which jammed a few transactions into the database
262             for testing purposes.
263              
264             =item Non-web interface
265              
266             The POD should explain how to use the given modules to circumvent the web interface.
267              
268             =back
269              
270             =head1 Constructor and initialization
271              
272             new(...) returns an object of type C<Business::AU::Ledger>.
273              
274             This is the class's contructor.
275              
276             Usage: Business::AU::Ledger -> new.
277              
278             =head1 Method: setup
279              
280             This method lists the valid run modes, which are:
281              
282             =over 4
283              
284             =item initialize_payments
285              
286             =item initialize_receipts
287              
288             =item submit_payment
289              
290             =item submit_receipt
291              
292             =item tab_set
293              
294             =item update_context
295              
296             =item update_payments
297              
298             =item update_receipts
299              
300             =back
301              
302             =head1 Installation and Configuration
303              
304             =head2 Installation
305              
306             There are several steps in the installation process:
307              
308             =over 4
309              
310             =item Install the database server
311              
312             You will edit .htledger.conf, as explained below, to tell Business::AU::Ledger
313             how to connect to the database.
314              
315             =item Install the Perl module Business::AU::Ledger
316              
317             This is the same as installing any other Perl module.
318              
319             Note, however, that you will I<always> need to download the distro from CPAN,
320             because other installation and configuration steps use files not installed in the
321             Perl module tree.
322              
323             Note, also, that installing the module will install a file called .htledger.conf in Perl's module tree,
324             and in the next few steps you may wish to edit that file. In this case, the file's permissions become relevant.
325              
326             =item Install the HTML templates
327              
328             Unpack the distro, and copy (recursively) the directory htdocs/assets/ to your web server's doc root directory.
329              
330             If you do not wish to use the recommended directory structure, put the contents of
331             htdocs/assets/css/business/au/ledger/ and htdocs/assets/templates/business/au/ledger/ anywhere you want,
332             and edit the file lib/Business/AU/Ledger/.htledger.conf (css_url and tmpl_path) to match.
333              
334             =item Install the YUI (see FAQ below)
335              
336             Download YUI from http://developer.yahoo.com/yui/ and install it in your web server's doc root directory.
337              
338             Then, if necessary, edit lib/Business/AU/Ledger/.htledger.conf, where it says yui_url=/yui.
339              
340             =item Install lib/Business/AU/Ledger/.htledger.conf
341              
342             Installing the module will have installed the version of .htledger.conf as shipped within the distro.
343              
344             If you edit your local copy of .htledger.conf, you must use your edited copy to overwrite the version installed
345             automatically.
346              
347             Specifically, the database credentials in this file will need to be edited, since several programs use them
348             to connect to the database.
349              
350             =item Install the CGI script ledger.cgi
351              
352             Copy cgi-bin/ledger.cgi into your web server's cgi-bin directory, and mark it as executable.
353              
354             =back
355              
356             =head2 Configuation
357              
358             =over 4
359              
360             =item Initialize the database tables
361              
362             In the unpacked distro dir, run:
363              
364             perl scripts/create.tables.pl
365             perl scripts/populate.tables.pl
366              
367             Check that this worked by logging on to your database server, via the command line say, and running:
368              
369             select * from tx_details
370              
371             You should get 15 rows output.
372              
373             =item Point your web client at http://127.0.0.1/cgi-bin/ledger.cgi
374              
375             To start, you must specify the first month of your financial year.
376              
377             After that, click on Payments or Receipts, then on the name of a month.
378              
379             Lastly, click on Initialize to display any transactions already in the database for that month.
380              
381             =back
382              
383             =head1 FAQ
384              
385             =head2 Q: How do you handle the ATO's requirements for BAS and GST?
386              
387             ATO is Australian Tax Office.
388              
389             BAS is Business Activity Statement, the basic document by which many businesses report turnover details.
390              
391             GST is Goods and Services Tax.
392              
393             The answer is: I don't (for which I'm extremely grateful).
394              
395             That is, I run my business in such a way as to simply not need to account for those details. I do this
396             by performing contract programming services via a contract with Freelance Global ( http://www.freelance-global.com/ ),
397             an organization operated by my accountant (M. Kelson).
398              
399             Organizations wishing to hire me sign a contract with Freelance, not with me directly.
400             Hence I avoid the need to manage BAS- and GST-related components of financial transactions.
401              
402             However, I do understand they are important, and will eventually add those features if those of you needing them
403             give me the support I need.
404              
405             =head2 Q: What happened to the Petty Cash/Private Use columns in the Payments input screen?
406              
407             A: I don't use those fields. If they vanished from one version to the next, it's because
408             I commented them out in assets/templates/business/au/ledger/monthly.tabs.js, and forgot to re-enable them
409             before releasing the new version. Sorry!
410              
411             Commenting them out means the required display width is narrower, and so I can use a bigger screen font.
412              
413             You can safely just uncomment lines 57 .. 60 of that file.
414              
415             =head2 Q: What's the basic design of the code?
416              
417             A: MVC (Model, View, Controller).
418              
419             The Model component is implemented in Business::AU::Ledger::Database and Business::AU::Ledger::Database::*.
420              
421             The View component is in Business::AU::Ledger::View and Business::AU::Ledger::View::*.
422              
423             The Controller is this module, Business::AU::Ledger.
424              
425             =head2 Q: How do I configure things?
426              
427             A: See lib/Business/AU/Ledger/.htledger.conf.
428              
429             See also the previous section 'Installation and Configuration'.
430              
431             See also the discussion below regarding the AU namespace.
432              
433             =head2 Q: Which JavaScript library do you use?
434              
435             A: YUI, the Yahoo! User Interface Library ( http://developer.yahoo.com/yui/ ).
436              
437             I'm using V 2.7.0 of YUI.
438              
439             =head2 Q: Can you, or will you, rewrite it to use a different JavaScript (non-YUI) package?
440              
441             A: Don't be ridiculous.
442              
443             =head2 Q: Why is it in the AU namespace?
444              
445             A: Some of the code, a very small amount, depends on the Australian taxation system.
446              
447             In fact, one reason for the Options tab (one day) is to allow for tax years which don't start in July the way ours do.
448             The default value for the month which starts each financial year can also be set in .htledger.conf.
449              
450             There are, of course, various place where Australian-specific output is generated. Here I'm referring to
451             the columns in the Payments and Receipts tabs.
452              
453             See Business::AU::Ledger::View::Payments and ::Receipts, in particular. See also the corresponding JavaScript
454             file assets/templates/business/au/ledger/monthly.tabs.js.
455              
456             Of course, the pop-up menus for various columns contain data specific to the ATO's classification system.
457             See the files in the data/ directory, which initalize the corresonding database tables.
458              
459             =head1 Author
460              
461             C<Business::AU::Ledger> was written by Ron Savage I<E<lt>ron@savage.net.auE<gt>> in 2009.
462              
463             Home page: http://savage.net.au/index.html
464              
465             =head1 Copyright
466              
467             Australian copyright (c) 2009, Ron Savage.
468             All Programs of mine are 'OSI Certified Open Source Software';
469             you can redistribute them and/or modify them under the terms of
470             the Artistic or the GPL licences, copies of which is available at:
471             http://www.opensource.org/licenses/index.html
472              
473             =cut
474