diff --git a/modules/purchase_trade/cron.py b/modules/purchase_trade/cron.py
index 6b4f022..559fc0e 100755
--- a/modules/purchase_trade/cron.py
+++ b/modules/purchase_trade/cron.py
@@ -18,6 +18,9 @@ class Cron(metaclass=PoolMeta):
cls.method.selection.append(
('valuation.valuation|update_daily_snapshot',
"Update Valuation Snapshot"))
+ cls.method.selection.append(
+ ('pricing.pricing|update_daily_pricing',
+ "Update Pricing"))
class PriceCron(ModelSQL, ModelView):
"Price Cron"
diff --git a/modules/purchase_trade/cron.xml b/modules/purchase_trade/cron.xml
index 32aff6c..1bbb27a 100755
--- a/modules/purchase_trade/cron.xml
+++ b/modules/purchase_trade/cron.xml
@@ -47,5 +47,11 @@
days
+
+
+ pricing.pricing|update_daily_pricing
+
+ days
+
diff --git a/modules/purchase_trade/pricing.py b/modules/purchase_trade/pricing.py
index 568ecf5..94004ba 100755
--- a/modules/purchase_trade/pricing.py
+++ b/modules/purchase_trade/pricing.py
@@ -1270,20 +1270,39 @@ class Pricing(ModelSQL,ModelView):
"Pricing component must belong to the related line.")
@classmethod
- def _sync_eod_price(cls, records):
- if not records:
- return
- with Transaction().set_context(skip_pricing_eod_sync=True):
- for record in records:
+ def _sync_eod_price(cls, records):
+ if not records:
+ return
+ with Transaction().set_context(skip_pricing_eod_sync=True):
+ for record in records:
eod_price = record.compute_eod_price()
if Decimal(str(record.eod_price or 0)) == Decimal(str(eod_price or 0)):
continue
- super(Pricing, cls).write([record], {
- 'eod_price': eod_price,
- })
-
- @classmethod
- def _is_manual_pricing_record(cls, record):
+ super(Pricing, cls).write([record], {
+ 'eod_price': eod_price,
+ })
+
+ @classmethod
+ def update_daily_pricing(cls):
+ PurchaseLine = Pool().get('purchase.line')
+ SaleLine = Pool().get('sale.line')
+
+ purchase_lines = PurchaseLine.search([])
+ sale_lines = SaleLine.search([])
+
+ for line in purchase_lines:
+ line.check_pricing()
+
+ for sale_line in sale_lines:
+ sale_line.check_pricing()
+
+ logger.info(
+ "Updated pricing for %s purchase line(s) and %s sale line(s)",
+ len(purchase_lines),
+ len(sale_lines))
+
+ @classmethod
+ def _is_manual_pricing_record(cls, record):
component = getattr(record, 'price_component', None)
if component is None:
return True
diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py
index c20d53c..c9bc623 100644
--- a/modules/purchase_trade/tests/test_module.py
+++ b/modules/purchase_trade/tests/test_module.py
@@ -1260,6 +1260,31 @@ class PurchaseTradeTestCase(ModuleTestCase):
self.assertEqual(generate.call_count, 2)
generate_from_sale_line.assert_called_once_with(unmatched_sale_line)
+ def test_update_daily_pricing_checks_all_purchase_and_sale_lines(self):
+ 'daily pricing cron refreshes purchase and sale pricing lines'
+ Pricing = Pool().get('pricing.pricing')
+ PurchaseLine = Mock()
+ SaleLine = Mock()
+ purchase_lines = [Mock(id=1), Mock(id=2)]
+ sale_lines = [Mock(id=3), Mock(id=4)]
+ PurchaseLine.search.return_value = purchase_lines
+ SaleLine.search.return_value = sale_lines
+
+ with patch(
+ 'trytond.modules.purchase_trade.pricing.Pool'
+ ) as PoolMock:
+ PoolMock.return_value.get.side_effect = lambda name: {
+ 'purchase.line': PurchaseLine,
+ 'sale.line': SaleLine,
+ }[name]
+
+ Pricing.update_daily_pricing()
+
+ PurchaseLine.search.assert_called_once_with([])
+ SaleLine.search.assert_called_once_with([])
+ for line in purchase_lines + sale_lines:
+ line.check_pricing.assert_called_once_with()
+
def test_create_pnl_fee_from_line_accepts_missing_rate_amount(self):
'purchase fee valuation treats an uncomputed rate amount as zero'
Valuation = Pool().get('valuation.valuation')