ITSA points 28.06

This commit is contained in:
2026-06-28 13:31:48 +02:00
parent b7b54c8b7b
commit f45cdb0807
18 changed files with 718 additions and 35 deletions

View File

@@ -272,6 +272,10 @@ class Purchase(metaclass=PoolMeta):
def __setup__(cls):
super().__setup__()
cls._transitions.discard(('confirmed', 'processing'))
cls.lines.states['readonly'] = (
(Eval('state') != 'draft')
& ((Eval('state') != 'quotation')
| ~Eval('allow_modification_after_validation')))
cls._buttons['process'] = {
'invisible': True,
'depends': ['state'],
@@ -380,11 +384,14 @@ class Purchase(metaclass=PoolMeta):
doc_template = fields.Many2One('doc.template',"Template")
required_documents = fields.Many2Many(
'contract.document.type', 'purchase', 'doc_type', 'Required Documents')
analytic_dimensions = fields.One2Many(
'analytic.dimension.assignment',
'purchase',
'Analytic Dimensions'
)
analytic_dimensions = fields.One2Many(
'analytic.dimension.assignment',
'purchase',
'Analytic Dimensions'
)
allow_modification_after_validation = fields.Function(
fields.Boolean("Autorise modification after validation"),
'on_change_with_allow_modification_after_validation')
trader = fields.Many2One(
'party.party', "Trader",
domain=[('categories.name', '=', 'TRADER')])
@@ -404,6 +411,13 @@ class Purchase(metaclass=PoolMeta):
self.company and self.company.party
and self.company.party.name in {'MELYA', 'ITSA'})
def on_change_with_allow_modification_after_validation(self, name=None):
Configuration = Pool().get('purchase.configuration')
configurations = Configuration.search([], limit=1)
return bool(
configurations
and configurations[0].allow_modification_after_validation)
def _get_default_bank_account(self):
if not self.party or not self.party.bank_accounts:
return None
@@ -2087,15 +2101,97 @@ class Line(metaclass=PoolMeta):
raise UserError(
"Shipment period From date must be before To date.")
@classmethod
def _estimated_bl_relation_field(cls):
return 'line'
@classmethod
def _has_estimated_bl_date(cls, estimated_dates):
return any(
getattr(estimated, 'trigger', None) == 'bldate'
for estimated in (estimated_dates or []))
@classmethod
def _values_have_estimated_bl_date(cls, values):
for command in values.get('estimated_date') or []:
action = command[0]
if action == 'create':
if any(
estimated.get('trigger') == 'bldate'
for estimated in command[1]):
return True
elif action == 'write':
actions = iter(command[1:])
for _estimated_ids, estimated_values in zip(actions, actions):
if estimated_values.get('trigger') == 'bldate':
return True
return False
@classmethod
def _delivery_period_from_values(cls, values):
period = values.get('del_period')
if period and not hasattr(period, 'beg_date'):
period = Pool().get('product.month')(period)
return period
@classmethod
def _default_estimated_bl_date(cls, values):
period = cls._delivery_period_from_values(values)
return getattr(period, 'beg_date', None)
@classmethod
def _set_default_estimated_bl_date_values(cls, values):
if cls._values_have_estimated_bl_date(values):
return
estimated_date = cls._default_estimated_bl_date(values)
if not estimated_date:
return
if values.get('estimated_date') is None:
values['estimated_date'] = []
values['estimated_date'].append(('create', [{
'trigger': 'bldate',
'estimated_date': estimated_date,
}]))
@classmethod
def _create_missing_estimated_bl_dates(cls, lines):
Estimated = Pool().get('pricing.estimated')
values = []
relation_field = cls._estimated_bl_relation_field()
for line in lines:
if cls._has_estimated_bl_date(getattr(line, 'estimated_date', None)):
continue
del_period = getattr(line, 'del_period', None)
estimated_date = getattr(del_period, 'beg_date', None)
if not estimated_date:
continue
values.append({
relation_field: line.id,
'trigger': 'bldate',
'estimated_date': estimated_date,
})
if values:
Estimated.create(values)
@classmethod
def create(cls, vlist):
regenerate_valuation = any(
cls._should_regenerate_valuation(values) for values in vlist)
for values in vlist:
cls._check_delivery_period_values([cls()], values)
cls._set_default_estimated_bl_date_values(values)
cls._set_initial_quantity_values(values)
lines = super().create(vlist)
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
Pool().get('fee.rule').apply_to_lines(
lines, 'purchase_line', auto_only=True)
if (regenerate_valuation
and not Transaction().context.get(
'_purchase_trade_skip_valuation_regeneration')):
Valuation = Pool().get('valuation.valuation')
with Transaction().set_context(
_purchase_trade_skip_valuation_regeneration=True):
Valuation.regenerate_for_purchase_lines(lines)
return lines
@classmethod
@@ -2689,12 +2785,28 @@ class Line(metaclass=PoolMeta):
def on_change_linked_unit(self):
self._recompute_trade_price_fields()
@classmethod
def _valuation_regeneration_fields(cls):
return {
'quantity', 'quantity_theorical', 'unit', 'unit_price',
'price_type', 'premium', 'linked_price', 'linked_currency',
'linked_unit', 'price_pricing', 'price_components', 'derivatives',
'fees', 'lots', 'product', 'currency',
}
@classmethod
def _should_regenerate_valuation(cls, values):
return bool(cls._valuation_regeneration_fields() & set(values))
@classmethod
def write(cls, *args):
actions = iter(args)
args = []
valuation_line_ids = set()
for records, values in zip(actions, actions):
cls._check_delivery_period_values(records, values)
if cls._should_regenerate_valuation(values):
valuation_line_ids.update(record.id for record in records)
args.extend((records, values))
# Agents:
@@ -2748,9 +2860,18 @@ class Line(metaclass=PoolMeta):
Pool().get('lot.lot').assert_lines_quantity_consistency(
cls._fresh_lines_for_quantity_consistency(lines))
cls._create_missing_estimated_bl_dates(lines)
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
Pool().get('fee.rule').apply_to_lines(
lines, 'purchase_line', auto_only=True)
if (valuation_line_ids
and not Transaction().context.get(
'_purchase_trade_skip_valuation_regeneration')):
Valuation = Pool().get('valuation.valuation')
with Transaction().set_context(
_purchase_trade_skip_valuation_regeneration=True):
Valuation.regenerate_for_purchase_lines(
cls.browse(list(valuation_line_ids)))
@classmethod
def _sync_open_lot_quantity(cls, line, vlot, target_quantity):