diff --git a/modules/purchase_trade/fee.py b/modules/purchase_trade/fee.py index 56bffc5..2a75034 100755 --- a/modules/purchase_trade/fee.py +++ b/modules/purchase_trade/fee.py @@ -55,9 +55,24 @@ class Fee(ModelSQL,ModelView): ('pay', 'PAY'), ('rec', 'REC'), ], "P/R", required=True) - product = fields.Many2One('product.product',"Product", required=True, domain=[('type', '=', 'service')]) - price = fields.Numeric("Price",digits=(1,4)) - mode = fields.Selection([ + product = fields.Many2One('product.product',"Product", required=True, domain=[('type', '=', 'service')]) + price = fields.Numeric("Price",digits=(1,4)) + enable_linked_currency = fields.Boolean("Linked currencies") + linked_price = fields.Numeric("Linked Price", digits='unit', states={ + 'invisible': ~Eval('enable_linked_currency'), + 'required': Eval('enable_linked_currency'), + }, depends=['enable_linked_currency']) + linked_currency = fields.Many2One('currency.linked', "Linked Currency", + states={ + 'invisible': ~Eval('enable_linked_currency'), + 'required': Eval('enable_linked_currency'), + }, depends=['enable_linked_currency']) + linked_unit = fields.Many2One('product.uom', "Linked Unit", + states={ + 'invisible': ~Eval('enable_linked_currency'), + 'required': Eval('enable_linked_currency'), + }, depends=['enable_linked_currency']) + mode = fields.Selection([ ('lumpsum', 'Lump sum'), ('perqt', 'Per qt'), ('pprice', '% price'), @@ -129,6 +144,75 @@ class Fee(ModelSQL,ModelView): @classmethod def default_qt_state(cls): return None + + def _get_linked_unit_factor(self): + if not (self.enable_linked_currency and self.linked_currency): + return None + factor = Decimal(self.linked_currency.factor or 0) + if not factor: + return None + unit_factor = Decimal(1) + if self.linked_unit: + source_unit = getattr(self, 'unit', None) + if not source_unit: + return factor + Uom = Pool().get('product.uom') + unit_factor = Decimal(str( + Uom.compute_qty(source_unit, float(1), self.linked_unit) or 0)) + return factor * unit_factor + + def _linked_to_fee_price(self, price): + factor = self._get_linked_unit_factor() + price = Decimal(price or 0) + if not factor: + return price + return round(price * factor, 4) + + def _fee_to_linked_price(self, price): + factor = self._get_linked_unit_factor() + price = Decimal(price or 0) + if not factor: + return price + return round(price / factor, 4) + + def _sync_price_from_linked(self): + if (self.enable_linked_currency and self.linked_currency + and self.linked_price is not None): + self.price = self._linked_to_fee_price(self.linked_price) + + @fields.depends( + 'enable_linked_currency', 'linked_currency', 'linked_unit', + 'linked_price', 'price', 'unit') + def on_change_enable_linked_currency(self): + if self.enable_linked_currency and self.price is not None: + self.linked_price = self._fee_to_linked_price(self.price) + self._sync_price_from_linked() + + @fields.depends( + 'enable_linked_currency', 'linked_currency', 'linked_unit', + 'linked_price', 'unit') + def on_change_linked_price(self): + self._sync_price_from_linked() + + @fields.depends( + 'enable_linked_currency', 'linked_currency', 'linked_unit', + 'linked_price', 'unit') + def on_change_linked_currency(self): + self._sync_price_from_linked() + + @fields.depends( + 'enable_linked_currency', 'linked_currency', 'linked_unit', + 'linked_price', 'unit') + def on_change_linked_unit(self): + self._sync_price_from_linked() + + @fields.depends( + 'enable_linked_currency', 'linked_currency', 'linked_unit', + 'price', 'unit') + def on_change_price(self): + if (self.enable_linked_currency and self.linked_currency + and self.price is not None): + self.linked_price = self._fee_to_linked_price(self.price) @fields.depends('mode','unit') def on_change_with_packing_category(self, name=None): diff --git a/modules/purchase_trade/lot.py b/modules/purchase_trade/lot.py index f123a7c..95db10d 100755 --- a/modules/purchase_trade/lot.py +++ b/modules/purchase_trade/lot.py @@ -294,8 +294,6 @@ class Lot(metaclass=PoolMeta): @classmethod def default_lot_unit(cls): - if is_itsa_company(): - return default_itsa_unit() default = getattr(super(), 'default_lot_unit', None) if default: return default() @@ -4599,9 +4597,10 @@ class LotInvoice(Wizard): val['lot_diff_quantity'] = Decimal(0) val['lot_diff_price'] = Decimal(0) val['lot_diff_amount'] = Decimal(0) - val['lot_quantity'] = lot.get_current_quantity_converted() - val['lot_price'] = lot.lot_price - val['lot_amount'] = lot.get_current_quantity_converted() * lot.lot_price if lot.lot_price else Decimal(0) + val['lot_quantity'] = lot.get_current_quantity_converted() + val['sale_invoice_padding'] = lot.sale_invoice_padding + val['lot_price'] = lot.lot_price + val['lot_amount'] = lot.get_current_quantity_converted() * lot.lot_price if lot.lot_price else Decimal(0) if lot.invoice_line_prov: val['lot_diff_quantity'] = val['lot_quantity'] - Decimal(lot.invoice_line_prov.quantity) val['lot_diff_price'] = val['lot_price'] - Decimal(lot.invoice_line_prov.unit_price) @@ -4908,10 +4907,12 @@ class LotInvoicingLot(ModelView): lis = fields.Many2One('lot.invoice.start',"Invoicing") lot = fields.Many2One('lot.lot',"Lot") lot_name = fields.Char("Name",readonly=True) - lot_state = fields.Many2One('lot.qt.type',"State") - lot_quantity = fields.Numeric("Qt",digits='unit',readonly=True) - lot_diff_quantity = fields.Numeric("Diff. qt",digits='unit',readonly=True) - lot_unit = fields.Many2One('product.uom',"Unit",readonly=True) + lot_state = fields.Many2One('lot.qt.type',"State") + lot_quantity = fields.Numeric("Qt",digits='unit',readonly=True) + sale_invoice_padding = fields.Numeric( + "Padding", digits='lot_unit', readonly=True) + lot_diff_quantity = fields.Numeric("Diff. qt",digits='unit',readonly=True) + lot_unit = fields.Many2One('product.uom',"Unit",readonly=True) lot_price = fields.Numeric("Price",digits='unit',readonly=True) lot_diff_price = fields.Numeric("Diff. price",digits='unit',readonly=True) lot_currency = fields.Char("Curr") @@ -5007,6 +5008,7 @@ class LotWeighing(Wizard): val['lot_qt'] = lot.lot_qt val['lot_quantity'] = lot.lot_quantity val['lot_gross_quantity'] = lot.lot_gross_quantity + val['sale_invoice_padding'] = lot.sale_invoice_padding val['lot_unit'] = lot.lot_unit.id val['lot_unit_line'] = lot.lot_unit_line.id lot_p.append(val) @@ -5083,6 +5085,8 @@ class LotWeighingLot(ModelView): lot_qt = fields.Integer("Qt") lot_quantity = fields.Numeric("Net weight",digits=(1,5),readonly=True) lot_gross_quantity = fields.Numeric("Gross weight",digits=(1,5),readonly=True) + sale_invoice_padding = fields.Numeric( + "Padding", digits='lot_unit_line', readonly=True) lot_unit = fields.Many2One('product.uom',"Unit",readonly=True) lot_unit_line = fields.Many2One('product.uom',"Unit",readonly=True) lot_quantity_new = fields.Numeric("New net weight",digits=(1,5)) diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py index 824ed8a..8b32ce9 100755 --- a/modules/purchase_trade/purchase.py +++ b/modules/purchase_trade/purchase.py @@ -322,7 +322,7 @@ class Purchase(metaclass=PoolMeta): fields.Many2Many('bank.account', None, None, "Bank Accounts"), 'on_change_with_bank_accounts') bank_account = fields.Many2One( - 'bank.account', "Bank Account", + 'bank.account', "Supplier Bank Account", domain=[('id', 'in', Eval('bank_accounts', []))], depends=['bank_accounts']) our_bank_account = fields.Many2One( diff --git a/modules/purchase_trade/sale.py b/modules/purchase_trade/sale.py index 72f029f..be95414 100755 --- a/modules/purchase_trade/sale.py +++ b/modules/purchase_trade/sale.py @@ -283,7 +283,7 @@ class Sale(metaclass=PoolMeta): fields.Many2Many('bank.account', None, None, "Bank Accounts"), 'on_change_with_bank_accounts') bank_account = fields.Many2One( - 'bank.account', "Bank Account", + 'bank.account', "Client Bank Account", domain=[('id', 'in', Eval('bank_accounts', []))], depends=['bank_accounts']) our_bank_account = fields.Many2One( diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index c68dbe3..2ac1acf 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -1568,6 +1568,25 @@ class PurchaseTradeTestCase(ModuleTestCase): self.assertEqual(fee.quantity, Decimal('3')) save.assert_not_called() + def test_fee_linked_price_updates_fee_price(self): + 'fee linked price converts to the accounting currency price' + Fee = Pool().get('fee.fee') + fee = Fee() + fee.enable_linked_currency = True + fee.linked_price = Decimal('15') + fee.linked_currency = Mock(factor=Decimal('0.01')) + fee.linked_unit = Mock() + fee.unit = Mock() + Uom = Mock() + Uom.compute_qty.return_value = Decimal('2') + + with patch('trytond.modules.purchase_trade.fee.Pool') as PoolMock: + PoolMock.return_value.get.return_value = Uom + + fee.on_change_linked_price() + + self.assertEqual(fee.price, Decimal('0.3000')) + def test_fee_pnl_regeneration_uses_shipment_lotqt_purchase_line(self): 'fee pnl regeneration follows shipment lot.qt back to purchase line' Fee = Pool().get('fee.fee') diff --git a/modules/purchase_trade/view/fee_form.xml b/modules/purchase_trade/view/fee_form.xml index c32fe47..2dda642 100755 --- a/modules/purchase_trade/view/fee_form.xml +++ b/modules/purchase_trade/view/fee_form.xml @@ -3,6 +3,20 @@