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

@@ -21,6 +21,7 @@ from trytond.modules.purchase_trade import sale as sale_module
from trytond.modules.purchase_trade import stock as stock_module
from trytond.modules.purchase_trade import fee as fee_module
from trytond.modules.purchase_trade import pricing as pricing_module
from trytond.modules.purchase_trade import duplicate as duplicate_module
from trytond.modules.purchase_trade import company_defaults
from trytond.modules.purchase_trade.service import ContractFactory
@@ -6053,6 +6054,126 @@ class PurchaseTradeTestCase(ModuleTestCase):
self.assertIsNone(
ContractFactory._get_shipment_origin(ContractsStartMock()))
def test_custom_duplicate_creates_purchase_open_virtual_lot(self):
'custom duplicate creates the purchase opening lot.qt explicitly'
saved_lots = []
virtual_parts = []
class FakeLot:
def __init__(self, id=None):
self.id = id
@classmethod
def save(cls, lots):
for lot in lots:
lot.id = 42
saved_lots.append(lot)
def createVirtualPart(self, quantity, shipment, sale_lot):
virtual_parts.append((self.id, quantity, shipment, sale_lot))
class FakeLotQt:
@classmethod
def search(cls, domain):
return []
class FakeLotQtHist:
pass
class FakeLotQtType:
@classmethod
def search(cls, domain):
return [Mock()]
pool = Mock()
pool.get.side_effect = lambda name: {
'lot.lot': FakeLot,
'lot.qt': FakeLotQt,
'lot.qt.hist': FakeLotQtHist,
'lot.qt.type': FakeLotQtType,
}[name]
line = SimpleNamespace(
__name__='purchase.line',
id=10,
lots=[],
product=Mock(type='goods'),
unit=Mock(),
quantity=Decimal('0'),
quantity_theorical=Decimal('125'),
fees=[],
purchase=Mock(),
)
with patch.object(duplicate_module, 'Pool', return_value=pool):
lot = duplicate_module.TradeCustomDuplicate._ensure_open_virtual_lot(
line)
self.assertEqual(lot.id, 42)
self.assertEqual(saved_lots[0].line, 10)
self.assertEqual(saved_lots[0].lot_quantity, Decimal('125.00000'))
self.assertEqual(virtual_parts, [
(42, Decimal('125.00000'), None, None)])
def test_custom_duplicate_creates_sale_open_virtual_lot(self):
'custom duplicate creates the sale opening lot.qt explicitly'
saved_lots = []
virtual_parts = []
class FakeLot:
def __init__(self, id=None):
self.id = id
@classmethod
def save(cls, lots):
for lot in lots:
lot.id = 43
saved_lots.append(lot)
def createVirtualPart(self, quantity, shipment, lot_s, mode):
virtual_parts.append((self.id, quantity, shipment, lot_s, mode))
class FakeLotQt:
@classmethod
def search(cls, domain):
return []
class FakeLotQtHist:
pass
class FakeLotQtType:
@classmethod
def search(cls, domain):
return []
pool = Mock()
pool.get.side_effect = lambda name: {
'lot.lot': FakeLot,
'lot.qt': FakeLotQt,
'lot.qt.hist': FakeLotQtHist,
'lot.qt.type': FakeLotQtType,
}[name]
line = SimpleNamespace(
__name__='sale.line',
id=11,
lots=[],
product=Mock(type='goods'),
unit=Mock(),
quantity=Decimal('0'),
quantity_theorical=Decimal('50'),
fees=[],
sale=Mock(),
)
with patch.object(duplicate_module, 'Pool', return_value=pool):
lot = duplicate_module.TradeCustomDuplicate._ensure_open_virtual_lot(
line)
self.assertEqual(lot.id, 43)
self.assertEqual(saved_lots[0].sale_line, 11)
self.assertEqual(saved_lots[0].lot_quantity, Decimal('50.00000'))
self.assertEqual(virtual_parts, [
(43, Decimal('50.00000'), None, 43, 'only sale')])
def test_lot_matching_rejects_purchase_quantity_above_available(self):
'apply matching cannot consume more than available purchase quantity'
class LotQtMock: