From e26241b5b9b8ad1e2bea02dff7ea9c14a606380e Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 28 Apr 2010 15:24:31 +0000 Subject: [PATCH] Loosened some restrictions on invoicing. It is now possible to invoice items that have not yet been received. It is also possible to invoice for cancelled items, assuming the debit for the cancelled item remains. git-svn-id: svn://svn.open-ils.org/ILS/trunk@16333 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/Acq/Invoice.pm | 4 +- .../src/perlmods/OpenILS/Application/Acq/Order.pm | 42 ++++++------ Open-ILS/web/js/dojo/openils/acq/nls/acq.js | 4 +- Open-ILS/web/js/ui/default/acq/common/li_table.js | 48 +++++++------ Open-ILS/web/js/ui/default/acq/invoice/view.js | 80 ++++++++++++---------- .../web/templates/default/acq/common/li_table.tt2 | 2 +- .../web/templates/default/acq/invoice/view.tt2 | 8 +-- 7 files changed, 98 insertions(+), 90 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Invoice.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Invoice.pm index e435c4700..7842494f3 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Invoice.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Invoice.pm @@ -179,6 +179,7 @@ sub update_entry_debits { sub entry_amount_per_item { my $entry = shift; return $entry->amount_paid if $U->is_true($entry->billed_per_item); + return 0 if $entry->phys_item_count == 0; return $entry->amount_paid / $entry->phys_item_count; } @@ -193,7 +194,6 @@ sub find_entry_debits { from => { acqfdeb => { acqlid => { - filter => {cancel_reason => undef, recv_time => {'!=' => undef}}, join => { jub => { join => { @@ -207,7 +207,7 @@ sub find_entry_debits { } }, where => {'+acqfdeb' => {encumbrance => $encumbrance}}, - order_by => {'acqlid' => ['recv_time']}, + order_by => {'acqlid' => ['recv_time']}, # un-received items will sort to the end limit => $entry->phys_item_count }; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm index b51bb75ff..6217933fa 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm @@ -646,6 +646,9 @@ sub create_lineitem_debits { sub create_lineitem_detail_debit { my ($mgr, $li, $lid, $dry_run, $no_translate) = @_; + # don't create the debit if one already exists + return $mgr->editor->retrieve_acq_fund_debit($lid->fund_debit) if $lid->fund_debit; + my $li_id = ref($li) ? $li->id : $li; unless(ref $li and ref $li->provider) { @@ -2275,7 +2278,7 @@ sub cancel_purchase_order { $mgr->editor->allowed("CREATE_PURCHASE_ORDER", $po->ordering_agency); $po->state("cancelled"); - $po->cancel_reason($cancel_reason); + $po->cancel_reason($cancel_reason->id); my $li_ids = $mgr->editor->search_acq_lineitem( {"purchase_order" => $po_id}, {"idlist" => 1} @@ -2436,7 +2439,7 @@ sub cancel_lineitem { ); $li->state("cancelled"); - $li->cancel_reason($cancel_reason); + $li->cancel_reason($cancel_reason->id); my $lids = $mgr->editor->search_acq_lineitem_detail([{ "lineitem" => $li_id @@ -2469,7 +2472,7 @@ sub cancel_lineitem { # Attempt to delete the gathered copies (this will also handle volume deletion and bib deletion) # Another edge case, if we have a bib but not copies, are we supposed to delete the bib? if (scalar(@$copies)>0) { - my $override = 0; + my $override = 1; my $delete_stats = undef; my $retarget_holds = []; my $cat_evt = OpenILS::Application::Cat::AssetCommon->update_fleshed_copies( @@ -2533,9 +2536,6 @@ sub cancel_lineitem { } } - # TODO delete the associated fund debits? - # TODO who/what/where/how do we indicate this change for electronic orders? - update_lineitem($mgr, $li) or return 0; $result->{"li"} = { $li_id => { @@ -2627,28 +2627,28 @@ sub cancel_lineitem_detail { $lid->lineitem->purchase_order->ordering_agency ) or (! $lid->lineitem->purchase_order); - $lid->cancel_reason($cancel_reason); + $lid->cancel_reason($cancel_reason->id); - # TODO who/what/where/how do we indicate this change for electronic orders? + unless($U->is_true($cancel_reason->keep_debits)) { + my $debit_id = $lid->fund_debit; + $lid->clear_fund_debit; - my $debit_id = $lid->fund_debit; - $lid->clear_fund_debit; + if($debit_id) { + # item is cancelled. Remove the fund debit. + my $debit = $mgr->editor->retrieve_acq_fund_debit($debit_id); + if (!$U->is_true($debit->encumbrance)) { + $mgr->editor->rollback; + return OpenILS::Event->new('ACQ_NOT_CANCELABLE', + note => "Debit is marked as paid: $debit_id"); + } + $mgr->editor->delete_acq_fund_debit($debit) or return $mgr->editor->die_event; + } + } # XXX LIDs don't have either an editor or a edit_time field. Should we # update these on the LI when we alter an LID? $mgr->editor->update_acq_lineitem_detail($lid) or return 0; - if($debit_id) { - # item is cancelled. Remove the fund debit. - my $debit = $mgr->editor->retrieve_acq_fund_debit($debit_id); - if (!$U->is_true($debit->encumbrance)) { - $mgr->editor->rollback; - return OpenILS::Event->new('ACQ_NOT_CANCELABLE', - note => "Debit is marked as paid: $debit_id"); - } - $mgr->editor->delete_acq_fund_debit($debit) or return $mgr->editor->die_event; - } - return {"lid" => {$lid_id => {"cancel_reason" => $cancel_reason}}}; } diff --git a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js index c1a53365f..b4e89c918 100644 --- a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js +++ b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js @@ -67,8 +67,8 @@ "PO#${13} ${18}" + "${15}", 'INVOICE_CONFIRM_PRORATE' : "Prorate charges?\n\nAny subsequent changes to the invoice that would affect prorated amounts should be resolved manually.", - 'INVOICE_EXTRA_COPIES' : "You are invoicing ${0} more copies than originally ordered.
The order will be updated to reflect the additional copies" + - "

After saving the invoice, you may finish editing and importing the new copies from the lineitem details page.", + 'INVOICE_EXTRA_COPIES' : "You are attempting to invoice ${0} more copies than originally ordered.

To add these items to the original order, " + + "select a fund and choose 'Add New Items' below.
After saving the invoice, you may finish editing and importing the new copies from the lineitem details page.", //'INVOICE_EXTRA_COPIES_CATALOG' : "Add ${0} new copies to the catalog?", 'UNNAMED': "Unnamed", 'NO_FIND_INVOICE': "Could not find that invoice.\nNote that the Invoice # field is case-sensitive.", diff --git a/Open-ILS/web/js/ui/default/acq/common/li_table.js b/Open-ILS/web/js/ui/default/acq/common/li_table.js index 55b828499..6563eba0c 100644 --- a/Open-ILS/web/js/ui/default/acq/common/li_table.js +++ b/Open-ILS/web/js/ui/default/acq/common/li_table.js @@ -349,7 +349,9 @@ function AcqLiTable() { /* of course I'd rather just populate a element inside the * option element, but it seems you can't actually have any elements - * inside option elements */ + * inside option elements + * TODO: move to dojo/i18n + * */ option.innerHTML = option.innerHTML.replace( /(^.+)(.*)( existing.+$)/, "$1" + String(count) + "$3" ); @@ -438,6 +440,28 @@ function AcqLiTable() { /* handle links that appear/disappear based on whether LI is received */ if (this.isPO) { var self = this; + + actNewInvoice.onclick = function() { + location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_li=' + li.id(); + nodeByName("action_none", row).selected = true; + }; + actLinkInvoice.onclick = function() { + self.invoiceLinkDialogManager.target = li; + acqLitLinkInvoiceDialog.show(); + nodeByName("action_none", row).selected = true; + }; + actViewInvoice.onclick = function() { + location.href = oilsBasePath + + "/acq/search/unified?so=" + + base64Encode({"jub":[{"id": li.id()}]}) + + "&rt=invoice"; + nodeByName("action_none", row).selected = true; + }; + + actNewInvoice.disabled = false; + actLinkInvoice.disabled = false; + actViewInvoice.disabled = false; + switch(li.state()) { case "on-order": actReceive.disabled = false; @@ -447,6 +471,7 @@ function AcqLiTable() { nodeByName("action_none", row).selected = true; }; return; + case "received": actUnRecv.disabled = false; actUnRecv.onclick = function() { @@ -464,27 +489,6 @@ function AcqLiTable() { actHoldingsMaint.disabled = false; actHoldingsMaint.onclick = self.generateMakeRecTab( li.eg_bib_id(), 'copy_browser', row ); - actNewInvoice.disabled = false; - actLinkInvoice.disabled = false; - actViewInvoice.disabled = false; - - actNewInvoice.onclick = function() { - location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_li=' + li.id(); - nodeByName("action_none", row).selected = true; - }; - actLinkInvoice.onclick = function() { - self.invoiceLinkDialogManager.target = li; - acqLitLinkInvoiceDialog.show(); - nodeByName("action_none", row).selected = true; - }; - actViewInvoice.onclick = function() { - location.href = oilsBasePath + - "/acq/search/unified?so=" + - base64Encode({"jub":[{"id": li.id()}]}) + - "&rt=invoice"; - nodeByName("action_none", row).selected = true; - }; - return; } } diff --git a/Open-ILS/web/js/ui/default/acq/invoice/view.js b/Open-ILS/web/js/ui/default/acq/invoice/view.js index abe6824fb..c4770c22d 100644 --- a/Open-ILS/web/js/ui/default/acq/invoice/view.js +++ b/Open-ILS/web/js/ui/default/acq/invoice/view.js @@ -69,6 +69,7 @@ function init() { searchFilter : {active : 't'}, labelFormat : fundLabelFormat, searchFormat : fundSearchFormat, + dijitArgs : {required : true}, parentNode : dojo.byId('acq-invoice-extra-copies-fund') }); extraCopiesFund.build(); @@ -289,6 +290,7 @@ function addInvoiceItem(item) { labelFormat : fundLabelFormat, searchFormat : fundSearchFormat, readOnly : invoice && openils.Util.isTrue(invoice.complete()), + dijitArgs : {required : true}, parentNode : nodeByName('fund', row) } @@ -379,39 +381,42 @@ function addInvoiceEntry(entry) { entry.lineitem(li); entry.purchase_order(li.purchase_order()); nodeByName('title_details', row).innerHTML = html; - } - ); - dojo.forEach( - ['inv_item_count', 'phys_item_count', 'cost_billed', 'amount_paid'], - function(field) { - var dijitArgs = {required : true, constraints : {min: 0}, style : 'width:6em'}; - if(entry.isnew() && field == 'phys_item_count') dijitArgs.value = numReceived; - registerWidget( - entry, - field, - new openils.widget.AutoFieldWidget({ - fmObject : entry, - fmClass : 'acqie', - fmField : field, - dijitArgs : dijitArgs, - readOnly : invoice && openils.Util.isTrue(invoice.complete()), - parentNode : nodeByName(field, row) - }), - function(w) { - if(field == 'phys_item_count') { - dojo.connect(w, 'onChange', - function() { - // staff entered a higher number in the receive field than was originally ordered - if(Number(this.attr('value')) > entry.lineitem().item_count()) { - storeExtraCopies( - entry.lineitem().id(), - Number(this.attr('value')) - entry.lineitem().item_count() - ); - } - } - ) + dojo.forEach( + ['inv_item_count', 'phys_item_count', 'cost_billed', 'amount_paid'], + function(field) { + var dijitArgs = {required : true, constraints : {min: 0}, style : 'width:6em'}; + if(entry.isnew() && field == 'phys_item_count') { + // by default, attempt to pay for all received and as-of-yet-un-invoiced items + dijitArgs.value = (Number(li.order_summary().recv_count()) - Number(li.order_summary().invoice_count())) || 0; } + registerWidget( + entry, + field, + new openils.widget.AutoFieldWidget({ + fmObject : entry, + fmClass : 'acqie', + fmField : field, + dijitArgs : dijitArgs, + readOnly : invoice && openils.Util.isTrue(invoice.complete()), + parentNode : nodeByName(field, row) + }), + function(w) { + if(field == 'phys_item_count') { + dojo.connect(w, 'onChange', + function() { + // staff entered a higher number in the receive field than was originally ordered + // taking into account already invoiced items + var extra = Number(this.attr('value')) - + (Number(entry.lineitem().item_count()) - Number(entry.lineitem().order_summary().invoice_count())); + if(extra > 0) { + storeExtraCopies(entry, extra); + } + } + ) + } + } + ); } ); } @@ -565,7 +570,7 @@ function prorateInvoice(invoice) { ); } -function storeExtraCopies(liId, numExtra) { +function storeExtraCopies(entry, numExtra) { dojo.byId('acq-invoice-extra-copies-message').innerHTML = dojo.string.substitute( @@ -576,7 +581,7 @@ function storeExtraCopies(liId, numExtra) { extraCopiesGo, 'onClick', function() { - extraCopies[liId] = { + extraCopies[entry.lineitem().id()] = { numExtra : numExtra, fund : extraCopiesFund.widget.attr('value') } @@ -586,9 +591,12 @@ function storeExtraCopies(liId, numExtra) { ); dojo.connect( - extraCopiesCancel, - 'onClick', - function() { extraItemsDialog.hide() } + extraCopiesCancel, + 'onClick', + function() { + widgetRegistry.acqie[entry.id()].phys_item_count.widget.attr('value', ''); + extraItemsDialog.hide() + } ); extraItemsDialog.show(); diff --git a/Open-ILS/web/templates/default/acq/common/li_table.tt2 b/Open-ILS/web/templates/default/acq/common/li_table.tt2 index 627286e07..2e9063252 100644 --- a/Open-ILS/web/templates/default/acq/common/li_table.tt2 +++ b/Open-ILS/web/templates/default/acq/common/li_table.tt2 @@ -114,7 +114,7 @@ - + diff --git a/Open-ILS/web/templates/default/acq/invoice/view.tt2 b/Open-ILS/web/templates/default/acq/invoice/view.tt2 index c269675d7..6ad0e9a3a 100644 --- a/Open-ILS/web/templates/default/acq/invoice/view.tt2 +++ b/Open-ILS/web/templates/default/acq/invoice/view.tt2 @@ -29,7 +29,7 @@ Title Details # Invoiced - # Received + # Paid Billed Paid Detach @@ -133,15 +133,11 @@
Select a fund for the new items:


-

- + [% END %] -- 2.11.0