Changes and fixes in HTTP (e.g. + account upsertion)

====================================================
  * Account upsertion
  * Empty credit and debit forms, the latter with the ability to charge groups
  * Fixed redirection on posting transfers
  * Reverse order of credits and debits
  * Style: prevent monospace size reduction in some browsers; td.mark class
  * Totals in report and and bankStatement
This commit is contained in:
Florian "flowdy" Heß 2017-01-25 22:38:39 +01:00
parent d89ad8c580
commit 5aaff598d1
11 changed files with 110 additions and 28 deletions

View File

@ -72,15 +72,17 @@ sub startup {
my $admin = $auth->under(sub { shift->stash('grade') > 1 });
$admin->any('/admin')->to('admin#dash');
$admin->any( [qw/GET POST/] => '/account/:account' => { account => undef })
->to('account#upsert');
$admin->post('/:account/in')->to('credit#upsert');
$admin->post('/:account/out')->to('debit#upsert');
$admin->get('/:account/credits')->to('credit#list');
$admin->get('/:account/debits')->to('debit#list');
$admin->post('/:account/transfer')->to('account#transfer');
$admin->any( [qw/GET POST PATCH/] => '/credit/:id' )->to('credit#upsert');
$admin->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->post('/debit')->to('debit#upsert');
$admin->any( [qw/GET POST/] => '/debit')->to('debit#upsert');
$admin->get('/:action')->to(controller => 'admin');
$auth->get('/')->to('account#list')->name('home');

View File

@ -18,6 +18,40 @@ sub list {
}
sub upsert {
my $self = shift;
my $db = $self->app->db;
my $account_rs = $db->resultset("Account");
my $account;
if ( my $name = $self->stash("account") ) {
$self->stash( name => $name );
$account = $account_rs->find($name);
}
else {
$self->stash( name => undef );
$account = $account_rs->new({});
}
$self->stash( account => $account );
if ( $self->req->method eq 'POST' ) {
for my $field ($account->result_source->columns) {
my $value = $self->param($field);
$account->$field($value);
}
$account->update_or_insert();
$self->redirect_to("home");
}
else {
my @types = $account_rs->search({ type => { '!=' => q// } }, {
columns => ['type'], distinct => 1
})->get_column("type")->all;
$self->stash( types => \@types );
}
return;
}
sub history {
my $self = shift;
my $history = $self->app->db->resultset("History")->search({
@ -34,18 +68,20 @@ sub transfer {
my $credits = $account->available_credits;
my $arrears = $account->current_arrears;
return $self->redirect_to('home')
if !( $credits->count() && $arrears->count() );
if ( $self->req->method eq 'POST' ) {
$db->make_transfers(
$self->every_param('credits')
=> $self->every_param('debits')
);
}
if ( !( $credits->count && $arrears->count ) ) {
$self->redirect_to('home');
return;
}
$self->stash( credits => $credits, arrears => $arrears );
return if $self->req->method ne 'POST';
$db->make_transfers(
$self->every_param('credits')
=> $self->every_param('debits')
);
return;
}

View File

@ -18,7 +18,10 @@ sub list {
return;
}
$self->stash( credits => $account->credits_rs );
my $rs = $account->search_related(
credits => {}, { order_by => { -desc => [qw/date/] } }
);
$self->stash( credits => $rs );
return;

View File

@ -18,7 +18,10 @@ sub list {
return;
}
$self->stash( debits => $account->debits_rs );
my $rs = $account->search_related(
debits => {}, { order_by => { -desc => [qw/date/] }}
);
$self->stash( debits => $rs );
return;
@ -29,17 +32,36 @@ sub upsert {
my $db = $self->app->db;
my $id = $self->stash("id");
my $account = $self->stash("account");
my @FIELDS = qw/billId date purpose value targetCredit/;
my $debtor = $self->stash("account") // $self->param("debtor");
if ( $self->req->method eq 'POST' && $debtor =~ s{^@}{} ) {
my $group_members = $db->resultset('Account')->search({
type => $debtor
});
while ( my $m = $group_members->next ) {
my %props = map { $_ => $self->param($_) } @FIELDS;
for ( $props{billId} ) {
s{\%u}{ $m->ID }e or $_ .= "-" . $m->ID;
}
$m->debits->create( \%props );
}
$self->redirect_to('home');
return;
}
my $method = $id ? 'find_or_new' : 'new';
my $debit = $db->resultset("Debit")->$method(
{ $id ? (billId => $id) : (), debtor => $account }
{ $id ? (billId => $id) : (), debtor => $debtor }
);
$self->stash( debit => $debit );
if ( $self->req->method eq 'GET' ) {
my $targets
= $db->resultset("Credit")->search({ account => { '!=' => $account } },
= $db->resultset("Credit")->search({ account => { '!=' => $debtor } },
{ join => 'income',
'+select' => [ { count => 'income.targetCredit', -as => 'targetted_by' } ],
group_by => ['income.targetCredit'],
@ -52,7 +74,7 @@ sub upsert {
return;
}
for my $field ( qw/billId debtor date purpose value targetCredit/ ) {
for my $field ( @FIELDS ) {
my $value = $self->param($field);
$debit->$field($value);
}

View File

@ -34,7 +34,12 @@ table td.centered {
table td.number {
text-align: right;
font-family: monospace;
font-family: monospace, monospace; /* Hack to prevent browser default size reduction of monospace font */
font-size:1em;
}
table td.mark {
background-color:rgba(255,0,0,0.1);
}
a.transfer-btn {

View File

@ -5,7 +5,9 @@
<tr><th>Account</th><th>Even until</th><th colspan="3">Arrears</th><th>Transfer</th><th colspan="3">Available</th><th>Earned</th><th>Promised</th><th>History</th><th>Report</th></tr>
% my ($type) = q{};
% my $inter_header = begin
<tr><th colspan="13"><%= shift || 'Club management accounts' %></th></tr>
% my $group = shift;
<tr><th colspan="11"><%= $group || 'Club management accounts' %></th>
<th colspan="2"><a href="/debit?group=<%= $group %>">Charge'm all</a></th></tr>
% end
% while ( my $account = $accounts->next ) {
% my $bal = $account->balance;
@ -15,8 +17,8 @@
<%= $inter_header->($t) %>
% }
% my $u = $account->ID;
<tr><th><%= $u %></th>
<td class="even_until"><%= $bal->even_until // "never" %></td><td class="number"><%== money $bal->arrears %></td><td><a href="<%= $u %>/debits">list</td><td><a href="<%= $u %>/out">add</a></td>
<tr><th><a href="/account/<%= $u %>"><%= $u %></a></th>
<td class="even_until"><%= $bal->even_until // "never" %></td><td class="number"><%== money $bal->arrears %></td><td><a href="<%= $u %>/debits">list</td><td><a href="<%= $u %>/out">Charge</a></td>
<td class="centered">
% my $which = ($bal->arrears && 1) + ($bal->available && 1);
% if ( $which == 2 ) {
@ -28,11 +30,11 @@
% else {
<span style="background-color:rgba(0,224,0,0.4);">&nbsp;N/A&nbsp;</span>
% }
</td><td class="number"><%== money $bal->available %></td><td><a href="<%= $u %>/credits">list</a></td><td><a href="<%= $u %>/in">add</a></td><td class="number"><%== money $bal->earned %></td><td class="number"><%== money $bal->promised %></td><td><a href="<%= $u %>/history">History</a></td><td><a href="<%= $u %>/report">Report</a></td></tr>
</td><td class="number"><%== money $bal->available %></td><td><a href="<%= $u %>/credits">list</a></td><td><a href="<%= $u %>/in">Credit</a></td><td class="number"><%== money $bal->earned %></td><td class="number"><%== money $bal->promised %></td><td><a href="<%= $u %>/history">History</a></td><td><a href="<%= $u %>/report">Report</a></td></tr>
% } # while
</table>
<p style="text-align:center;"><a href="/bankStatement">Reconstructed bank statement</a></p>
<p style="text-align:center;"><a href="/account/">Create account</a> &sdot; <a href="/bankStatement">Reconstructed bank statement</a></p>
<div class="help">
<h2>Column explanation</h2>
<dl>

View File

@ -2,7 +2,10 @@
<table>
<tr><th>Date</th><th>Value</th><th>Purpose</th></tr>
% my $total;
% while ( my $record = $report->next ) {
% $total += $record->value;
<tr><td><%= $record->date %></td><td class="number"><%== money $record->value %></td><td><%== nl2br $record->purpose %></td></tr>
% }
<tr><td style="text-align:right;">In total:</td><td class="number"><%== money $total %></td></tr>
</table>

View File

@ -2,7 +2,11 @@
<table>
<tr><th>Date</th><th>Purpose</th><th>Account</th><th>Debit</th><th>Credit</th></tr>
% my ($total_credit, $total_debit);
% while ( my $record = $records->next ) {
<tr><td><%= $record->date %></td><td><%= $record->purpose %></td><td><%= $record->account %></td><td><%= $record->debit %></td><td><%= $record->credit %></td></tr>
% $total_credit += $record->credit;
% $total_debit += $record->debit;
<tr><td><%= $record->date %></td><td><%= $record->purpose %></td><td><%= $record->account %></td><td class="number"><%== money $record->debit %></td><td class="number"><%== money $record->credit %></td></tr>
% }
<tr><td colspan="3" style="text-align:right;">Current balance:</td><td class="number"><%== $total_debit ? money $total_debit : '' %></td><td class="number"><%== $total_credit ? money $total_credit : '' %></td>
</table>

View File

@ -1,8 +1,10 @@
% title 'Income of ' . $account;
<p>Listed in reverse order:</p>
<table class="income">
<tr><th>Id</th><th>Date</th><th>Purpose</th><th>value</th><th>spent</th></tr>
% while ( my $credit = $credits->next ) {
<tr><td class="number"><a href="/credit/<%= $credit->credId %>"><%= $credit->credId %></a></td><td><%= $credit->date %></td><td><%== nl2br $credit->purpose %></td><td class="number"><%== money $credit->value %></td><td class="number"><%== money $credit->spent %></td></tr>
<tr><td class="number"><a href="/credit/<%= $credit->credId %>"><%= $credit->credId %></a></td><td><%= $credit->date %></td><td><%== nl2br $credit->purpose %></td><td class="number"><%== money $credit->value %></td><td class="number <%= $credit->spent < $credit->value ? "mark" : "" %>"><%== money $credit->spent %></td></tr>
% }
</table>

View File

@ -1,9 +1,11 @@
% title 'Outcome of ' . $account;
<p>Listed in reverse order:</p>
<table class="income">
<tr><th>Id</th><th>Date</th><th>Purpose</th><th>value</th><th>paid</th><th>to</th></tr>
% while ( my $debit = $debits->next ) {
% my $tgt = $debit->target;
<tr><td><a href="/debit/<%= $debit->billId %>"><%= $debit->billId %></a></td><td><%= $debit->date %></td><td><%== nl2br $debit->purpose %></td><td class="number"><%== money $debit->value %></td><td class="number"><%== money $debit->paid %><td><a href="/credit/<%= $tgt->credId %>"><%= $tgt->account->ID %></a></tr>
<tr><td><a href="/debit/<%= $debit->billId %>"><%= $debit->billId %></a></td><td><%= $debit->date %></td><td><%== nl2br $debit->purpose %></td><td class="number"><%== money $debit->value %></td><td class="number <%= $debit->paid < $debit->value ? "mark" : "" %>"><%== money $debit->paid %><td><a href="/credit/<%= $tgt->credId %>"><%= $tgt->account->ID %></a></tr>
% }
</table>

View File

@ -26,7 +26,7 @@ oops
% my $cmpacc = $targets->[0][1];
% my $target = $debit->targetCredit // '';
<select id="targetCredit" title="<%= $targets_count %>" name="targetCredit">
<option value="">-- Please select (mandatory) --</option>
<option value="">-- Please select (unless outgoing payment) --</option>
<optgroup label="<%= $cmpacc %>">
% for my $tc ( @$targets ) {
% my $newacc = $tc->[1];
@ -43,7 +43,8 @@ oops
</select>
% end
% $r{debtor} = begin
<input id="debtor" name="debtor" value="<%= $debit->debtor %>">
% my $g = param 'group';
<input id="debtor" name="debtor" value="<%= $g ? "\@$g" : $debit->debtor %>">
% end
<dl class="upsert">