LP#1380803 Include direct charges in PO esimated price
authorBill Erickson <berickxx@gmail.com>
Mon, 6 Apr 2015 18:54:55 +0000 (14:54 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 13 Apr 2015 14:25:41 +0000 (10:25 -0400)
Move the estimated PO price calculation into the middle layer, along
with the total encumbered and spent calculation.  Add a new
PO.amount_estimated field for carrying the data.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Financials.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm
Open-ILS/web/js/ui/default/acq/po/view_po.js

index 354d396..2719924 100644 (file)
@@ -8236,6 +8236,7 @@ SELECT  usr,
                        <field reporter:label="Line Item Count" name="lineitem_count" oils_persist:virtual="true" reporter:datatype="int" />
                        <field reporter:label="Amount Encumbered" name="amount_encumbered" oils_persist:virtual="true" reporter:datatype="float" />
                        <field reporter:label="Amount Spent" name="amount_spent" oils_persist:virtual="true" reporter:datatype="float" />
+                       <field reporter:label="Amount Estimated" name="amount_estimated" oils_persist:virtual="true" reporter:datatype="float" />
                        <field reporter:label="PO Items" name="po_items" oils_persist:virtual="true" reporter:datatype="link" />
                </fields>
                <links>
index 7f20e38..92dca62 100644 (file)
@@ -870,46 +870,95 @@ sub po_perm_failure {
 sub build_price_summary {
     my ($e, $po_id) = @_;
 
-    # TODO: Add summary value for estimated amount (pre-encumber)
-
-    # fetch the fund debits for this purchase order
-    my $debits = $e->json_query({
-        "select" => {"acqfdeb" => [qw/encumbrance amount/]},
-        "from" => {
-            "acqlid" => {
-                "jub" => {
-                    "fkey" => "lineitem",
-                    "field" => "id",
-                    "join" => {
-                        "acqpo" => {
-                            "fkey" => "purchase_order", "field" => "id"
+    # amounts for lineitems / lineitem_details
+    my $li_data = $e->json_query({
+        select => {
+            jub => [
+                'estimated_unit_price', 
+                {column => 'id', alias => 'li_id'}
+            ],
+            acqlid => [
+                # lineitem_detail.id is needed to ensure we have one 
+                # "row" of data for every copy, regardless of whether
+                # a fund_debit exists for each copy.
+                {column => 'id', alias => 'lid_id'}
+            ],
+            acqfdeb => [
+                'encumbrance', 
+                {column => 'amount', alias => 'debit_amount'}
+            ]
+        }, 
+        from => {
+            jub => {
+                acqlid => {
+                    fkey => 'id',
+                    field => 'lineitem',
+                    join => {
+                        acqfdeb => {
+                            type => 'left',
+                            fkey => 'fund_debit',
+                            field => 'id'
                         }
                     }
-                },
-                "acqfdeb" => {"fkey" => "fund_debit", "field" => "id"}
+                }
             }
         },
-        "where" => {"+acqpo" => {"id" => $po_id}}
+        where => {'+jub' => {purchase_order => $po_id}}
     });
 
-    # add any debits for non-bib po_items
-    push(@$debits, @{
-        $e->json_query({
-            "select" => {"acqfdeb" => [qw/encumbrance amount/]},
-            "from" => {acqpoi => 'acqfdeb'},
-            "where" => {"+acqpoi" => {"purchase_order" => $po_id}}
-        })
+    # amounts for po_item's
+    my $item_data = $e->json_query({
+        select => {
+            acqpoi => ['estimated_cost'],
+            acqfdeb => [
+                'encumbrance', 
+                {column => 'amount', alias => 'debit_amount'}
+            ]
+        },
+        from => {
+            acqpoi => {
+                acqfdeb => {
+                    type => 'left',
+                    fkey => 'fund_debit',
+                    field => 'id'
+                }
+            }
+        },
+        where => {'+acqpoi' => {purchase_order => $po_id}}
     });
+                   
+    # sum amounts debited (for activated PO's) and amounts estimated 
+    # (for pending PO's) for all lineitem_details and po_items.
+
+    my ($enc, $spent, $estimated) = (0, 0, 0);
+
+    for my $deb (@$li_data, @$item_data) {
+
+        if (defined $deb->{debit_amount}) { # could be $0
+            # we have a debit, treat it as authoritative.
+
+            # estimated amount includes all amounts encumbered or spent
+            $estimated += $deb->{debit_amount};
+
+            if($U->is_true($deb->{encumbrance})) {
+                $enc += $deb->{debit_amount};
+            } else {
+                $spent += $deb->{debit_amount};
+            }
 
-    my ($enc, $spent) = (0, 0);
-    for my $deb (@$debits) {
-        if($U->is_true($deb->{encumbrance})) {
-            $enc += $deb->{amount};
         } else {
-            $spent += $deb->{amount};
+            # PO is not activated, so sum estimated costs.
+            # There will be one $deb object for every lineitem_detail 
+            # and po_item.  Adding the estimated costs for all gives 
+            # us the total esimated amount.
+
+            $estimated += (
+                $deb->{estimated_unit_price} || $deb->{estimated_cost} || 0
+            );
         }
     }
-    ($enc, $spent);
+
+    return ($enc, $spent, $estimated);
 }
 
 
@@ -971,9 +1020,10 @@ sub retrieve_purchase_order_impl {
     }
 
     if($$options{flesh_price_summary}) {
-        my ($enc, $spent) = build_price_summary($e, $po_id);
+        my ($enc, $spent, $estimated) = build_price_summary($e, $po_id);
         $po->amount_encumbered($enc);
         $po->amount_spent($spent);
+        $po->amount_estimated($estimated);
     }
 
     return $po;
index a63b948..4dec15d 100644 (file)
@@ -569,7 +569,7 @@ sub check_import_li_marc_perms {
 sub describe_affected_po {
     my ($e, $po) = @_;
 
-    my ($enc, $spent) =
+    my ($enc, $spent, $estimated) =
         OpenILS::Application::Acq::Financials::build_price_summary(
             $e, $po->id
         );
@@ -577,7 +577,8 @@ sub describe_affected_po {
     +{$po->id => {
             "state" => $po->state,
             "amount_encumbered" => $enc,
-            "amount_spent" => $spent
+            "amount_spent" => $spent,
+            "amount_estimated" => $estimated
         }
     };
 }
index 436450a..9d463aa 100644 (file)
@@ -314,6 +314,7 @@ function renderPo() {
     dojo.byId("acq-po-view-total-li").innerHTML = PO.lineitem_count();
     dojo.byId("acq-po-view-total-enc").innerHTML = PO.amount_encumbered().toFixed(2);
     dojo.byId("acq-po-view-total-spent").innerHTML = PO.amount_spent().toFixed(2);
+    dojo.byId("acq-po-view-total-estimated").innerHTML = PO.amount_estimated().toFixed(2);
     dojo.byId("acq-po-view-state").innerHTML = po_state; // TODO i18n
 
     if(PO.order_date()) {
@@ -449,7 +450,6 @@ function init() {
 
 function init2() {
 
-    var totalEstimated = 0;
     var zeroLi = true;
     fieldmapper.standardRequest(
         ['open-ils.acq', 'open-ils.acq.lineitem.search'],
@@ -463,13 +463,10 @@ function init2() {
                 zeroLi = false;
                 liTable.show('list');
                 var li = openils.Util.readResponse(r);
-                // TODO: Add po_item's to total estimated amount
-                totalEstimated += (Number(li.item_count() || 0) * Number(li.estimated_unit_price() || 0));
                 liTable.addLineitem(li);
             },
 
             oncomplete : function() {
-                dojo.byId("acq-po-view-total-estimated").innerHTML = totalEstimated.toFixed(2);
                 if (liFocus) liTable.drawCopies(liFocus);
                 if(zeroLi) openils.Util.show('acq-po-no-lineitems');
             }