Bug 24080: Add payout option to patron account page
authorMartin Renvoize <martin.renvoize@ptfs-europe.com>
Thu, 21 Nov 2019 13:59:43 +0000 (13:59 +0000)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Fri, 3 Jan 2020 16:35:45 +0000 (16:35 +0000)
This enhancement adds a refined workflow to allow librarians to pay out
money to patrons and record these payouts on the patrons account.

The use case is that a patron has somehow accrued credit, through a
refund perhaps, and the library wants to be able to physically hand over
some money to balance the patrons account.

Test plan:
1) Undertake a series of transactions that result in some outstanding
   credit on a patrons account.
2) Note that a new 'Issue payout' button appears next to a credit with
   an outstanding balance (but only if your user has the payout
   permission or is a superlibrarian)
3) Click the 'Issue payout' button and a modal should appear
   pre-populated with the amountoutstanding.
4) You should be able to edit the amount you wish to payout, make
   payment or cancel.
5) Signoff

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt
members/boraccount.pl

index 2ad20bb..f6e6e02 100644 (file)
@@ -84,6 +84,9 @@
         [% IF account.is_credit %]
           <a href="boraccount.pl?action=void&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs void"><i class="fa fa-ban"></i> Void</a>
         [% END %]
+        [% IF CAN_user_updatecharges_payout && account.is_credit && ( account.amountoutstanding < 0 ) %]
+          <button type="button" data-toggle="modal" data-target="#issuePayoutModal" data-account="[%- PROCESS account_type_description account=account -%]" data-accountline="[% account.accountlines_id | html %]" data-amount="[% account.amountoutstanding | $Price %]" class="btn btn-default btn-xs"><i class="fa fa-money"></i> Issue payout</button>
+        [% END %]
       </td>
     </tr>
 
         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
      </div> <!-- /.row -->
 
+    <!-- Issue payout modal -->
+    <div class="modal" id="issuePayoutModal" tabindex="-1" role="dialog" aria-labelledby="issuePayoutLabel">
+        <form  id="payout_form" action="/cgi-bin/koha/members/boraccount.pl" method="get" enctype="multipart/form-data" class="validated">
+            <input type="hidden" name="accountlines_id" value="" id="payoutline">
+            <input type="hidden" name="action" value="payout">
+            <input type="hidden" name="borrowernumber" value="[% account.borrowernumber | html %]">
+            <div class="modal-dialog" role="document">
+                <div class="modal-content">
+                    <div class="modal-header">
+                        <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                        <h4 class="modal-title" id="issuePayoutLabel">Issue payout</h4>
+                    </div>
+                    <div class="modal-body">
+                        <fieldset class="rows">
+                            <ol>
+                                <li>
+                                    <span id="item" class="label">Account: </span><span></span>
+                                </li>
+                                <li>
+                                    <span id="paid" class="label">Amount outstanding: </span><span>[% payout.amount | $Price %]</span>
+                                </li>
+                                <li>
+                                    <label class="required" for="amount">Returned to patron: </label>
+                                    <input type="number" step="0.01" id="amount" name="amount" min="0.00" required="required">
+                                    <span class="required">Required</span>
+                                </li>
+                                [% SET payment_types = AuthorisedValues.GetAuthValueDropbox('PAYMENT_TYPE') %]
+                                [% IF payment_types %]
+                                <li>
+                                    <label for="transaction_type">Transaction type: </label>
+                                    <select name="transaction_type" id="transaction_type">
+                                        [% FOREACH pt IN payment_types %]
+                                            <option value="[% pt.authorised_value | html %]">[% pt.lib | html %]</option>
+                                        [% END %]
+                                    </select>
+                                </li>
+                                [% END %]
+
+                                [% IF Koha.Preference('UseCashRegisters') %]
+                                <li>
+                                    <label for="cash_register">Cash register: </label>
+                                    <select name="cash_register" id="cash_register">
+                                        [% FOREACH register IN registers %]
+                                          [% IF register.id == registerid %]
+                                        <option value="[% register.id | html %]" selected="selected">[% register.name | html %]</option>
+                                          [% ELSE %]
+                                        <option value="[% register.id | html %]">[% register.name | html %]</option>
+                                          [% END %]
+                                        [% END %]
+                                    </select>
+                                </li>
+                                [% END %]
+
+                            </ol>
+                        </fieldset> <!-- /.rows -->
+                    </div> <!-- /.modal-body -->
+                    <div class="modal-footer">
+                        <input type="hidden" name="registerid" value="[% register.id | html %]">
+                        <input type="hidden" name="op" value="payout">
+                        <button type="submit" class="btn btn-default">Confirm</button>
+                        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+                    </div> <!-- /.modal-footer -->
+                </div> <!-- /.modal-content -->
+            </div> <!-- /.modal-dialog -->
+        </form> <!-- /#payout_form -->
+    </div> <!-- /#issuePayoutModal -->
+
 [% MACRO jsinclude BLOCK %]
     [% INCLUDE 'datatables.inc' %]
     [% INCLUDE 'columns_settings.inc' %]
                     e.preventDefault();
                 }
             });
+
+            $("#issuePayoutModal").on("shown.bs.modal", function(e){
+                var button = $(e.relatedTarget);
+                var account = button.data('account');
+                $("#account + span").replaceWith(account);
+                var accountline = button.data('accountline');
+                $('#payoutline').val(accountline);
+                var amount = button.data('amount') * -1;
+                $("#paid + span").replaceWith(amount);
+                $("#amount").attr({ "value": amount, "max": amount });
+                $("#amount, #transaction_type").focus();
+            });
         });
     </script>
 [% END %]
index 251a3aa..df2ad35 100755 (executable)
@@ -29,6 +29,7 @@ use C4::Output;
 use CGI qw ( -utf8 );
 use C4::Members;
 use C4::Accounts;
+use Koha::Cash::Registers;
 use Koha::Patrons;
 use Koha::Patron::Categories;
 
@@ -47,12 +48,14 @@ my ($template, $loggedinuser, $cookie) = get_template_and_user(
     }
 );
 
+my $schema         = Koha::Database->new->schema;
 my $borrowernumber = $input->param('borrowernumber');
 my $payment_id     = $input->param('payment_id');
 my $change_given   = $input->param('change_given');
 my $action         = $input->param('action') || '';
 
 my $logged_in_user = Koha::Patrons->find( $loggedinuser ) or die "Not logged in";
+my $library_id = C4::Context->userenv->{'branch'};
 my $patron = Koha::Patrons->find( $borrowernumber );
 unless ( $patron ) {
     print $input->redirect("/cgi-bin/koha/circ/circulation.pl?borrowernumber=$borrowernumber");
@@ -61,12 +64,60 @@ unless ( $patron ) {
 
 output_and_exit_if_error( $input, $cookie, $template, { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron } );
 
+my $registerid;
+if ( C4::Context->preference('UseCashRegisters') ) {
+    $registerid = scalar $input->param('registerid');
+    my $registers  = Koha::Cash::Registers->search(
+        { branch   => $library_id, archived => 0 },
+        { order_by => { '-asc' => 'name' } }
+    );
+
+    if ( !$registers->count ) {
+        $template->param( error_registers => 1 );
+    }
+    else {
+
+        if ( !$registerid ) {
+            my $default_register = Koha::Cash::Registers->find(
+                { branch => $library_id, branch_default => 1 } );
+            $registerid = $default_register->id if $default_register;
+        }
+        $registerid = $registers->next->id if !$registerid;
+
+        $template->param(
+            registerid => $registerid,
+            registers  => $registers,
+        );
+    }
+}
+
 if ( $action eq 'void' ) {
     my $payment_id = scalar $input->param('accountlines_id');
     my $payment    = Koha::Account::Lines->find( $payment_id );
     $payment->void();
 }
 
+if ( $action eq 'payout' ) {
+    my $payment_id        = scalar $input->param('accountlines_id');
+    my $payment           = Koha::Account::Lines->find($payment_id);
+    my $amount           = scalar $input->param('amount');
+    my $transaction_type = scalar $input->param('transaction_type');
+    $schema->txn_do(
+        sub {
+            my $payout = $payment->payout(
+                {
+                    payout_type   => $transaction_type,
+                    branch        => $library_id,
+                    staff_id      => $logged_in_user->id,
+                    cash_register => $registerid,
+                    interface     => 'intranet',
+                    amount        => $amount
+                }
+            );
+        }
+    );
+}
+
 #get account details
 my $total = $patron->account->balance;