Changeset 7b4d418 in rattail


Ignore:
Timestamp:
03/07/19 17:04:20 (6 months ago)
Author:
Lance Edgar <ledgar@…>
Branches:
master
Children:
1242a5e
Parents:
6927d74
Message:

Add "calculated" invoice total for receiving row, batch

so then invoice_total is meant to reflect the "original" total as obtained
from the invoice proper, whereas invoice_total_calculated is up to us

Location:
rattail
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • rattail/batch/handlers.py

    r6927d74 r7b4d418  
    189189        if not row.removed:
    190190            batch.rowcount += 1
     191            self.after_add_row(batch, row)
     192
     193    def after_add_row(self, batch, row):
     194        """
     195        Event hook, called immediately after the given row has been "properly"
     196        added to the batch.  This is a good place to update totals for the
     197        batch, to account for the new row, etc.
     198        """
    191199
    192200    def purge_batches(self, session, before=None, before_days=90,
  • rattail/batch/purchase.py

    r6927d74 r7b4d418  
    179179                        if child_row.invoice_total:
    180180                            parent_row.invoice_total = (parent_row.invoice_total or 0) + child_row.invoice_total
     181                        if child_row.invoice_total_calculated:
     182                            parent_row.invoice_total_calculated = (parent_row.invoice_total_calculated or 0) + child_row.invoice_total_calculated
    181183
    182184                    else: # new product; simply add new row to parent
     
    581583            self.refresh_row(truck_dump_row)
    582584
    583     def clone_truck_dump_credit(self, truck_dump_credit, child_row):
    584         """
    585         Clone a credit record from a truck dump, onto the given child row.
    586         """
    587         child_batch = child_row.batch
    588         child_credit = model.PurchaseBatchCredit()
    589         self.copy_credit_attributes(truck_dump_credit, child_credit)
    590         child_credit.date_ordered = child_batch.date_ordered
    591         child_credit.date_shipped = child_batch.date_shipped
    592         child_credit.date_received = child_batch.date_received
    593         child_credit.invoice_date = child_batch.invoice_date
    594         child_credit.invoice_number = child_batch.invoice_number
    595         child_credit.invoice_line_number = child_row.invoice_line_number
    596         child_credit.invoice_case_cost = child_row.invoice_case_cost
    597         child_credit.invoice_unit_cost = child_row.invoice_unit_cost
    598         child_credit.invoice_total = child_row.invoice_total
    599         child_row.credits.append(child_credit)
    600         return child_credit
    601 
    602585    # TODO: surely this should live elsewhere
    603586    def calc_best_fit(self, units, case_quantity):
     
    611594
    612595    def refresh(self, batch, progress=None):
    613 
    614         # reset PO total for ordering batch
    615         if batch.mode == self.enum.PURCHASE_BATCH_MODE_ORDERING:
    616             batch.po_total = 0
    617 
    618         # reset invoice total for receiving and costing batch
    619         elif batch.mode in (self.enum.PURCHASE_BATCH_MODE_RECEIVING,
    620                             self.enum.PURCHASE_BATCH_MODE_COSTING):
    621             batch.invoice_total = 0
    622596
    623597        # refresh all rows etc. per usual
     
    847821                                           row.STATUS_TRUCKDUMP_PARTCLAIMED):
    848822                    break
     823
     824    def after_add_row(self, batch, row):
     825        if batch.mode == self.enum.PURCHASE_BATCH_MODE_RECEIVING:
     826
     827            # update "original" invoice total for batch
     828            if row.invoice_total is not None:
     829                batch.invoice_total = (batch.invoice_total or 0) + row.invoice_total
     830
     831            # update "calculated" invoice totals for row, batch
     832            if row.invoice_unit_cost is None:
     833                row.invoice_total_calculated = None
     834            else:
     835                row.invoice_total_calculated = row.invoice_unit_cost * self.get_units_accounted_for(row)
     836            if row.invoice_total_calculated is not None:
     837                batch.invoice_total_calculated = (batch.invoice_total_calculated or 0) + row.invoice_total_calculated
    849838
    850839    def refresh_row(self, row, initial=False):
     
    909898            row.invoice_unit_cost = row.po_unit_cost or (cost.unit_cost if cost else None)
    910899
    911         # update PO / invoice totals for row and batch
    912         self.refresh_totals(row, cost, initial)
    913 
    914900        # all that's left should be setting status for the row...and that logic
    915901        # will primarily depend on the 'mode' for this purchase batch
     
    10781064                    (getattr(row, 'units_{}'.format(mode)) or 0) + units)
    10791065
    1080         # undo any totals previously in effect for the row, then refresh.  this
    1081         # updates some totals as well as status for the row
    1082         if row.invoice_total:
    1083             batch.invoice_total -= row.invoice_total
     1066        # refresh row status etc.
    10841067        self.refresh_row(row)
     1068
     1069        # update calculated invoice totals if normal received amounts
     1070        if mode == 'received':
     1071            invoice_amount = 0
     1072            if cases:
     1073                invoice_amount += cases * row.case_quantity * row.invoice_unit_cost
     1074            if units:
     1075                invoice_amount += units * row.invoice_unit_cost
     1076            row.invoice_total_calculated = (row.invoice_total_calculated or 0) + invoice_amount
     1077            batch.invoice_total_calculated = (batch.invoice_total_calculated or 0) + invoice_amount
    10851078
    10861079    def receiving_update_row_credits(self, row, mode, cases, units, **kwargs):
     
    11641157        credit.invoice_case_cost = row.invoice_case_cost
    11651158        credit.invoice_unit_cost = row.invoice_unit_cost
    1166         credit.invoice_total = row.invoice_total
     1159        credit.invoice_total = row.invoice_total_calculated
    11671160
    11681161    def receiving_update_row_children(self, row, mode, cases, units, **kwargs):
     
    12091202                raise RuntimeError("infinite loop detected; aborting")
    12101203
    1211         # undo any totals previously in effect for the row, then refresh.  this
    1212         # updates some totals as well as status for the row
    1213         if row.invoice_total:
    1214             batch.invoice_total -= row.invoice_total
     1204        # refresh parent row status
    12151205        self.refresh_row(row)
    12161206
     
    15811571
    15821572        if batch.mode == self.enum.PURCHASE_BATCH_MODE_RECEIVING:
    1583             if row.invoice_total:
    1584                 batch.invoice_total -= row.invoice_total
     1573            if row.invoice_total_calculated:
     1574                batch.invoice_total_calculated -= row.invoice_total_calculated
    15851575
    15861576        super(PurchaseBatchHandler, self).remove_row(row)
    1587 
    1588     def refresh_totals(self, row, cost, initial):
    1589         batch = row.batch
    1590 
    1591         if batch.mode == self.enum.PURCHASE_BATCH_MODE_ORDERING:
    1592             if row.po_unit_cost:
    1593                 row.po_total = row.po_unit_cost * self.get_units_ordered(row)
    1594                 batch.po_total = (batch.po_total or 0) + row.po_total
    1595             else:
    1596                 row.po_total = None
    1597 
    1598         elif batch.mode in (self.enum.PURCHASE_BATCH_MODE_RECEIVING,
    1599                             self.enum.PURCHASE_BATCH_MODE_COSTING):
    1600             if row.invoice_unit_cost:
    1601                 row.invoice_total = row.invoice_unit_cost * self.get_units_accounted_for(row)
    1602                 batch.invoice_total = (batch.invoice_total or 0) + row.invoice_total
    1603             else:
    1604                 row.invoice_total = None
    16051577
    16061578    def get_unit_cost(self, product, vendor):
     
    19471919        purchase.invoice_number = batch.invoice_number
    19481920        purchase.invoice_date = batch.invoice_date
    1949         purchase.invoice_total = batch.invoice_total
     1921        purchase.invoice_total = batch.invoice_total_calculated
    19501922        purchase.date_received = batch.date_received
    19511923
     
    19731945            item.invoice_case_cost = row.invoice_case_cost
    19741946            item.invoice_unit_cost = row.invoice_unit_cost
    1975             item.invoice_total = row.invoice_total
     1947            item.invoice_total = row.invoice_total_calculated
    19761948
    19771949        with session.no_autoflush:
  • rattail/db/model/batch/purchase.py

    r6927d74 r7b4d418  
    9898    creation / population.  Really this is only used for batches of 'receiving'
    9999    mode, to present a slightly different UI if order quantities were (not) known.
     100    """)
     101
     102    invoice_total_calculated = sa.Column(sa.Numeric(precision=8, scale=2), nullable=True, doc="""
     103    Calculated invoice total, per quantity received thus far (if applicable).
    100104    """)
    101105
     
    231235        """)
    232236
     237    invoice_total_calculated = sa.Column(sa.Numeric(precision=7, scale=2), nullable=True, doc="""
     238    Calculated total cost for line item, per quantity received thus far.  See
     239    also :attr:`invoice_total`.
     240    """)
     241
    233242    truck_dump_status = sa.Column(sa.Integer(), nullable=True, doc="""
    234243    Truck dump status code for the row.  Only relevant for truck dump parent
Note: See TracChangeset for help on using the changeset viewer.