Duplicate custom

This commit is contained in:
2026-06-18 11:34:19 +02:00
parent 3b3f9c0988
commit 4b5e49f264
2 changed files with 243 additions and 0 deletions

View File

@@ -170,6 +170,127 @@ class TradeCustomDuplicate(Wizard):
return line.getVirtualLot()
return None
@staticmethod
def _line_side(line):
if getattr(line, '__name__', None) == 'purchase.line':
return 'purchase'
if getattr(line, '__name__', None) == 'sale.line':
return 'sale'
if getattr(line, 'purchase', None):
return 'purchase'
if getattr(line, 'sale', None):
return 'sale'
@staticmethod
def _line_quantity(line):
quantity = (
getattr(line, 'quantity_theorical', None)
or getattr(line, 'quantity', None)
or Decimal(0))
return Decimal(str(quantity)).quantize(Decimal("0.00001"))
@staticmethod
def _ensure_open_virtual_lot(line):
product = getattr(line, 'product', None)
if not product or getattr(product, 'type', None) == 'service':
return None
quantity = TradeCustomDuplicate._line_quantity(line)
if quantity <= 0:
return None
side = TradeCustomDuplicate._line_side(line)
if side not in {'purchase', 'sale'}:
return None
lot = TradeCustomDuplicate._first_virtual_lot(line)
if not lot:
lot = TradeCustomDuplicate._create_open_virtual_lot(
line, side, quantity)
TradeCustomDuplicate._ensure_open_lot_qt(lot, side, quantity)
return lot
@staticmethod
def _create_open_virtual_lot(line, side, quantity):
pool = Pool()
Lot = pool.get('lot.lot')
LotQtHist = pool.get('lot.qt.hist')
LotQtType = pool.get('lot.qt.type')
lot = Lot()
if side == 'purchase':
lot.line = line.id
lot.lot_qt = None
lot.lot_unit = None
else:
lot.sale_line = line.id
lot.lot_qt = quantity
lot.lot_unit_line = line.unit
lot.lot_quantity = quantity
lot.lot_gross_quantity = None
lot.lot_status = 'forecast'
lot.lot_type = 'virtual'
lot.lot_product = line.product
lqtt = LotQtType.search([('sequence', '=', 1)])
if lqtt:
lqh = LotQtHist()
lqh.quantity_type = lqtt[0]
lqh.quantity = quantity
lqh.gross_quantity = quantity
lot.lot_hist = [lqh]
Lot.save([lot])
lot = Lot(lot.id)
TradeCustomDuplicate._sync_fee_lots(line, lot, side)
return lot
@staticmethod
def _sync_fee_lots(line, lot, side):
fees = list(getattr(line, 'fees', None) or [])
if not fees:
return
FeeLots = Pool().get('fee.lots')
line_field = 'line' if side == 'purchase' else 'sale_line'
for fee in fees:
domain = [
('fee', '=', fee.id),
('lot', '=', lot.id),
(line_field, '=', line.id),
]
if not FeeLots.search(domain):
fee_lot = FeeLots()
fee_lot.fee = fee.id
fee_lot.lot = lot.id
setattr(fee_lot, line_field, line.id)
FeeLots.save([fee_lot])
@staticmethod
def _ensure_open_lot_qt(lot, side, quantity):
LotQt = Pool().get('lot.qt')
if side == 'purchase':
domain = [
('lot_p', '=', lot.id),
('lot_s', '=', None),
('lot_shipment_in', '=', None),
('lot_shipment_internal', '=', None),
('lot_shipment_out', '=', None),
]
create = lambda: lot.createVirtualPart(quantity, None, None)
else:
domain = [
('lot_p', '=', None),
('lot_s', '=', lot.id),
('lot_shipment_in', '=', None),
('lot_shipment_internal', '=', None),
('lot_shipment_out', '=', None),
]
create = lambda: lot.createVirtualPart(
quantity, None, lot.id, 'only sale')
if not LotQt.search(domain):
create()
@staticmethod
def _create_matched_mirror(record, line, options):
source_model = record.__name__
@@ -222,6 +343,7 @@ class TradeCustomDuplicate(Wizard):
options = self.start
new_record = self._copy_contract(record, options)
new_line = self._apply_line_options(new_record, options)
TradeCustomDuplicate._ensure_open_virtual_lot(new_line)
self.start.duplicated_record_id = new_record.id
if options.create_matched_mirror:
self._create_matched_mirror(new_record, new_line, options)