[open-ils-commits] r17079 - in trunk/Open-ILS: src/perlmods/OpenILS/Application/Circ web/js/dojo/openils/circ/nls web/js/ui/default/circ/selfcheck xul/staff_client/server/locale/en-US xul/staff_client/server/patron (erickson)

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Aug 4 16:19:20 EDT 2010


Author: erickson
Date: 2010-08-04 16:19:14 -0400 (Wed, 04 Aug 2010)
New Revision: 17079

Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm
   trunk/Open-ILS/web/js/dojo/openils/circ/nls/selfcheck.js
   trunk/Open-ILS/web/js/ui/default/circ/selfcheck/payment.js
   trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js
   trunk/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties
   trunk/Open-ILS/xul/staff_client/server/patron/bill2.js
Log:
require latest last_xact_id for payments

To prevent accidental multiple payments on the transaction or payments
against stale information, require the latest user last_xact_id to be
passed into the payment API call.  Update staff client (thanks jason)
and self-check payment interfaces to match.

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm	2010-08-04 20:19:14 UTC (rev 17079)
@@ -66,6 +66,10 @@
                     ], 
                 }/, type => 'hash'
             },
+            {
+                desc => q/Last user transaction ID.  This is the actor.usr.last_xact_id value/, 
+                type => 'string'
+            }
         ],
         "return" => {
             "desc" =>
@@ -73,6 +77,11 @@
                 BAD_PARAMS
                     Bad parameters were given to this API method itself.
                     See note field.
+                INVALID_USER_XACT_ID
+                    The last user transaction ID does not match the ID in the database.  This means
+                    the user object has been updated since the last retrieval.  The client should
+                    be instructed to reload the user object and related transactions before attempting
+                    another payment
                 REFUND_EXCEEDS_BALANCE
                 REFUND_EXCEEDS_DESK_PAYMENTS
                 CREDIT_PROCESSOR_NOT_SPECIFIED
@@ -117,7 +126,7 @@
     }
 );
 sub make_payments {
-    my($self, $client, $auth, $payments) = @_;
+    my($self, $client, $auth, $payments, $last_xact_id) = @_;
 
     my $e = new_editor(authtoken => $auth, xact => 1);
     return $e->die_event unless $e->checkauth;
@@ -138,6 +147,11 @@
 
     my $patron = $e->retrieve_actor_user($user_id) or return $e->die_event;
 
+    if($patron->last_xact_id ne $last_xact_id) {
+        $e->rollback;
+        return OpenILS::Event->new('INVALID_USER_XACT_ID');
+    }
+
     # A user is allowed to make credit card payments on his/her own behalf
     # All other scenarious require permission
     unless($type eq 'credit_card_payment' and $user_id == $e->requestor->id) {
@@ -364,8 +378,12 @@
         }
     }
 
+    # update the user to create a new last_xact_id
+    $e->update_actor_user($patron) or return $e->die_event;
+    $patron = $e->retrieve_actor_user($patron) or return $e->die_event;
+
     $e->commit;
-    return \@payment_ids;
+    return {last_xact_id => $patron->last_xact_id, payments => \@payment_ids};
 }
 
 sub _recording_failure {

Modified: trunk/Open-ILS/web/js/dojo/openils/circ/nls/selfcheck.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/circ/nls/selfcheck.js	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/web/js/dojo/openils/circ/nls/selfcheck.js	2010-08-04 20:19:14 UTC (rev 17079)
@@ -36,6 +36,7 @@
     "FAIL_PART_no_ultimate_items": "The system could not find any items to match this hold request",
     "FAIL_PART_no_matchpoint": "System rules do not define how to handle this item",
     "FAIL_PART_no_user": "The system could not find this patron",
-    "FAIL_PART_transit_range": "The item cannot transit this far"
+    "FAIL_PART_transit_range": "The item cannot transit this far",
+    "PAYMENT_INVALID_USER_XACT_ID" : "We cannot proceed with the payment, because your account was updated from another location.  Please refresh the interface or log out and back in to retrieve the latest account information"
 }
 

Modified: trunk/Open-ILS/web/js/ui/default/circ/selfcheck/payment.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/circ/selfcheck/payment.js	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/web/js/ui/default/circ/selfcheck/payment.js	2010-08-04 20:19:14 UTC (rev 17079)
@@ -102,7 +102,7 @@
 
     var resp = fieldmapper.standardRequest(
         ['open-ils.circ', 'open-ils.circ.money.payment'],
-        {params : [this.authtoken, args]}
+        {params : [this.authtoken, args, patron.last_xact_id()]}
     );
 
     if (typeof(progressDialog) != "undefined")

Modified: trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js	2010-08-04 20:19:14 UTC (rev 17079)
@@ -114,9 +114,13 @@
                         var message = evt + '';
                         if(evt.textcode == 'CREDIT_PROCESSOR_DECLINED_TRANSACTION' && evt.payload)
                             message += '\n' + evt.payload.error_message;
+                        if(evt.textcode == 'INVALID_USER_XACT_ID')
+                            message += '\n' + localeStrings.PAYMENT_INVALID_USER_XACT_ID;
                         self.handleAlert(message, true, 'payment-failure');
                         return;
                     }
+
+                    self.patron.last_xact_id(resp.last_xact_id); // update to match latest from server
                     self.printPaymentReceipt(
                         resp,
                         function() {
@@ -1356,7 +1360,7 @@
 }
 
 
-SelfCheckManager.prototype.printPaymentReceipt = function(paymentIds, callback) {
+SelfCheckManager.prototype.printPaymentReceipt = function(response, callback) {
     
     var self = this;
     progressDialog.show(true);
@@ -1365,7 +1369,7 @@
         ['open-ils.circ', 'open-ils.circ.money.payment_receipt.print'],
         {
             async : true,
-            params : [this.authtoken, paymentIds],
+            params : [this.authtoken, response.payments],
             oncomplete : function(r) {
                 var resp = openils.Util.readResponse(r);
                 var output = resp.template_output();

Modified: trunk/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties	2010-08-04 20:19:14 UTC (rev 17079)
@@ -54,6 +54,7 @@
 staff.patron.bills.pay.annotate_payment=Please annotate this payment:
 staff.patron.bills.pay.annotate_payment.title=Annotate Payment
 staff.patron.bills.pay.refund_exceeds_desk_payment=%1$s\n\nAnother way to "zero" this transaction is to use Add Billing and add a miscellaneous bill to counter the negative balance.
+staff.patron.bills.pay.invalid_user_xact_id=%1$s\n\nThis patron data is stale.  Refreshing patron data.  You should re-attempt the payment.
 staff.patron.bills.pay.payment_failed=Bill payment likely failed
 staff.patron.bills.info_box.label_value.reservation=Reservation
 # 1 - Resource Barcode  2 - Resource Type Name

Modified: trunk/Open-ILS/xul/staff_client/server/patron/bill2.js
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/patron/bill2.js	2010-08-04 19:56:26 UTC (rev 17078)
+++ trunk/Open-ILS/xul/staff_client/server/patron/bill2.js	2010-08-04 20:19:14 UTC (rev 17079)
@@ -42,19 +42,7 @@
 
         $('credit_forward').setAttribute('value','???');
         if (!g.patron) {
-            g.network.simple_request(
-                'FM_AU_FLESHED_RETRIEVE_VIA_ID.authoritative',
-                [ ses(), g.patron_id ],
-                function(req) {
-                    try {
-                        g.patron = req.getResultObject();
-                        if (typeof g.patron.ilsevent != 'undefined') throw(g.patron);
-                        $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
-                    } catch(E) {
-                        alert('Error in bill2.js, retrieve patron callback: ' + E);
-                    }
-                }
-            );
+            refresh_patron();
         } else {
             $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
         }
@@ -757,14 +745,7 @@
             if (typeof window.xulG == 'object' && typeof window.xulG.refresh == 'function') window.xulG.refresh();
             if (typeof window.xulG == 'object' && typeof window.xulG.on_money_change == 'function') window.xulG.on_money_change();
             if ( $('payment_type').value == 'credit_payment' || $('convert_change_to_credit').checked ) {
-                JSAN.use('patron.util'); 
-                patron.util.retrieve_au_via_id(ses(),g.patron_id, function(req) {
-                    var au_obj = req.getResultObject();
-                    if (typeof au_obj.ilsevent == 'undefined') {
-                        g.patron = au_obj;
-                        $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
-                    }
-                });
+                refresh_patron();
             }
             try {
                 if ( ! $('receipt_upon_payment').hasAttribute('checked') ) { return; } // Skip print attempt
@@ -836,11 +817,14 @@
             payment_type : $('payment_type').getAttribute('label'),
             note : payment_blob.note
         }
-        var robj = g.network.simple_request( 'BILL_PAY', [ ses(), payment_blob ]);
+        var robj = g.network.simple_request( 'BILL_PAY', [ ses(), payment_blob, g.patron.last_xact_id() ]);
         if (typeof robj.ilsevent != 'undefined') {
-            switch(Number(robj.ilsevent)) {
-                case 0 /* SUCCESS */ : return true; break;
-                case 1226 /* REFUND_EXCEEDS_DESK_PAYMENTS */ : alert($("patronStrings").getFormattedString('staff.patron.bills.pay.refund_exceeds_desk_payment', [robj.desc])); return false; break;
+            switch(robj.textcode) {
+                case 'SUCCESS' : return true; break;
+                case 'REFUND_EXCEEDS_DESK_PAYMENTS' : alert($("patronStrings").getFormattedString('staff.patron.bills.pay.refund_exceeds_desk_payment', [robj.desc])); return false; break;
+                case 'INVALID_USER_XACT_ID' :
+                    refresh(); default_focus();
+                    alert($("patronStrings").getFormattedString('staff.patron.bills.pay.invalid_user_xact_id', [robj.desc])); return false; break;
                 default: throw(robj); break;
             }
         }
@@ -856,6 +840,7 @@
         if (params && params.clear_voided_summary) {
             g.data.voided_billings = []; g.data.stash('voided_billings');
         }
+        refresh_patron();
         g.bill_list.clear();
         retrieve_mbts_for_list();
         tally_voided();
@@ -908,3 +893,13 @@
     }
 }
 
+function refresh_patron() {
+    JSAN.use('patron.util'); JSAN.use('util.money');
+    patron.util.retrieve_au_via_id(ses(),g.patron_id, function(req) {
+        var au_obj = req.getResultObject();
+        if (typeof au_obj.ilsevent == 'undefined') {
+            g.patron = au_obj;
+            $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
+        }
+    });
+}



More information about the open-ils-commits mailing list