net gross
This commit is contained in:
@@ -146,6 +146,22 @@ class Invoice(metaclass=PoolMeta):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_report_reused_lot_lines(self):
|
||||
groups = {}
|
||||
for line in self._get_report_invoice_lines():
|
||||
lots = self._get_report_preferred_lots(line)
|
||||
if not lots:
|
||||
continue
|
||||
for lot in lots:
|
||||
lot_id = getattr(lot, 'id', None)
|
||||
key = lot_id if lot_id is not None else id(lot)
|
||||
groups.setdefault(key, {'lot': lot, 'lines': []})
|
||||
groups[key]['lines'].append(line)
|
||||
return {
|
||||
key: value for key, value in groups.items()
|
||||
if len(value['lines']) > 1
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _convert_report_quantity(quantity, from_unit, to_unit):
|
||||
value = Decimal(str(quantity or 0))
|
||||
@@ -170,6 +186,50 @@ class Invoice(metaclass=PoolMeta):
|
||||
cls._get_report_invoice_line_unit(line),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _find_report_hist_entry_for_quantity(cls, lot, quantity, exclude_state_id=None):
|
||||
target = Decimal(str(quantity or 0)).copy_abs()
|
||||
for entry in list(getattr(lot, 'lot_hist', []) or []):
|
||||
quantity_type = getattr(entry, 'quantity_type', None)
|
||||
if getattr(quantity_type, 'id', None) == exclude_state_id:
|
||||
continue
|
||||
entry_quantity = Decimal(str(getattr(entry, 'quantity', 0) or 0))
|
||||
if entry_quantity == target:
|
||||
return entry
|
||||
return None
|
||||
|
||||
def _get_report_reused_lot_gross_total(self):
|
||||
reused_lots = self._get_report_reused_lot_lines()
|
||||
if not reused_lots:
|
||||
return None
|
||||
total = Decimal(0)
|
||||
for data in reused_lots.values():
|
||||
lot = data['lot']
|
||||
_, current_gross = self._get_report_lot_hist_weights(lot)
|
||||
if current_gross is None:
|
||||
continue
|
||||
current_state = getattr(getattr(lot, 'lot_state', None), 'id', None)
|
||||
negative_lines = [
|
||||
line for line in data['lines']
|
||||
if Decimal(str(getattr(line, 'quantity', 0) or 0)) < 0
|
||||
]
|
||||
previous_gross = Decimal(0)
|
||||
matched = False
|
||||
for line in negative_lines:
|
||||
previous_entry = self._find_report_hist_entry_for_quantity(
|
||||
lot,
|
||||
self._get_report_invoice_line_quantity_from_line(line),
|
||||
exclude_state_id=current_state,
|
||||
)
|
||||
if not previous_entry:
|
||||
continue
|
||||
previous_gross += Decimal(str(
|
||||
getattr(previous_entry, 'gross_quantity', 0) or 0))
|
||||
matched = True
|
||||
if matched:
|
||||
total += current_gross - previous_gross
|
||||
return total
|
||||
|
||||
@staticmethod
|
||||
def _get_report_invoice_line_unit(line):
|
||||
lots = Invoice._get_report_preferred_lots(line)
|
||||
@@ -799,6 +859,13 @@ class Invoice(metaclass=PoolMeta):
|
||||
@property
|
||||
def report_gross(self):
|
||||
if self.lines:
|
||||
reused_gross = self._get_report_reused_lot_gross_total()
|
||||
if reused_gross is not None:
|
||||
non_reused_total = sum(
|
||||
self._get_report_invoice_line_weights(line)[1]
|
||||
for line in self._get_report_invoice_lines()
|
||||
if not self._report_invoice_line_reuses_lot(line))
|
||||
return non_reused_total + reused_gross
|
||||
return sum(
|
||||
self._get_report_invoice_line_weights(line)[1]
|
||||
for line in self._get_report_invoice_lines())
|
||||
|
||||
@@ -1189,11 +1189,26 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
mt = Mock(id=1, rec_name='MT')
|
||||
kg = Mock(id=2, rec_name='KILOGRAM')
|
||||
current_type = Mock(id=100)
|
||||
previous_type = Mock(id=200)
|
||||
shared_lot = Mock(id=10, lot_type='physic', lot_unit_line=kg)
|
||||
shared_lot.lot_state = current_type
|
||||
shared_lot.get_hist_quantity.return_value = (
|
||||
Decimal('999995'),
|
||||
Decimal('999995'),
|
||||
Decimal('999992'),
|
||||
)
|
||||
shared_lot.lot_hist = [
|
||||
Mock(
|
||||
quantity_type=previous_type,
|
||||
quantity=Decimal('999995'),
|
||||
gross_quantity=Decimal('999998'),
|
||||
),
|
||||
Mock(
|
||||
quantity_type=current_type,
|
||||
quantity=Decimal('999990'),
|
||||
gross_quantity=Decimal('999992'),
|
||||
),
|
||||
]
|
||||
|
||||
negative = Mock(
|
||||
type='line',
|
||||
@@ -1233,6 +1248,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
PoolMock.return_value.get.return_value = uom_model
|
||||
|
||||
self.assertEqual(invoice.report_net, Decimal('-5.000'))
|
||||
self.assertEqual(invoice.report_gross, Decimal('-6'))
|
||||
self.assertEqual(
|
||||
invoice.report_quantity_lines.splitlines(),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user