Batch processor (.trsr charge) now also accessible via web interface
Plus, added `./trsr server` and `./trsr sql` calls. These are essentially execs of morbo and sqlite3 with appropriate arguments.
This commit is contained in:
		
							parent
							
								
									a686011cf4
								
							
						
					
					
						commit
						f5cde1c585
					
				| @ -97,12 +97,14 @@ sub startup { | |||||||
|       my $c = shift; |       my $c = shift; | ||||||
|       return $c->stash('grade') > 1 || undef; |       return $c->stash('grade') > 1 || undef; | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|   $admin->any('/admin')->to('admin#dash'); |   $admin->any('/admin')->to('admin#dash'); | ||||||
|   $admin->any( [qw/GET POST/] => '/account/:account' => { account => undef }) |   $admin->any( [qw/GET POST/] => '/account/:account' => { account => undef }) | ||||||
|       ->to('account#upsert'); |       ->to('account#upsert'); | ||||||
|   $admin->any( [qw/GET POST/] => '/:account/in')->to('credit#upsert'); |   $admin->any( [qw/GET POST/] => '/:account/in')->to('credit#upsert'); | ||||||
|   $admin->any( [qw/GET POST/] => '/:account/out')->to('debit#upsert'); |   $admin->any( [qw/GET POST/] => '/:account/out')->to('debit#upsert'); | ||||||
|   $admin->post('/:account/transfer')->to('account#transfer'); |   $admin->post('/:account/transfer')->to('account#transfer'); | ||||||
|  |   $admin->any( [qw/GET POST/] => '/batch-processor' )->to('account#batch_processor'); | ||||||
|   $admin->any( [qw/GET POST PATCH/] => '/credit/:id' )->to('credit#upsert'); |   $admin->any( [qw/GET POST PATCH/] => '/credit/:id' )->to('credit#upsert'); | ||||||
|   $admin->any( [qw/GET POST/] => '/credit')->to('credit#upsert'); |   $admin->any( [qw/GET POST/] => '/credit')->to('credit#upsert'); | ||||||
|   $admin->any( [qw/GET POST PATCH/] => '/debit/*id' )->to('debit#upsert'); |   $admin->any( [qw/GET POST PATCH/] => '/debit/*id' )->to('debit#upsert'); | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ use strict; | |||||||
| package TrsrDB::HTTP::Account; | package TrsrDB::HTTP::Account; | ||||||
| use Mojo::Base 'Mojolicious::Controller'; | use Mojo::Base 'Mojolicious::Controller'; | ||||||
| use Carp qw(croak); | use Carp qw(croak); | ||||||
|  | use FindBin qw($Bin); | ||||||
| 
 | 
 | ||||||
| sub list { | sub list { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
| @ -79,6 +80,25 @@ sub upsert { | |||||||
|     return; |     return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub batch_processor { | ||||||
|  |     my $self = shift; | ||||||
|  | 
 | ||||||
|  |     if ( $self->req->method eq 'POST' ) { | ||||||
|  |         my $text = $self->req->headers->content_type =~ m{^text/plain\b} | ||||||
|  |                  ? $self->req->body | ||||||
|  |                  : $self->param("batch") | ||||||
|  |                  ; | ||||||
|  |         open my $fh, '<', \$text; | ||||||
|  |         require "$Bin/trsr" or die; | ||||||
|  |         $self->app->db->storage->txn_do(sub { | ||||||
|  |             Commands::act_on_other_db($self->app->db); | ||||||
|  |             Commands::charge_account($fh); | ||||||
|  |         }); | ||||||
|  |         $self->redirect_to('home'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| sub history { | sub history { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my %query = ( account => $self->stash("account") ); |     my %query = ( account => $self->stash("account") ); | ||||||
|  | |||||||
| @ -58,7 +58,8 @@ table td.mark { | |||||||
|     background-color:rgba(255,0,0,0.1); |     background-color:rgba(255,0,0,0.1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| table td input { | table td input, | ||||||
|  | textarea { | ||||||
|     width:100%; |     width:100%; | ||||||
|     box-sizing: border-box; |     box-sizing: border-box; | ||||||
| } | } | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ | |||||||
| % } # while | % } # while | ||||||
| </table> | </table> | ||||||
| 
 | 
 | ||||||
| % stash links => [ '/account' => "Create account", '/bankStatement' => "Reconstructed bank statement" ]; | % stash links => [ '/account' => "Create account", '/batch-processor' => "Batch Processor", '/bankStatement' => "Reconstructed bank statement" ]; | ||||||
| % stash help => $_ for begin | % stash help => $_ for begin | ||||||
| <h2>Column explanation</h2> | <h2>Column explanation</h2> | ||||||
| <dl> | <dl> | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								test.sh
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								test.sh
									
									
									
									
									
								
							| @ -1,20 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
| 
 |  | ||||||
| abort () { |  | ||||||
|    echo Database not deleted. |  | ||||||
|    exit ${1:-1} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| db=$(mktemp -t trsr-XXXXXXXXX.db); |  | ||||||
| bash t/schema.sh $db |  | ||||||
| if [ $? == 0 ]; then |  | ||||||
|    echo Tests passed. |  | ||||||
| else abort |  | ||||||
| fi |  | ||||||
| 
 |  | ||||||
| > $db; sqlite3 $db < schema.sql |  | ||||||
| export TRSRDB_SQLITE_FILE=$db |  | ||||||
| if prove -r t; then |  | ||||||
|     rm $db |  | ||||||
| else abort $? |  | ||||||
| fi |  | ||||||
							
								
								
									
										258
									
								
								trsr
									
									
									
									
									
								
							
							
						
						
									
										258
									
								
								trsr
									
									
									
									
									
								
							| @ -1,58 +1,22 @@ | |||||||
| #!/usr/bin/env perl | #!/usr/bin/env perl | ||||||
| use strict; | use strict; | ||||||
| 
 | 
 | ||||||
|  | my (%OPTS, $ACCOUNT, %targets); | ||||||
|  | 
 | ||||||
|  | package Commands { | ||||||
|  | use Text::Wrap qw(wrap); | ||||||
|  | use Carp qw(croak); | ||||||
|  | use Scalar::Util qw(openhandle); | ||||||
|  | 
 | ||||||
| my $db; | my $db; | ||||||
| use TrsrDB \$db; | use TrsrDB \$db; | ||||||
| use open qw/:std :encoding(utf8)/; | use open qw/:std :encoding(utf8)/; | ||||||
| 
 | 
 | ||||||
| my %dispatcher = ( | sub act_on_other_db { | ||||||
|     charge => \&Commands::charge_account, |     $db = shift; | ||||||
|     ct  => sub { | } | ||||||
|         Commands::charge_account(); |  | ||||||
|         Commands::make_transfers(); |  | ||||||
|     }, |  | ||||||
|     cts => sub { |  | ||||||
|         Commands::charge_account(); |  | ||||||
|         Commands::make_transfers(); |  | ||||||
|         Commands::balance_status(); |  | ||||||
|     }, |  | ||||||
|     ctr => sub { |  | ||||||
|         Commands::charge_account(); |  | ||||||
|         Commands::make_transfers(); |  | ||||||
|         Commands::balance_status(1); |  | ||||||
|     }, |  | ||||||
|     report => sub { |  | ||||||
|         Commands::balance_status(1); |  | ||||||
|     }, |  | ||||||
|     status => \&Commands::balance_status, |  | ||||||
|     transfer => \&Commands::make_transfers, |  | ||||||
|     tr  => sub { |  | ||||||
|         Commands::make_transfers(); |  | ||||||
|         Commands::balance_status(1); |  | ||||||
|     }, |  | ||||||
|     ts  => sub { |  | ||||||
|         Commands::make_transfers(); |  | ||||||
|         Commands::balance_status(); |  | ||||||
|     } |  | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| package Commands; | sub single_charge { | ||||||
| use Text::Wrap qw(wrap); |  | ||||||
| use Carp qw(croak); |  | ||||||
| 
 |  | ||||||
| use Getopt::Long; |  | ||||||
| 
 |  | ||||||
| my %targets; |  | ||||||
| my %OPTS = ( |  | ||||||
|     'account' => \my $ACCOUNT, |  | ||||||
|     'target-credit' => \%targets |  | ||||||
| ); |  | ||||||
| GetOptions( \%OPTS, |  | ||||||
|   '1', 'account|a=s', 'target|t=s', 'target-credit|tcr=i', 'source|s=s', |  | ||||||
|   'date|d=s', 'value|v=i', 'purpose|p=s', 'bill-id|b=s' |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| sub _single_charge { |  | ||||||
|     my $accounts = $db->resultset("Account"); |     my $accounts = $db->resultset("Account"); | ||||||
| 
 | 
 | ||||||
|     _require_value(); |     _require_value(); | ||||||
| @ -64,7 +28,7 @@ sub _single_charge { | |||||||
| 
 | 
 | ||||||
|     my $charger = sub { |     my $charger = sub { | ||||||
|         my ($account, $billId) = @_; |         my ($account, $billId) = @_; | ||||||
|         my $what = $billId ? 'add_to_debit' : 'add_to_credit'; |         my $what = $billId ? 'add_to_debits' : 'add_to_credits'; | ||||||
|         return $account->$what({ |         return $account->$what({ | ||||||
|             $billId ? ( |             $billId ? ( | ||||||
|                 billId => $billId, |                 billId => $billId, | ||||||
| @ -81,14 +45,16 @@ sub _single_charge { | |||||||
|             $db->make_transfers( $record->ID => $t ); |             $db->make_transfers( $record->ID => $t ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     elsif ( $billId =~ s{ @(\w+) }{ %s }xms ) { |     elsif ( $billId =~ s{ @(\w+) }{ %s }xms ) { | ||||||
|         $accounts = $accounts->search({ type => $1 }); |         $accounts = $accounts->search({ type => $1 }); | ||||||
|         while ( my $account = $accounts->next ) { |         while ( my $account = $accounts->next ) { | ||||||
|             $charger->( $account, sprintf $billId, $account->ID ); |             $charger->( $account, sprintf $billId ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     else { |     else { | ||||||
|         die "Sorry, you haven't specified account(s) to charge"; |         croak "You haven't specified an account to charge"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -168,48 +134,46 @@ sub _require_target { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub charge_account { | sub charge_account { | ||||||
|     goto &_single_charge if $OPTS{1}; |     goto &single_charge if $OPTS{1}; | ||||||
| 
 | 
 | ||||||
|     print "Enter records ...\n"; |     print "Enter records ...\n"; | ||||||
| 
 | 
 | ||||||
|  |     local *ARGV = openhandle($_[0]) | ||||||
|  |         // croak "charge_account() expects open file handle to read from" | ||||||
|  |         if exists $_[0]; | ||||||
|  | 
 | ||||||
|     # Possible line formats: |     # Possible line formats: | ||||||
|     # ------------------------------------------------------- |     # ------------------------------------------------------- | ||||||
|     # Date Account Var Purpose            :: Target credit (TCr) |     # Date Account Var Amount Purpose     :: Credit (Payment or target) | ||||||
|     # Date Account +Amount Purpose        :: Payment Credit |     #              ^^^ Field may be empty, yet not stripped | ||||||
|     # Date Account -Amount TCr ID Purpose :: Bill |     # Date Account Amount TCr ID: Purpose :: Bill | ||||||
|     # Date Account <Amount ID Purpose     :: Outgoing payment |     #                     ^^^ Field may be empty, yet not stripped | ||||||
|     # Please note: Omit Account if specified on commandline. |     # Please note: Omit Account if specified on commandline. | ||||||
| 
 | 
 | ||||||
|     my @transfers; |     my @transfers; | ||||||
| 
 | 
 | ||||||
|     while ( defined( my $line = <ARGV> ) ) { |     while ( defined( my $line = <ARGV> ) ) { | ||||||
|         chomp $line; |  | ||||||
|         _strip_comment_from($line) // next; |         _strip_comment_from($line) // next; | ||||||
|         my ($date, $account, $amount, $purpose) = $ACCOUNT |         my ($date, $account, $debit, $credit, $purpose) = $ACCOUNT | ||||||
|             ? do { my @columns = split /[,\s]\s*/, $line, 3; |             ? do { my @columns = split /[,\s]\s*/, $line, 4; | ||||||
|                    splice @columns, 1, 0, $ACCOUNT; |                    splice @columns, 1, 0, $ACCOUNT; | ||||||
|                    @columns } |                    @columns | ||||||
|             : split /[,\s]\s*/, $line, 4 |                  } | ||||||
|  |             : split /[,\s]\s*/, $line, 5 | ||||||
|             ; |             ; | ||||||
| 
 | 
 | ||||||
|         $account = $db->resultset("Account")->find($account) |         $account = $db->resultset("Account")->find($account) | ||||||
|             // die "User not found: $account\n"; |             // die "User not found: $account\n"; | ||||||
| 
 | 
 | ||||||
|         if ( $amount =~ m{^[a-z]}i ) { |         _append_adj_lines_to($purpose); | ||||||
|             _append_adj_lines_to($purpose); |  | ||||||
|             my $r = record_credit($date, $account, $purpose, 0); |  | ||||||
|             $targets{ $amount } = $r->credId; |  | ||||||
|         } |  | ||||||
|         elsif ( $amount =~ s/^([<-])// ) { |  | ||||||
| 
 | 
 | ||||||
|             (my ($tgt, $billId), $purpose) |         if ( $debit =~ /^\d/ ) { | ||||||
|                 = $1 eq q{<} ? (undef, split /\s+/, $purpose, 2) |  | ||||||
|                              : (split /\s+/, $purpose, 3) |  | ||||||
|                              ; |  | ||||||
| 
 | 
 | ||||||
|             _append_adj_lines_to($purpose); |             my $tgt = $credit; | ||||||
| 
 |             my $billId = $purpose =~ s{ \A ([[:print:]]+?) : \s* }{}xms | ||||||
|             $DB::single=1; |                        ? $1 | ||||||
|  |                        : croak qq{Missing ID in debit purpose: $purpose} | ||||||
|  |                        ; | ||||||
| 
 | 
 | ||||||
|             if ( $purpose =~ s{ \s* << \s* (.+?) \r? \n? \z }{}xms ) { |             if ( $purpose =~ s{ \s* << \s* (.+?) \r? \n? \z }{}xms ) { | ||||||
|                 push @transfers, [ |                 push @transfers, [ | ||||||
| @ -217,45 +181,59 @@ sub charge_account { | |||||||
|                 ] => $billId; |                 ] => $billId; | ||||||
|             } |             } | ||||||
|                  |                  | ||||||
|             if ( my ($var, $account) = $tgt =~ m{^([A-Za-z]\w+)([?=]\w+)$} ) { |             if ( my ($var, $op, $assigned) | ||||||
|                 my $op = substr $account, 0, 1; |                      = $tgt =~ m{^([A-Za-z]\w+)([?=])(\d+)$} | ||||||
|  |                ) { | ||||||
|                 if ( $op eq q{=} ) { |                 if ( $op eq q{=} ) { | ||||||
|                     $tgt = $targets{ $var } = $account; |                     $tgt = $targets{ $var } = $assigned; | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     print "Please select target credit to reference by $var:\n", |                     $tgt = select_target_credit_from($assigned, $var); | ||||||
|                           "-------------------------------------------------\n"; |  | ||||||
|                     $tgt = $targets{ $var } |  | ||||||
|                          = select_target_credit_from($account); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             elsif ( $tgt =~ /^[a-z]/i ) { |             elsif ( $tgt =~ /^[a-z]/i ) { | ||||||
|                 $tgt = $targets{ $tgt } |                 $tgt = $targets{ $tgt } | ||||||
|                     // croak "Target credit not declared: $tgt!\n"; |                     // croak "Target credit not assigned: $tgt!\n"; | ||||||
|             } |             } | ||||||
|             record_debit( | 
 | ||||||
|                 $date, $account, $billId, $purpose, |             $account->add_to_debits({ | ||||||
|                 integer_money_value($amount), $tgt |                 billId => $billId, | ||||||
|             );     |                 date => $date, | ||||||
|              |                 purpose => $purpose, | ||||||
|  |                 value => integer_money_value($debit), | ||||||
|  |                 targetCredit => $tgt, | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
|         elsif ( ($amount) = $amount =~ m{ \A \+? (\d+) \z }xms ) { | 
 | ||||||
|             my $tgt = $purpose =~ s{ \s* >> \s* (.+) \z }{}xms && $1; |         elsif ( $credit =~ /^\d/ ) { | ||||||
|             _append_adj_lines_to($purpose); | 
 | ||||||
|             my $c = record_credit( |             my $tgt = $purpose =~ s{ \s* >> \s* (.+) \r? \n? \z }{}xms && $1; | ||||||
|                 $date, $account, $purpose, integer_money_value($amount) | 
 | ||||||
|             ); |             my $c = $account->add_to_credits({ | ||||||
|  |                 date => $date, | ||||||
|  |                 account => $account, | ||||||
|  |                 purpose => $purpose, | ||||||
|  |                 value => integer_money_value($credit) | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             if ( $debit =~ /^[a-z]/i ) { $targets{ $debit } = $c->credId; } | ||||||
|  |             elsif ( $debit ne q{+} ) { | ||||||
|  |                 croak "Invalid field input: $debit neither number nor name"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             push @transfers, $c->credId => $tgt if $tgt; |             push @transfers, $c->credId => $tgt if $tgt; | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             die "Amount cannot be parsed: $amount\n"; |             die "Cannot be parsed: $debit $credit\n"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ( @transfers ) { |     if ( @transfers ) { | ||||||
|         my $t = $db->make_transfers( @transfers ); |         my $t = $db->make_transfers( @transfers ); | ||||||
|         if ( $t ) { |         if ( $t ) { | ||||||
|             printf "Transferred %f in total.\n", $t; |             printf "Transferred %d in total.\n", $t; | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             print "No transfers could be made.\n"; |             print "No transfers could be made.\n"; | ||||||
| @ -281,9 +259,11 @@ sub integer_money_value { | |||||||
| 
 | 
 | ||||||
| sub _append_adj_lines_to { | sub _append_adj_lines_to { | ||||||
|     my ($has_more, $line); |     my ($has_more, $line); | ||||||
|  |     $DB::single=1; | ||||||
|     for ( $_[0] //= do { $has_more = 1; <ARGV> } ) { |     for ( $_[0] //= do { $has_more = 1; <ARGV> } ) { | ||||||
|         if ( s/^"// .. s/(?<!")(")(?!")// || $has_more) { |         if ( s/^"// .. s/(?<!")(")(?=\s|$)// || $has_more) { | ||||||
|             $line = <ARGV> if $has_more = !$1; |             last if $1; | ||||||
|  |             $line = <ARGV>; | ||||||
|             last if $line eq $/; |             last if $line eq $/; | ||||||
|             $line =~ s{^\s+}{}; |             $line =~ s{^\s+}{}; | ||||||
|             $_ .= $line; |             $_ .= $line; | ||||||
| @ -293,34 +273,15 @@ sub _append_adj_lines_to { | |||||||
|     &_strip_comment_from; |     &_strip_comment_from; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub record_credit { |  | ||||||
|     my ($date, $account, $purpose, $amount) = @_; |  | ||||||
|     return $account->credits->create({ |  | ||||||
|         date => $date, |  | ||||||
|         account => $account, |  | ||||||
|         purpose => $purpose, |  | ||||||
|         value => $amount |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| sub record_debit { |  | ||||||
|     my ($date, $debtor, $billId, $purpose, $value, $targetCredit) = @_; |  | ||||||
|     return $db->resultset("Debit")->create({ |  | ||||||
|         billId => $billId, |  | ||||||
|         date => $date, |  | ||||||
|         debtor => $debtor->ID, |  | ||||||
|         purpose => $purpose, |  | ||||||
|         value => $value, |  | ||||||
|         targetCredit => $targetCredit, |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| sub select_target_credit_from { | sub select_target_credit_from { | ||||||
|     my ($account) = @_; |     my ($account, $var) = @_; | ||||||
| 
 | 
 | ||||||
|     croak "Interactive target credit selection is not possible" |     croak "Interactive target credit selection is not possible" | ||||||
|         if !( -t STDIN ); |         if !( -t STDIN ); | ||||||
| 
 | 
 | ||||||
|  |     print "Please select target credit to reference by $var:\n", | ||||||
|  |           "-------------------------------------------------\n"; | ||||||
|  | 
 | ||||||
|     $account = $db->resultset("Account")->find($account); |     $account = $db->resultset("Account")->find($account); | ||||||
|     my $credits = $account->credits->search({}, { |     my $credits = $account->credits->search({}, { | ||||||
|         join => 'income', |         join => 'income', | ||||||
| @ -339,19 +300,17 @@ sub select_target_credit_from { | |||||||
|     while (1) { |     while (1) { | ||||||
|         print "Which credit do you want to target? "; |         print "Which credit do you want to target? "; | ||||||
|         chomp( my $input = <STDIN> ); |         chomp( my $input = <STDIN> ); | ||||||
|         return $input if $credits->find($input); |         return $targets{ $var } = $input if $credits->find($input); | ||||||
|         warn "Credit ID $input is not a listed option.\n"; |         warn "Credit ID $input is not a listed option.\n"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return; |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub make_transfers { | sub make_transfers { | ||||||
|     print "Make transfers ...\n"; |     print "Make transfers ...\n"; | ||||||
| 
 | 
 | ||||||
|     if ( ! -t STDIN ) { |     if ( ! -t STDIN ) { | ||||||
|         die "Input expected from interactive terminal"; |         croak "Input expected from interactive terminal"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     my $search_opts = { order_by => { -asc => ['date'] } }; |     my $search_opts = { order_by => { -asc => ['date'] } }; | ||||||
| @ -466,8 +425,61 @@ sub _balance_report { | |||||||
|     }     |     }     | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | } # End of package Commands | ||||||
|  | 
 | ||||||
|  | return 1 if caller; | ||||||
|  | 
 | ||||||
| package main; | package main; | ||||||
| 
 | 
 | ||||||
|  | use Getopt::Long; | ||||||
|  | 
 | ||||||
|  | %OPTS = ( | ||||||
|  |     'account' => \$ACCOUNT, | ||||||
|  |     'target-credit' => \%targets | ||||||
|  | ); | ||||||
|  | GetOptions( \%OPTS, | ||||||
|  |   '1', 'account|a=s', 'target|t=s', 'target-credit|tcr=i', 'source|s=s', | ||||||
|  |   'date|d=s', 'value|v=i', 'purpose|p=s', 'bill-id|b=s' | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | my %dispatcher = ( | ||||||
|  |     charge => \&Commands::charge_account, | ||||||
|  |     ct  => sub { | ||||||
|  |         Commands::charge_account(); | ||||||
|  |         Commands::make_transfers(); | ||||||
|  |     }, | ||||||
|  |     cts => sub { | ||||||
|  |         Commands::charge_account(); | ||||||
|  |         Commands::make_transfers(); | ||||||
|  |         Commands::balance_status(); | ||||||
|  |     }, | ||||||
|  |     ctr => sub { | ||||||
|  |         Commands::charge_account(); | ||||||
|  |         Commands::make_transfers(); | ||||||
|  |         Commands::balance_status(1); | ||||||
|  |     }, | ||||||
|  |     report => sub { | ||||||
|  |         Commands::balance_status(1); | ||||||
|  |     }, | ||||||
|  |     server => sub { | ||||||
|  |         exec qw{morbo server -w TrsrDB -w templates/}; | ||||||
|  |     }, | ||||||
|  |     sql => sub { | ||||||
|  |         exec "sqlite3" => -cmd => "PRAGMA foreign_keys=ON; PRAGMA recursive_triggers=ON;" | ||||||
|  |                        => -line => $ENV{TRSRDB_SQLITE_FILE}; | ||||||
|  |     }, | ||||||
|  |     status => \&Commands::balance_status, | ||||||
|  |     transfer => \&Commands::make_transfers, | ||||||
|  |     tr  => sub { | ||||||
|  |         Commands::make_transfers(); | ||||||
|  |         Commands::balance_status(1); | ||||||
|  |     }, | ||||||
|  |     ts  => sub { | ||||||
|  |         Commands::make_transfers(); | ||||||
|  |         Commands::balance_status(); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  | 
 | ||||||
| my $cmd = shift; | my $cmd = shift; | ||||||
| if ( my $sref = $dispatcher{ $cmd } ) { | if ( my $sref = $dispatcher{ $cmd } ) { | ||||||
|     $sref->(); |     $sref->(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Florian "flowdy" Heß
						Florian "flowdy" Heß