bug template
This commit is contained in:
@@ -109,6 +109,9 @@ class Invoice(metaclass=PoolMeta):
|
|||||||
|
|
||||||
def _get_report_invoice_line_weights(self, line):
|
def _get_report_invoice_line_weights(self, line):
|
||||||
lots = self._get_report_preferred_lots(line)
|
lots = self._get_report_preferred_lots(line)
|
||||||
|
if lots and self._report_invoice_line_reuses_lot(line):
|
||||||
|
quantity = self._get_report_invoice_line_quantity_from_line(line)
|
||||||
|
return quantity, quantity
|
||||||
if lots:
|
if lots:
|
||||||
sign = self._get_report_line_sign(line)
|
sign = self._get_report_line_sign(line)
|
||||||
net_total = Decimal(0)
|
net_total = Decimal(0)
|
||||||
@@ -124,6 +127,49 @@ class Invoice(metaclass=PoolMeta):
|
|||||||
quantity = Decimal(str(getattr(line, 'quantity', 0) or 0))
|
quantity = Decimal(str(getattr(line, 'quantity', 0) or 0))
|
||||||
return quantity, quantity
|
return quantity, quantity
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_report_line_lot_keys(line):
|
||||||
|
keys = []
|
||||||
|
for lot in Invoice._get_report_preferred_lots(line):
|
||||||
|
lot_id = getattr(lot, 'id', None)
|
||||||
|
keys.append(lot_id if lot_id is not None else id(lot))
|
||||||
|
return tuple(sorted(keys))
|
||||||
|
|
||||||
|
def _report_invoice_line_reuses_lot(self, line):
|
||||||
|
line_keys = self._get_report_line_lot_keys(line)
|
||||||
|
if not line_keys:
|
||||||
|
return False
|
||||||
|
for other in self._get_report_invoice_lines():
|
||||||
|
if other is line:
|
||||||
|
continue
|
||||||
|
if self._get_report_line_lot_keys(other) == line_keys:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _convert_report_quantity(quantity, from_unit, to_unit):
|
||||||
|
value = Decimal(str(quantity or 0))
|
||||||
|
if not from_unit or not to_unit:
|
||||||
|
return value
|
||||||
|
if getattr(from_unit, 'id', None) == getattr(to_unit, 'id', None):
|
||||||
|
return value
|
||||||
|
from_name = getattr(from_unit, 'rec_name', None)
|
||||||
|
to_name = getattr(to_unit, 'rec_name', None)
|
||||||
|
if from_name and to_name and from_name == to_name:
|
||||||
|
return value
|
||||||
|
converted = Pool().get('product.uom').compute_qty(
|
||||||
|
from_unit, float(value), to_unit) or 0
|
||||||
|
return Decimal(str(converted))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_report_invoice_line_quantity_from_line(cls, line):
|
||||||
|
quantity = Decimal(str(getattr(line, 'quantity', 0) or 0))
|
||||||
|
return cls._convert_report_quantity(
|
||||||
|
quantity,
|
||||||
|
getattr(line, 'unit', None),
|
||||||
|
cls._get_report_invoice_line_unit(line),
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_report_invoice_line_unit(line):
|
def _get_report_invoice_line_unit(line):
|
||||||
lots = Invoice._get_report_preferred_lots(line)
|
lots = Invoice._get_report_preferred_lots(line)
|
||||||
@@ -1022,6 +1068,9 @@ class InvoiceLine(metaclass=PoolMeta):
|
|||||||
@property
|
@property
|
||||||
def report_net(self):
|
def report_net(self):
|
||||||
if self.type == 'line':
|
if self.type == 'line':
|
||||||
|
invoice = getattr(self, 'invoice', None)
|
||||||
|
if invoice and invoice._report_invoice_line_reuses_lot(self):
|
||||||
|
return Invoice._get_report_invoice_line_quantity_from_line(self)
|
||||||
lot = getattr(self, 'lot', None)
|
lot = getattr(self, 'lot', None)
|
||||||
if lot:
|
if lot:
|
||||||
net, _ = Invoice._get_report_lot_hist_weights(lot)
|
net, _ = Invoice._get_report_lot_hist_weights(lot)
|
||||||
|
|||||||
@@ -1183,6 +1183,63 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
|||||||
self.assertEqual(invoice.report_net, Decimal('800'))
|
self.assertEqual(invoice.report_net, Decimal('800'))
|
||||||
self.assertEqual(invoice.report_gross, Decimal('820'))
|
self.assertEqual(invoice.report_gross, Decimal('820'))
|
||||||
|
|
||||||
|
def test_invoice_report_uses_line_quantities_when_same_lot_is_invoiced_twice(self):
|
||||||
|
'invoice final note keeps line differences when two lines share the same lot'
|
||||||
|
Invoice = Pool().get('account.invoice')
|
||||||
|
|
||||||
|
mt = Mock(id=1, rec_name='MT')
|
||||||
|
kg = Mock(id=2, rec_name='KILOGRAM')
|
||||||
|
shared_lot = Mock(id=10, lot_type='physic', lot_unit_line=kg)
|
||||||
|
shared_lot.get_hist_quantity.return_value = (
|
||||||
|
Decimal('999995'),
|
||||||
|
Decimal('999995'),
|
||||||
|
)
|
||||||
|
|
||||||
|
negative = Mock(
|
||||||
|
type='line',
|
||||||
|
quantity=Decimal('-999.995'),
|
||||||
|
unit=mt,
|
||||||
|
lot=shared_lot,
|
||||||
|
)
|
||||||
|
positive = Mock(
|
||||||
|
type='line',
|
||||||
|
quantity=Decimal('999.990'),
|
||||||
|
unit=mt,
|
||||||
|
lot=shared_lot,
|
||||||
|
)
|
||||||
|
|
||||||
|
invoice = Invoice()
|
||||||
|
negative.invoice = invoice
|
||||||
|
positive.invoice = invoice
|
||||||
|
invoice.lines = [negative, positive]
|
||||||
|
|
||||||
|
uom_model = Mock()
|
||||||
|
uom_model.search.return_value = [Mock(id=3, rec_name='LBS', symbol='LBS')]
|
||||||
|
uom_model.compute_qty.side_effect = (
|
||||||
|
lambda from_unit, qty, to_unit: (
|
||||||
|
qty * 1000
|
||||||
|
if getattr(from_unit, 'rec_name', None) == 'MT'
|
||||||
|
and getattr(to_unit, 'rec_name', None) == 'KILOGRAM'
|
||||||
|
else (
|
||||||
|
qty * 2.20462
|
||||||
|
if getattr(from_unit, 'rec_name', None) == 'KILOGRAM'
|
||||||
|
and getattr(to_unit, 'rec_name', None) == 'LBS'
|
||||||
|
else qty
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch('trytond.modules.purchase_trade.invoice.Pool') as PoolMock:
|
||||||
|
PoolMock.return_value.get.return_value = uom_model
|
||||||
|
|
||||||
|
self.assertEqual(invoice.report_net, Decimal('-5.000'))
|
||||||
|
self.assertEqual(
|
||||||
|
invoice.report_quantity_lines.splitlines(),
|
||||||
|
[
|
||||||
|
'-999995.0 KILOGRAM (-2204608.98 LBS)',
|
||||||
|
'999990.0 KILOGRAM (2204597.95 LBS)',
|
||||||
|
])
|
||||||
|
|
||||||
def test_invoice_report_weights_use_single_virtual_lot_when_no_physical(self):
|
def test_invoice_report_weights_use_single_virtual_lot_when_no_physical(self):
|
||||||
'invoice uses the unique virtual lot hist when no physical lot exists'
|
'invoice uses the unique virtual lot hist when no physical lot exists'
|
||||||
Invoice = Pool().get('account.invoice')
|
Invoice = Pool().get('account.invoice')
|
||||||
|
|||||||
Reference in New Issue
Block a user