--- /dev/null
+#!perl
+
+use Test::More tests => 22;
+
+diag("Test that adjust-to-zero closes a checked-in lost circ when rebilling to zero");
+
+use constant WORKSTATION_NAME => 'BR4-test-27-lp1749795_adjust_to_zero_closes_circ.t';
+use constant WORKSTATION_LIB => 7;
+
+use strict; use warnings;
+
+use DateTime;
+use DateTime::Format::ISO8601;
+use OpenSRF::Utils qw/cleanse_ISO8601/;
+use OpenILS::Utils::TestUtils;
+my $script = OpenILS::Utils::TestUtils->new();
+use Data::Dumper;
+
+our $apputils = "OpenILS::Application::AppUtils";
+
+my $user_obj;
+my $storage_ses = $script->session('open-ils.storage');
+
+### Setup a patron
+my $patron_id = 52;
+my $patron_usrname = '99999306663';
+
+### Setup an item
+my $item_id = 310;
+my $item_barcode = 'CONC70000345';
+
+
+## HELPER FUNCTIONS
+
+sub retrieve_patron {
+ my $patron_id = shift;
+
+ my $user_req = $storage_ses->request('open-ils.storage.direct.actor.user.retrieve', $patron_id);
+ if (my $user_resp = $user_req->recv) {
+ if (my $patron_obj = $user_resp->content) {
+ return $patron_obj;
+ }
+ }
+ return 0;
+}
+
+sub fetch_billable_xact_summary {
+ my $xact_id = shift;
+ my $ses = $script->session('open-ils.cstore');
+ my $req = $ses->request(
+ 'open-ils.cstore.direct.money.billable_transaction_summary.retrieve',
+ $xact_id);
+
+ if (my $resp = $req->recv) {
+ return $resp->content;
+ } else {
+ return 0;
+ }
+}
+
+sub pay_bills {
+ my $payment_blob = shift;
+ my $resp = $apputils->simplereq(
+ 'open-ils.circ',
+ 'open-ils.circ.money.payment',
+ $script->authtoken,
+ $payment_blob,
+ $user_obj->last_xact_id
+ );
+
+ #refetch user_obj to get latest last_xact_id
+ $user_obj = retrieve_patron($patron_id)
+ or die 'Could not refetch patron';
+
+ return $resp;
+}
+
+#----------------------------------------------------------------
+# The tests... assumes stock sample data, full-auto install by
+# eg_wheezy_installer.sh, etc.
+#----------------------------------------------------------------
+
+# Connect to Evergreen
+$script->authenticate({
+ username => 'admin',
+ password => 'demo123',
+ type => 'staff'});
+ok( $script->authtoken, 'Have an authtoken');
+
+my $ws = $script->register_workstation(WORKSTATION_NAME,WORKSTATION_LIB);
+ok( ! ref $ws, 'Registered a new workstation');
+
+$script->logout();
+$script->authenticate({
+ username => 'admin',
+ password => 'demo123',
+ type => 'staff',
+ workstation => WORKSTATION_NAME});
+ok( $script->authtoken, 'Have an authtoken associated with the workstation');
+
+
+### Setup Org Unit Settings that apply to all test cases
+
+my $org_id = 1; #CONS
+my $settings = {
+ 'circ.max_item_price' => 50,
+ 'circ.min_item_price' => 50,
+ 'circ.void_lost_on_checkin' => 1,
+ 'circ.lost.xact_open_on_zero' => 0 #Leave transaction open when lost balance equals zero? NO
+};
+
+$apputils->simplereq(
+ 'open-ils.actor',
+ 'open-ils.actor.org_unit.settings.update',
+ $script->authtoken,
+ $org_id,
+ $settings
+);
+
+# Look up the patron
+if ($user_obj = retrieve_patron($patron_id)) {
+ is(
+ ref $user_obj,
+ 'Fieldmapper::actor::user',
+ 'open-ils.storage.direct.actor.user.retrieve returned aou object'
+ );
+ is(
+ $user_obj->usrname,
+ $patron_usrname,
+ 'Patron with id = ' . $patron_id . ' has username ' . $patron_usrname
+ );
+}
+
+
+# TEST OVERVIEW
+#1. check out an item
+#2. mark it lost
+#-- check that bill is $50
+#3. make full payment
+#-- check that circ and bill are closed
+#4. check in the item
+#-- check that negative balance appears
+#5. adjust to zero
+#-- check that bill is gone
+#-- check that circ is closed
+
+# Check copy out to patron at BR4.
+my $checkout = $script->do_checkout(
+ {copy_id => $item_id, patron_id => $patron_id}
+);
+is(ref($checkout), 'HASH', 'Got checkout event');
+is($checkout->{textcode}, 'SUCCESS', 'Checkout succeeded');
+
+# Check copy status.
+my $copy = $apputils->simplereq(
+ 'open-ils.pcrud',
+ 'open-ils.pcrud.retrieve.acp',
+ $script->authtoken,
+ $item_id
+);
+is($copy->status(), 1, 'Copy is checked out');
+
+### Mark item LOST
+my $response = $apputils->simplereq(
+ 'open-ils.circ',
+ 'open-ils.circ.circulation.set_lost',
+ $script->authtoken,
+ {barcode => $item_barcode}
+);
+
+# verify that checkout returned a circ object
+ok(
+ $checkout->{payload}{circ},
+ 'Response has a "circ" object'
+);
+my $xact_id;
+if ($checkout->{payload}{circ}) {
+ my $xact = $checkout->{payload}{circ};
+ $xact_id = $xact->id();
+}
+
+
+my $summary = fetch_billable_xact_summary($xact_id);
+ok( $summary, 'Found the transaction summary');
+is(
+ $summary->balance_owed,
+ '50.00',
+ 'Balance owed is 50.00 for lost item'
+);
+
+### pay the whole bill
+my $payment_blob = {
+ userid => $patron_id,
+ note => 'XX-lp1749795_adjust_to_zero_closes_circ.t',
+ payment_type => 'cash_payment',
+ patron_credit => '0.00',
+ payments => [ [ $xact_id, '50.00' ] ]
+};
+my $pay_resp = pay_bills($payment_blob);
+
+is(
+ scalar( @{ $pay_resp->{payments} } ),
+ 1,
+ 'Payment response included one payment id'
+);
+
+$summary = fetch_billable_xact_summary($xact_id);
+is(
+ $summary->balance_owed,
+ '0.00',
+ 'Remaining balance of 0.00 after payment'
+);
+
+# check that circ and bill are closed
+ok(
+ $summary->xact_finish,
+ 'Transaction is closed'
+);
+
+### check-in the copy
+
+my $item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', $item_id);
+if (my $item_resp = $item_req->recv) {
+ if (my $item = $item_resp->content) {
+ is(
+ ref $item,
+ 'Fieldmapper::asset::copy',
+ 'open-ils.storage.direct.asset.copy.retrieve returned acp object'
+ );
+ is(
+ $item->status,
+ 3,
+ 'Item with id = ' . $item_id . ' has status of LOST'
+ );
+ }
+}
+
+### verify checkin succeeded
+my $checkin_resp = $script->do_checkin_override({
+ barcode => $item_barcode});
+is(
+ $checkin_resp->{ilsevent},
+ 0,
+ 'Checkin returned a SUCCESS event'
+);
+
+### verify item status
+$item_req = $storage_ses->request('open-ils.storage.direct.asset.copy.retrieve', $item_id);
+if (my $item_resp = $item_req->recv) {
+ if (my $item = $item_resp->content) {
+ ok(
+ $item->status == 7 || $item->status == 0,
+ 'Item with id = ' . $item_id . ' has status of Reshelving or Available after fresh Storage request'
+ );
+ }
+}
+
+### verify negative balance
+$summary = fetch_billable_xact_summary($xact_id);
+is(
+ $summary->balance_owed,
+ '-50.00',
+ 'Patron has a negative balance (credit) of 50.00 due to overpayment'
+);
+
+
+# Adjust to zero
+
+# returns array of IDs for each transaction updated, Event on error.
+my $adjust_resp = $apputils->simplereq(
+ 'open-ils.circ',
+ 'open-ils.circ.money.billable_xact.adjust_to_zero',
+ $script->authtoken,
+ [$xact_id]
+);
+is(
+ $adjust_resp->[0],
+ $xact_id,
+ 'Adjust-to-zero succeeded'
+);
+
+### verify account has zero balance
+$summary = fetch_billable_xact_summary($xact_id);
+is(
+ $summary->balance_owed,
+ '0.00',
+ 'Patron has 0.00 balance'
+);
+### verify xact is closed
+ok(
+ $summary->xact_finish,
+ 'Transaction is closed'
+);
+
+