diff --git a/modules/purchase_trade/pricing.py b/modules/purchase_trade/pricing.py index 1ebcf6f..df9a8a2 100755 --- a/modules/purchase_trade/pricing.py +++ b/modules/purchase_trade/pricing.py @@ -1032,11 +1032,26 @@ class Pricing(ModelSQL,ModelView): def default_settl_price(cls): return Decimal(0) - @classmethod - def default_eod_price(cls): - return Decimal(0) - - @fields.depends('line', 'sale_line') + @classmethod + def default_eod_price(cls): + return Decimal(0) + + @classmethod + def default_price_component(cls): + Component = Pool().get('pricing.component') + context = Transaction().context + domains = [] + if context.get('default_line'): + domains.append([('line', '=', context['default_line'])]) + if context.get('default_sale_line'): + domains.append([('sale_line', '=', context['default_sale_line'])]) + for domain in domains: + component = cls._get_single_manual_component( + Component.search(domain, limit=2)) + if component: + return component.id + + @fields.depends('line', 'sale_line') def on_change_with_available_components(self, name=None): Component = Pool().get('pricing.component') line = getattr(self, 'line', None) @@ -1050,10 +1065,34 @@ class Pricing(ModelSQL,ModelView): @classmethod def set_available_components(cls, records, name, value): pass - - @staticmethod - def _weighted_average_price(fixed_qt, fixed_price, unfixed_qt, unfixed_price): - fixed_qt = Decimal(str(fixed_qt or 0)) + + @staticmethod + def _get_single_manual_component(components): + manual_components = [ + component for component in components + if not getattr(component, 'auto', False)] + if len(manual_components) == 1 and len(components) == 1: + return manual_components[0] + + def _default_single_manual_component(self): + if self.price_component: + return + component = self._get_single_manual_component( + self.on_change_with_available_components()) + if component: + self.price_component = component + + @fields.depends('line', 'sale_line', 'price_component') + def on_change_line(self): + self._default_single_manual_component() + + @fields.depends('line', 'sale_line', 'price_component') + def on_change_sale_line(self): + self._default_single_manual_component() + + @staticmethod + def _weighted_average_price(fixed_qt, fixed_price, unfixed_qt, unfixed_price): + fixed_qt = Decimal(str(fixed_qt or 0)) fixed_price = Decimal(str(fixed_price or 0)) unfixed_qt = Decimal(str(unfixed_qt or 0)) unfixed_price = Decimal(str(unfixed_price or 0)) diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 8fcb052..de29f35 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -2591,6 +2591,68 @@ class PurchaseTradeTestCase(ModuleTestCase): ('id', 'in', Eval('available_components', [])), ]) + def test_pricing_defaults_single_manual_purchase_component(self): + 'new purchase pricing rows default the only manual line component' + Pricing = Pool().get('pricing.pricing') + owner = Mock(id=10) + component = Mock(id=33, auto=False) + component_model = Mock() + component_model.search.return_value = [component] + pool = Mock() + pool.get.return_value = component_model + pricing = Pricing() + pricing.line = owner + pricing.sale_line = None + pricing.price_component = None + + with patch('trytond.modules.purchase_trade.pricing.Pool', + return_value=pool): + pricing.on_change_line() + + component_model.search.assert_called_once_with([('line', '=', owner)]) + self.assertEqual(pricing.price_component, component) + + def test_pricing_defaults_single_manual_sale_component(self): + 'new sale pricing rows default the only manual line component' + Pricing = Pool().get('pricing.pricing') + owner = Mock(id=10) + component = Mock(id=33, auto=False) + component_model = Mock() + component_model.search.return_value = [component] + pool = Mock() + pool.get.return_value = component_model + pricing = Pricing() + pricing.line = None + pricing.sale_line = owner + pricing.price_component = None + + with patch('trytond.modules.purchase_trade.pricing.Pool', + return_value=pool): + pricing.on_change_sale_line() + + component_model.search.assert_called_once_with([ + ('sale_line', '=', owner)]) + self.assertEqual(pricing.price_component, component) + + def test_pricing_does_not_default_single_auto_component(self): + 'new manual pricing rows do not default an auto component' + Pricing = Pool().get('pricing.pricing') + owner = Mock(id=10) + component_model = Mock() + component_model.search.return_value = [Mock(id=33, auto=True)] + pool = Mock() + pool.get.return_value = component_model + pricing = Pricing() + pricing.line = owner + pricing.sale_line = None + pricing.price_component = None + + with patch('trytond.modules.purchase_trade.pricing.Pool', + return_value=pool): + pricing.on_change_line() + + self.assertIsNone(pricing.price_component) + def test_pricing_component_must_belong_to_pricing_owner(self): 'pricing rows reject components from another purchase or sale line' Pricing = Pool().get('pricing.pricing')