check qt create contract & matching
This commit is contained in:
@@ -1025,6 +1025,24 @@ class LotQt(
|
||||
logger.info("MATCH_LOTS:%s",lot_s)
|
||||
LotQt = Pool().get('lot.qt')
|
||||
Lot = Pool().get('lot.lot')
|
||||
for lp in lot_p:
|
||||
qt_p = Decimal(str(lp.lot_matched_qt or 0))
|
||||
if qt_p <= 0:
|
||||
continue
|
||||
lqt = LotQt(lp.lot_r_id)
|
||||
available = Decimal(str(lqt.lot_quantity or 0))
|
||||
if qt_p > available:
|
||||
raise UserError(
|
||||
"Quantity to match exceeds the available purchase quantity.")
|
||||
for ls in lot_s:
|
||||
qt_s = Decimal(str(ls.lot_matched_qt or 0))
|
||||
if qt_s <= 0:
|
||||
continue
|
||||
lqt = LotQt(ls.lot_r_id)
|
||||
available = abs(Decimal(str(lqt.lot_quantity or 0)))
|
||||
if qt_s > available:
|
||||
raise UserError(
|
||||
"Quantity to match exceeds the available sale quantity.")
|
||||
for lp in lot_p:
|
||||
qt_p = lp.lot_matched_qt
|
||||
if qt_p == 0:
|
||||
|
||||
@@ -37,6 +37,7 @@ class ContractFactory:
|
||||
|
||||
created = []
|
||||
sources = cls._get_sources(ct, type_)
|
||||
cls._validate_requested_quantity(contracts, sources, ct)
|
||||
base_contract = cls._get_base_contract(sources, ct, type_)
|
||||
|
||||
for c in contracts:
|
||||
@@ -251,6 +252,18 @@ class ContractFactory:
|
||||
if getattr(line.unit, 'id', None) != getattr(first_line.unit, 'id', None):
|
||||
raise UserError('Selected lots must share the same unit.')
|
||||
|
||||
@classmethod
|
||||
def _validate_requested_quantity(cls, contracts, sources, ct):
|
||||
if not getattr(ct, 'matched', False) or not sources:
|
||||
return
|
||||
available = sum(source['quantity'] for source in sources)
|
||||
requested = sum(
|
||||
cls._normalize_quantity(contract.quantity)
|
||||
for contract in contracts)
|
||||
if requested > available:
|
||||
raise UserError(
|
||||
'The requested quantity exceeds the selected open quantity.')
|
||||
|
||||
@classmethod
|
||||
def _get_line_sources(cls, contract_detail, sources, ct):
|
||||
if not ct.matched or len(sources) <= 1:
|
||||
|
||||
@@ -2348,6 +2348,36 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
with self.assertRaises(UserError):
|
||||
ContractFactory._get_line_sources(contract_detail, sources, ct)
|
||||
|
||||
def test_contract_factory_rejects_total_above_selected_open_quantity(self):
|
||||
'matched create contracts cannot consume more than selected open quantity'
|
||||
contracts = [
|
||||
Mock(quantity=Decimal('100')),
|
||||
Mock(quantity=Decimal('100')),
|
||||
]
|
||||
ct = Mock(matched=True)
|
||||
sources = [
|
||||
{'lot': Mock(), 'trade_line': Mock(), 'quantity': Decimal('100')},
|
||||
]
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
ContractFactory._validate_requested_quantity(contracts, sources, ct)
|
||||
|
||||
def test_lot_matching_rejects_purchase_quantity_above_available(self):
|
||||
'apply matching cannot consume more than available purchase quantity'
|
||||
class LotQtMock:
|
||||
def __call__(self, _id):
|
||||
return Mock(lot_quantity=Decimal('100'))
|
||||
|
||||
pool = Mock()
|
||||
pool.get.side_effect = (
|
||||
lambda name: LotQtMock() if name == 'lot.qt' else Mock())
|
||||
purchase_lot = Mock(
|
||||
lot_matched_qt=Decimal('101'), lot_r_id=1)
|
||||
|
||||
with patch.object(lot_module, 'Pool', return_value=pool):
|
||||
with self.assertRaises(UserError):
|
||||
lot_module.LotQt.match_lots([purchase_lot], [])
|
||||
|
||||
def test_contract_detail_defaults_sale_locations_from_dropship_purchase(self):
|
||||
'create contracts copies supplier-to-customer locations from purchase to sale'
|
||||
supplier = Mock(id=1, type='supplier')
|
||||
|
||||
Reference in New Issue
Block a user