pricing manuel
This commit is contained in:
@@ -413,19 +413,22 @@ class Pricing(ModelSQL,ModelView):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, vlist):
|
def create(cls, vlist):
|
||||||
records = super(Pricing, cls).create(vlist)
|
records = super(Pricing, cls).create(vlist)
|
||||||
|
cls._sync_manual_last(records)
|
||||||
cls._sync_eod_price(records)
|
cls._sync_eod_price(records)
|
||||||
return records
|
return records
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def write(cls, *args):
|
def write(cls, *args):
|
||||||
super(Pricing, cls).write(*args)
|
super(Pricing, cls).write(*args)
|
||||||
if Transaction().context.get('skip_pricing_eod_sync'):
|
if (Transaction().context.get('skip_pricing_eod_sync')
|
||||||
|
or Transaction().context.get('skip_pricing_last_sync')):
|
||||||
return
|
return
|
||||||
records = []
|
records = []
|
||||||
actions = iter(args)
|
actions = iter(args)
|
||||||
for record_set, values in zip(actions, actions):
|
for record_set, values in zip(actions, actions):
|
||||||
if values:
|
if values:
|
||||||
records.extend(record_set)
|
records.extend(record_set)
|
||||||
|
cls._sync_manual_last(records)
|
||||||
cls._sync_eod_price(records)
|
cls._sync_eod_price(records)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -441,6 +444,64 @@ class Pricing(ModelSQL,ModelView):
|
|||||||
'eod_price': eod_price,
|
'eod_price': eod_price,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_manual_last_group_domain(cls, record):
|
||||||
|
component = getattr(record, 'price_component', None)
|
||||||
|
if getattr(record, 'sale_line', None):
|
||||||
|
domain = [
|
||||||
|
('sale_line', '=', record.sale_line.id),
|
||||||
|
]
|
||||||
|
domain.append((
|
||||||
|
'price_component',
|
||||||
|
'=',
|
||||||
|
component.id if getattr(component, 'id', None) else None,
|
||||||
|
))
|
||||||
|
return domain
|
||||||
|
if getattr(record, 'line', None):
|
||||||
|
domain = [
|
||||||
|
('line', '=', record.line.id),
|
||||||
|
]
|
||||||
|
domain.append((
|
||||||
|
'price_component',
|
||||||
|
'=',
|
||||||
|
component.id if getattr(component, 'id', None) else None,
|
||||||
|
))
|
||||||
|
return domain
|
||||||
|
return None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sync_manual_last(cls, records):
|
||||||
|
if not records:
|
||||||
|
return
|
||||||
|
domains = []
|
||||||
|
seen = set()
|
||||||
|
for record in records:
|
||||||
|
domain = cls._get_manual_last_group_domain(record)
|
||||||
|
if not domain:
|
||||||
|
continue
|
||||||
|
key = tuple(domain)
|
||||||
|
if key in seen:
|
||||||
|
continue
|
||||||
|
seen.add(key)
|
||||||
|
domains.append(domain)
|
||||||
|
if not domains:
|
||||||
|
return
|
||||||
|
with Transaction().set_context(
|
||||||
|
skip_pricing_last_sync=True,
|
||||||
|
skip_pricing_eod_sync=True):
|
||||||
|
for domain in domains:
|
||||||
|
pricings = cls.search(
|
||||||
|
domain,
|
||||||
|
order=[('pricing_date', 'ASC'), ('id', 'ASC')])
|
||||||
|
if not pricings:
|
||||||
|
continue
|
||||||
|
last_pricing = pricings[-1]
|
||||||
|
for pricing in pricings[:-1]:
|
||||||
|
if pricing.last:
|
||||||
|
super(Pricing, cls).write([pricing], {'last': False})
|
||||||
|
if not last_pricing.last:
|
||||||
|
super(Pricing, cls).write([last_pricing], {'last': True})
|
||||||
|
|
||||||
def get_fixed_price(self):
|
def get_fixed_price(self):
|
||||||
price = Decimal(0)
|
price = Decimal(0)
|
||||||
Pricing = Pool().get('pricing.pricing')
|
Pricing = Pool().get('pricing.pricing')
|
||||||
|
|||||||
@@ -290,6 +290,38 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
purchase_pricing.get_eod_price_purchase(), Decimal('106.0000'))
|
purchase_pricing.get_eod_price_purchase(), Decimal('106.0000'))
|
||||||
|
|
||||||
|
def test_pricing_sync_manual_last_uses_greatest_date_per_component_group(self):
|
||||||
|
'pricing rows keep one last by line/component, chosen by greatest pricing date'
|
||||||
|
Pricing = Pool().get('pricing.pricing')
|
||||||
|
|
||||||
|
sale_line = Mock(id=10)
|
||||||
|
component = Mock(id=33)
|
||||||
|
first = Mock(
|
||||||
|
id=1,
|
||||||
|
price_component=component,
|
||||||
|
sale_line=sale_line,
|
||||||
|
line=None,
|
||||||
|
pricing_date=datetime.date(2026, 4, 10),
|
||||||
|
last=True,
|
||||||
|
)
|
||||||
|
second = Mock(
|
||||||
|
id=2,
|
||||||
|
price_component=component,
|
||||||
|
sale_line=sale_line,
|
||||||
|
line=None,
|
||||||
|
pricing_date=datetime.date(2026, 4, 9),
|
||||||
|
last=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch.object(Pricing, 'search', return_value=[second, first]), patch(
|
||||||
|
'trytond.modules.purchase_trade.pricing.super') as super_mock:
|
||||||
|
Pricing._sync_manual_last([first, second])
|
||||||
|
|
||||||
|
self.assertEqual(super_mock.return_value.write.call_args_list[0].args[0], [second])
|
||||||
|
self.assertEqual(super_mock.return_value.write.call_args_list[0].args[1], {'last': False})
|
||||||
|
self.assertEqual(super_mock.return_value.write.call_args_list[1].args[0], [first])
|
||||||
|
self.assertEqual(super_mock.return_value.write.call_args_list[1].args[1], {'last': True})
|
||||||
|
|
||||||
def test_sale_and_purchase_trader_operator_domains_use_explicit_categories(self):
|
def test_sale_and_purchase_trader_operator_domains_use_explicit_categories(self):
|
||||||
'sale and purchase trader/operator fields are filtered by TRADER/OPERATOR categories'
|
'sale and purchase trader/operator fields are filtered by TRADER/OPERATOR categories'
|
||||||
Sale = Pool().get('sale.sale')
|
Sale = Pool().get('sale.sale')
|
||||||
|
|||||||
Reference in New Issue
Block a user