Bug create contract
This commit is contained in:
@@ -749,7 +749,11 @@ class BotWizard(Wizard):
|
||||
lms.lot_r_id = ls.getLotQt()[0].id
|
||||
lms.lot_matched_qt = lp.lot_quantity
|
||||
lms.lot_sale = s
|
||||
LotQt.match_lots([lmp],[lms])
|
||||
Lot = Pool().get('lot.lot')
|
||||
with Lot.skip_quantity_consistency():
|
||||
LotQt.match_lots([lmp],[lms])
|
||||
Lot.assert_lines_quantity_consistency(
|
||||
[p.lines[0], s.lines[0]])
|
||||
Sale._process_shipment([s])
|
||||
|
||||
elif do_ == "add":
|
||||
@@ -876,4 +880,4 @@ class BotAction(ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def state_dashboard(cls):
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -230,6 +230,11 @@ class Lot(metaclass=PoolMeta):
|
||||
if getattr(lot, 'sale_line', None):
|
||||
lines.append(lot.sale_line)
|
||||
cls.assert_lines_quantity_consistency(lines)
|
||||
|
||||
@staticmethod
|
||||
def skip_quantity_consistency():
|
||||
return Transaction().set_context(
|
||||
_purchase_trade_skip_quantity_consistency=True)
|
||||
|
||||
line = fields.Many2One('purchase.line',"Purchase",ondelete='CASCADE')
|
||||
move = fields.Function(fields.Many2One('stock.move',"Move"),'get_current_move')
|
||||
@@ -1308,8 +1313,7 @@ class LotQt(
|
||||
lqt.lot_p.line.unit)))
|
||||
tot_qt = round(tot_qt, 5)
|
||||
cls._warn_physical_lot_tolerance(lqt, vlots)
|
||||
with Transaction().set_context(
|
||||
_purchase_trade_skip_quantity_consistency=True):
|
||||
with Lot.skip_quantity_consistency():
|
||||
# Consume the forecast first. Physical lot saves recompute the
|
||||
# virtual lot, so the matching lot.qt must already carry the
|
||||
# target open quantity during the rest of the transaction.
|
||||
@@ -2656,72 +2660,73 @@ class LotShipping(Wizard):
|
||||
affected_lines = []
|
||||
if not self.ship.shipment:
|
||||
pass
|
||||
for r in self.records:
|
||||
if r.r_lot_shipment_in:
|
||||
raise UserError("Please unlink before linking to a new shipment !")
|
||||
else:
|
||||
shipped_quantity = Decimal(str(r.r_lot_quantity)).quantize(Decimal("0.00001"))
|
||||
logger.info("LotShipping:%s",shipped_quantity)
|
||||
shipment_origin = None
|
||||
if self.ship.quantity:
|
||||
shipped_quantity = self.ship.quantity
|
||||
if shipped_quantity == 0:
|
||||
shipped_quantity = Decimal(str(r.r_lot_matched)).quantize(Decimal("0.00001"))
|
||||
if self.ship.shipment == 'in':
|
||||
if not self.ship.shipment_in:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.in,'+str(self.ship.shipment_in.id)
|
||||
elif self.ship.shipment == 'out':
|
||||
if not self.ship.shipment_out:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.out,'+str(self.ship.shipment_out.id)
|
||||
elif self.ship.shipment == 'int':
|
||||
if not self.ship.shipment_internal:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.internal,'+str(self.ship.shipment_internal.id)
|
||||
if r.id < 10000000 :
|
||||
l = Lot(r.id)
|
||||
logger.info("IN_SHIPPING1:%s",l)
|
||||
if self.ship.shipment == 'in':
|
||||
l.lot_shipment_in = self.ship.shipment_in
|
||||
elif self.ship.shipment == 'out':
|
||||
l.lot_shipment_out = self.ship.shipment_out
|
||||
elif self.ship.shipment == 'int':
|
||||
l.lot_shipment_internal = self.ship.shipment_internal
|
||||
logger.info("IN_SHIPPING2:%s",l.move)
|
||||
if not l.move:
|
||||
continue
|
||||
logger.info("IN_SHIPPING3:%s",r)
|
||||
move = Move(l.move)
|
||||
move.shipment = shipment_origin
|
||||
Move.save([move])
|
||||
linked_transit_move = move.get_linked_transit_move()
|
||||
if linked_transit_move:
|
||||
linked_transit_move.shipment = shipment_origin
|
||||
Move.save([linked_transit_move])
|
||||
#Decrease forecasted virtual part shipped
|
||||
vlot_p = l.getVlot_p()
|
||||
l.updateVirtualPart(-l.get_current_quantity_converted(),shipment_origin,l.getVlot_s())
|
||||
l.lot_av = 'reserved'
|
||||
Lot.save([l])
|
||||
l.set_current_quantity(l.lot_quantity,l.lot_gross_quantity,2)
|
||||
Lot.save([l])
|
||||
if l.line:
|
||||
affected_lines.append(l.line)
|
||||
if l.sale_line:
|
||||
affected_lines.append(l.sale_line)
|
||||
with Lot.skip_quantity_consistency():
|
||||
for r in self.records:
|
||||
if r.r_lot_shipment_in:
|
||||
raise UserError("Please unlink before linking to a new shipment !")
|
||||
else:
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
#Increase forecasted virtual part shipped
|
||||
if not lqt.lot_p.updateVirtualPart(shipped_quantity,shipment_origin,lqt.lot_s):
|
||||
logger.info("LotShipping2:%s",shipped_quantity)
|
||||
lqt.lot_p.createVirtualPart(shipped_quantity,shipment_origin,lqt.lot_s)
|
||||
#Decrease forecasted virtual part non shipped
|
||||
lqt.lot_p.updateVirtualPart(-shipped_quantity,None,lqt.lot_s)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
shipped_quantity = Decimal(str(r.r_lot_quantity)).quantize(Decimal("0.00001"))
|
||||
logger.info("LotShipping:%s",shipped_quantity)
|
||||
shipment_origin = None
|
||||
if self.ship.quantity:
|
||||
shipped_quantity = self.ship.quantity
|
||||
if shipped_quantity == 0:
|
||||
shipped_quantity = Decimal(str(r.r_lot_matched)).quantize(Decimal("0.00001"))
|
||||
if self.ship.shipment == 'in':
|
||||
if not self.ship.shipment_in:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.in,'+str(self.ship.shipment_in.id)
|
||||
elif self.ship.shipment == 'out':
|
||||
if not self.ship.shipment_out:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.out,'+str(self.ship.shipment_out.id)
|
||||
elif self.ship.shipment == 'int':
|
||||
if not self.ship.shipment_internal:
|
||||
UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.internal,'+str(self.ship.shipment_internal.id)
|
||||
if r.id < 10000000 :
|
||||
l = Lot(r.id)
|
||||
logger.info("IN_SHIPPING1:%s",l)
|
||||
if self.ship.shipment == 'in':
|
||||
l.lot_shipment_in = self.ship.shipment_in
|
||||
elif self.ship.shipment == 'out':
|
||||
l.lot_shipment_out = self.ship.shipment_out
|
||||
elif self.ship.shipment == 'int':
|
||||
l.lot_shipment_internal = self.ship.shipment_internal
|
||||
logger.info("IN_SHIPPING2:%s",l.move)
|
||||
if not l.move:
|
||||
continue
|
||||
logger.info("IN_SHIPPING3:%s",r)
|
||||
move = Move(l.move)
|
||||
move.shipment = shipment_origin
|
||||
Move.save([move])
|
||||
linked_transit_move = move.get_linked_transit_move()
|
||||
if linked_transit_move:
|
||||
linked_transit_move.shipment = shipment_origin
|
||||
Move.save([linked_transit_move])
|
||||
#Decrease forecasted virtual part shipped
|
||||
vlot_p = l.getVlot_p()
|
||||
l.updateVirtualPart(-l.get_current_quantity_converted(),shipment_origin,l.getVlot_s())
|
||||
l.lot_av = 'reserved'
|
||||
Lot.save([l])
|
||||
l.set_current_quantity(l.lot_quantity,l.lot_gross_quantity,2)
|
||||
Lot.save([l])
|
||||
if l.line:
|
||||
affected_lines.append(l.line)
|
||||
if l.sale_line:
|
||||
affected_lines.append(l.sale_line)
|
||||
else:
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
#Increase forecasted virtual part shipped
|
||||
if not lqt.lot_p.updateVirtualPart(shipped_quantity,shipment_origin,lqt.lot_s):
|
||||
logger.info("LotShipping2:%s",shipped_quantity)
|
||||
lqt.lot_p.createVirtualPart(shipped_quantity,shipment_origin,lqt.lot_s)
|
||||
#Decrease forecasted virtual part non shipped
|
||||
lqt.lot_p.updateVirtualPart(-shipped_quantity,None,lqt.lot_s)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
@@ -2784,13 +2789,14 @@ class LotMatching(Wizard):
|
||||
def transition_matching(self):
|
||||
Warning = Pool().get('res.user.warning')
|
||||
LotQt = Pool().get('lot.qt')
|
||||
if self.match.tot_p != self.match.tot_s:
|
||||
warning_name = Warning.format("Quantity's issue", [])
|
||||
if Warning.check(warning_name):
|
||||
raise QtWarning(warning_name,
|
||||
"Quantities not compatibles")
|
||||
if self.match.tot_p != self.match.tot_s:
|
||||
warning_name = Warning.format("Quantity's issue", [])
|
||||
if Warning.check(warning_name):
|
||||
raise QtWarning(warning_name,
|
||||
"Quantities not compatibles")
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotQt.match_lots(self.match.lot_p,self.match.lot_s)
|
||||
with Lot.skip_quantity_consistency():
|
||||
LotQt.match_lots(self.match.lot_p,self.match.lot_s)
|
||||
affected_lines = []
|
||||
for matched_lot in list(self.match.lot_p or []) + list(self.match.lot_s or []):
|
||||
if matched_lot.lot_id:
|
||||
@@ -2974,42 +2980,43 @@ class LotUnmatch(Wizard):
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotQt = Pool().get('lot.qt')
|
||||
affected_lines = []
|
||||
for r in self.records:
|
||||
if r.id > 10000000 :
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
if lqt.lot_p and lqt.lot_s:
|
||||
lot = lqt.lot_p
|
||||
qt = lqt.lot_quantity
|
||||
#Increase forecasted virtual parts non matched
|
||||
if not lot.updateVirtualPart(qt,lqt.lot_shipment_origin,None):
|
||||
lot.createVirtualPart(qt,lqt.lot_shipment_origin,None)
|
||||
if not lot.updateVirtualPart(qt,lqt.lot_shipment_origin,lqt.lot_s,'only sale'):
|
||||
lot.createVirtualPart(qt,lqt.lot_shipment_origin,lqt.lot_s,'only sale')
|
||||
#Decrease forecasted virtual part matched
|
||||
logger.info("UNMATCH_QT:%s",qt)
|
||||
lot.updateVirtualPart(-qt,lqt.lot_shipment_origin,lqt.lot_s)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
else:
|
||||
lot = Lot(r.id)
|
||||
qt = lot.get_current_quantity_converted()
|
||||
# #Increase forecasted virtual part matched
|
||||
# if not lot.updateVirtualPart(qt,lot.lot_shipment_origin,lot.getVlot_s()):
|
||||
# lot.createVirtualPart(qt,lot.lot_shipment_origin,lot.getVlot_s())
|
||||
# #Decrease forecasted virtual part non matched
|
||||
# if not lot.updateVirtualPart(-qt,lot.lot_shipment_origin,None):
|
||||
# lot.createVirtualPart(-qt,lot.lot_shipment_origin,None)
|
||||
ls = lot.getVlot_s()
|
||||
ls.lot_quantity += qt
|
||||
Lot.save([ls])
|
||||
lot.sale_line = None
|
||||
Lot.save([lot])
|
||||
if lot.line:
|
||||
affected_lines.append(lot.line)
|
||||
if ls.sale_line:
|
||||
affected_lines.append(ls.sale_line)
|
||||
with Lot.skip_quantity_consistency():
|
||||
for r in self.records:
|
||||
if r.id > 10000000 :
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
if lqt.lot_p and lqt.lot_s:
|
||||
lot = lqt.lot_p
|
||||
qt = lqt.lot_quantity
|
||||
#Increase forecasted virtual parts non matched
|
||||
if not lot.updateVirtualPart(qt,lqt.lot_shipment_origin,None):
|
||||
lot.createVirtualPart(qt,lqt.lot_shipment_origin,None)
|
||||
if not lot.updateVirtualPart(qt,lqt.lot_shipment_origin,lqt.lot_s,'only sale'):
|
||||
lot.createVirtualPart(qt,lqt.lot_shipment_origin,lqt.lot_s,'only sale')
|
||||
#Decrease forecasted virtual part matched
|
||||
logger.info("UNMATCH_QT:%s",qt)
|
||||
lot.updateVirtualPart(-qt,lqt.lot_shipment_origin,lqt.lot_s)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
else:
|
||||
lot = Lot(r.id)
|
||||
qt = lot.get_current_quantity_converted()
|
||||
# #Increase forecasted virtual part matched
|
||||
# if not lot.updateVirtualPart(qt,lot.lot_shipment_origin,lot.getVlot_s()):
|
||||
# lot.createVirtualPart(qt,lot.lot_shipment_origin,lot.getVlot_s())
|
||||
# #Decrease forecasted virtual part non matched
|
||||
# if not lot.updateVirtualPart(-qt,lot.lot_shipment_origin,None):
|
||||
# lot.createVirtualPart(-qt,lot.lot_shipment_origin,None)
|
||||
ls = lot.getVlot_s()
|
||||
ls.lot_quantity += qt
|
||||
Lot.save([ls])
|
||||
lot.sale_line = None
|
||||
Lot.save([lot])
|
||||
if lot.line:
|
||||
affected_lines.append(lot.line)
|
||||
if ls.sale_line:
|
||||
affected_lines.append(ls.sale_line)
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
|
||||
@@ -3027,57 +3034,58 @@ class LotUnship(Wizard):
|
||||
LotQt = Pool().get('lot.qt')
|
||||
Move = Pool().get('stock.move')
|
||||
affected_lines = []
|
||||
for r in self.records:
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
lot = Lot(r.id)
|
||||
if lqt and r.r_lot_type == 'virtual':
|
||||
shipment = None
|
||||
qt = lqt.lot_quantity
|
||||
mode = 'both'
|
||||
if not lqt.lot_p:
|
||||
lot = lqt.lot_s
|
||||
mode = 'only sale'
|
||||
else:
|
||||
lot = lqt.lot_p
|
||||
if lqt.lot_shipment_in:
|
||||
shipment = lqt.lot_shipment_in
|
||||
elif lqt.lot_shipment_internal:
|
||||
shipment = lqt.lot_shipment_internal
|
||||
elif lqt.lot_shipment_out:
|
||||
shipment = lqt.lot_shipment_out
|
||||
#Decrease forecasted virtual part shipped
|
||||
lot.updateVirtualPart(-qt,lqt.lot_shipment_origin,lqt.lot_s,mode)
|
||||
#Increase forecasted virtual part non shipped
|
||||
if not lot.updateVirtualPart(qt,None,lqt.lot_s,mode):
|
||||
lot.createVirtualPart(qt,None,lqt.lot_s,mode)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
if lot and r.r_lot_type == 'physic':
|
||||
lot = Lot(r.r_lot_p)
|
||||
if lot.lot_type == 'physic':
|
||||
str_sh = str(lot.lot_shipment_origin)
|
||||
if 'stock.shipment.in' in str_sh:
|
||||
lot.lot_shipment_in = None
|
||||
elif 'stock.shipment.out' in str_sh:
|
||||
lot.lot_shipment_out = None
|
||||
elif 'stock.shipment.internal' in str_sh:
|
||||
lot.lot_shipment_internal = None
|
||||
|
||||
if lot.move:
|
||||
move = Move(lot.move)
|
||||
move.shipment = None
|
||||
Move.save([move])
|
||||
# lm = LotMove.search([('lot','=',lot.id),('move','=',lot.move)])
|
||||
# if lm:
|
||||
# LotMove.delete(lm)
|
||||
lot.lot_status = 'forecast'
|
||||
Lot.save([lot])
|
||||
if lot.line:
|
||||
affected_lines.append(lot.line)
|
||||
if lot.sale_line:
|
||||
affected_lines.append(lot.sale_line)
|
||||
with Lot.skip_quantity_consistency():
|
||||
for r in self.records:
|
||||
lqt = LotQt(r.id - 10000000)
|
||||
lot = Lot(r.id)
|
||||
if lqt and r.r_lot_type == 'virtual':
|
||||
shipment = None
|
||||
qt = lqt.lot_quantity
|
||||
mode = 'both'
|
||||
if not lqt.lot_p:
|
||||
lot = lqt.lot_s
|
||||
mode = 'only sale'
|
||||
else:
|
||||
lot = lqt.lot_p
|
||||
if lqt.lot_shipment_in:
|
||||
shipment = lqt.lot_shipment_in
|
||||
elif lqt.lot_shipment_internal:
|
||||
shipment = lqt.lot_shipment_internal
|
||||
elif lqt.lot_shipment_out:
|
||||
shipment = lqt.lot_shipment_out
|
||||
#Decrease forecasted virtual part shipped
|
||||
lot.updateVirtualPart(-qt,lqt.lot_shipment_origin,lqt.lot_s,mode)
|
||||
#Increase forecasted virtual part non shipped
|
||||
if not lot.updateVirtualPart(qt,None,lqt.lot_s,mode):
|
||||
lot.createVirtualPart(qt,None,lqt.lot_s,mode)
|
||||
if lqt.lot_p and lqt.lot_p.line:
|
||||
affected_lines.append(lqt.lot_p.line)
|
||||
if lqt.lot_s and lqt.lot_s.sale_line:
|
||||
affected_lines.append(lqt.lot_s.sale_line)
|
||||
if lot and r.r_lot_type == 'physic':
|
||||
lot = Lot(r.r_lot_p)
|
||||
if lot.lot_type == 'physic':
|
||||
str_sh = str(lot.lot_shipment_origin)
|
||||
if 'stock.shipment.in' in str_sh:
|
||||
lot.lot_shipment_in = None
|
||||
elif 'stock.shipment.out' in str_sh:
|
||||
lot.lot_shipment_out = None
|
||||
elif 'stock.shipment.internal' in str_sh:
|
||||
lot.lot_shipment_internal = None
|
||||
|
||||
if lot.move:
|
||||
move = Move(lot.move)
|
||||
move.shipment = None
|
||||
Move.save([move])
|
||||
# lm = LotMove.search([('lot','=',lot.id),('move','=',lot.move)])
|
||||
# if lm:
|
||||
# LotMove.delete(lm)
|
||||
lot.lot_status = 'forecast'
|
||||
Lot.save([lot])
|
||||
if lot.line:
|
||||
affected_lines.append(lot.line)
|
||||
if lot.sale_line:
|
||||
affected_lines.append(lot.sale_line)
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
|
||||
@@ -3201,56 +3209,61 @@ class LotImporting(Wizard):
|
||||
def transition_start(self):
|
||||
return 'imp'
|
||||
|
||||
def transition_importing(self):
|
||||
if self.records:
|
||||
line = self.records[0].r_line
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotQt = Pool().get('lot.qt')
|
||||
def transition_importing(self):
|
||||
if self.records:
|
||||
line = self.records[0].r_line
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotQt = Pool().get('lot.qt')
|
||||
LotQtHist = Pool().get('lot.qt.hist')
|
||||
LotQtType = Pool().get('lot.qt.type')
|
||||
lqt = LotQt(self.records[0].id - 10000000)
|
||||
tot_qt = 0
|
||||
for l in self.imp.lots:
|
||||
l.line = line
|
||||
l.lot_shipment_in = self.records[0].r_lot_shipment_in
|
||||
l.lot_shipment_internal = self.records[0].r_lot_shipment_internal
|
||||
l.lot_shipment_out = self.records[0].r_lot_shipment_out
|
||||
l.lot_product = self.records[0].r_lot_product
|
||||
l.sale_line = self.records[0].r_sale_line
|
||||
l.lot_type = 'physic'
|
||||
premium = Decimal(0)
|
||||
if l.lot_price:
|
||||
premium = l.lot_price - l.line.unit_price
|
||||
logger.info("IMPORTLOT:%s",l.line.linked_price)
|
||||
if l.line.linked_price:
|
||||
premium = l.lot_price - l.line.linked_price
|
||||
l.lot_premium = premium
|
||||
l.lot_premium_sup = premium
|
||||
Uom = Pool().get('product.uom')
|
||||
net_qt = round(Decimal(Uom.compute_qty(l.lot_unit_line, float(l.lot_quantity), line.unit)),5)
|
||||
gross_qt = round(Decimal(Uom.compute_qty(l.lot_unit_line, float(l.lot_gross_quantity), line.unit)),5)
|
||||
lqtt = LotQtType.search([('sequence','=',1)])
|
||||
if lqtt:
|
||||
lqh = LotQtHist()
|
||||
lqh.quantity_type = lqtt[0]
|
||||
lqh.quantity = l.lot_quantity
|
||||
lqh.gross_quantity = l.lot_gross_quantity
|
||||
l.lot_hist = [lqh]
|
||||
Lot.save([l])
|
||||
tot_qt += net_qt
|
||||
logger.info("IMPORTING:%s",net_qt)
|
||||
#need to decrease sale virtual lot if matching
|
||||
if self.records[0].r_lot_s:
|
||||
ls = Lot(self.records[0].r_lot_s)
|
||||
ls.lot_quantity -= net_qt
|
||||
ls.lot_gross_quantity -= net_qt
|
||||
ls.lot_qt -= float(net_qt)
|
||||
Lot.save([ls])
|
||||
lqt.lot_quantity -= tot_qt
|
||||
if lqt.lot_quantity < 0:
|
||||
lqt.lot_quantity = 0
|
||||
LotQt.save([lqt])
|
||||
return 'end'
|
||||
LotQtType = Pool().get('lot.qt.type')
|
||||
lqt = LotQt(self.records[0].id - 10000000)
|
||||
tot_qt = 0
|
||||
affected_lines = [line]
|
||||
if self.records[0].r_sale_line:
|
||||
affected_lines.append(self.records[0].r_sale_line)
|
||||
with Lot.skip_quantity_consistency():
|
||||
for l in self.imp.lots:
|
||||
l.line = line
|
||||
l.lot_shipment_in = self.records[0].r_lot_shipment_in
|
||||
l.lot_shipment_internal = self.records[0].r_lot_shipment_internal
|
||||
l.lot_shipment_out = self.records[0].r_lot_shipment_out
|
||||
l.lot_product = self.records[0].r_lot_product
|
||||
l.sale_line = self.records[0].r_sale_line
|
||||
l.lot_type = 'physic'
|
||||
premium = Decimal(0)
|
||||
if l.lot_price:
|
||||
premium = l.lot_price - l.line.unit_price
|
||||
logger.info("IMPORTLOT:%s",l.line.linked_price)
|
||||
if l.line.linked_price:
|
||||
premium = l.lot_price - l.line.linked_price
|
||||
l.lot_premium = premium
|
||||
l.lot_premium_sup = premium
|
||||
Uom = Pool().get('product.uom')
|
||||
net_qt = round(Decimal(Uom.compute_qty(l.lot_unit_line, float(l.lot_quantity), line.unit)),5)
|
||||
gross_qt = round(Decimal(Uom.compute_qty(l.lot_unit_line, float(l.lot_gross_quantity), line.unit)),5)
|
||||
lqtt = LotQtType.search([('sequence','=',1)])
|
||||
if lqtt:
|
||||
lqh = LotQtHist()
|
||||
lqh.quantity_type = lqtt[0]
|
||||
lqh.quantity = l.lot_quantity
|
||||
lqh.gross_quantity = l.lot_gross_quantity
|
||||
l.lot_hist = [lqh]
|
||||
Lot.save([l])
|
||||
tot_qt += net_qt
|
||||
logger.info("IMPORTING:%s",net_qt)
|
||||
#need to decrease sale virtual lot if matching
|
||||
if self.records[0].r_lot_s:
|
||||
ls = Lot(self.records[0].r_lot_s)
|
||||
ls.lot_quantity -= net_qt
|
||||
ls.lot_gross_quantity -= net_qt
|
||||
ls.lot_qt -= float(net_qt)
|
||||
Lot.save([ls])
|
||||
lqt.lot_quantity -= tot_qt
|
||||
if lqt.lot_quantity < 0:
|
||||
lqt.lot_quantity = 0
|
||||
LotQt.save([lqt])
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
|
||||
def end(self):
|
||||
return 'reload'
|
||||
@@ -3823,36 +3836,37 @@ class LotWeighing(Wizard):
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotHist = Pool().get('lot.qt.hist')
|
||||
affected_lines = []
|
||||
for l in self.w.lot_p:
|
||||
quantity = l.lot.get_current_quantity_converted()
|
||||
lhs = LotHist.search([('lot',"=",l.lot.id),('quantity_type','=',self.w.lot_state.id)])
|
||||
if lhs:
|
||||
lh = lhs[0]
|
||||
else:
|
||||
lh = LotHist()
|
||||
lh.lot = l.lot
|
||||
lh.quantity_type = self.w.lot_state
|
||||
lh.quantity = round(l.lot_quantity_new,5)
|
||||
lh.gross_quantity = round(l.lot_gross_quantity_new,5)
|
||||
LotHist.save([lh])
|
||||
l.lot.lot_qt = l.lot_qt
|
||||
|
||||
if self.w.lot_update_state :
|
||||
l.lot.lot_state = self.w.lot_state
|
||||
Lot.save([l.lot])
|
||||
diff = round(Decimal(l.lot.get_current_quantity_converted() - quantity),5)
|
||||
if diff != 0 :
|
||||
#need to update virtual part
|
||||
l.lot.updateVirtualPart(-diff,l.lot.lot_shipment_origin,l.lot.getVlot_s())
|
||||
if l.lot.line:
|
||||
affected_lines.append(l.lot.line)
|
||||
if l.lot.sale_line:
|
||||
affected_lines.append(l.lot.sale_line)
|
||||
#adjuts fee ordered with new quantity
|
||||
fees = FeeLots.search(['lot','=',l.lot.id])
|
||||
for f in fees:
|
||||
f.fee.sync_quantity_from_lots()
|
||||
f.fee.adjust_purchase_values()
|
||||
with Lot.skip_quantity_consistency():
|
||||
for l in self.w.lot_p:
|
||||
quantity = l.lot.get_current_quantity_converted()
|
||||
lhs = LotHist.search([('lot',"=",l.lot.id),('quantity_type','=',self.w.lot_state.id)])
|
||||
if lhs:
|
||||
lh = lhs[0]
|
||||
else:
|
||||
lh = LotHist()
|
||||
lh.lot = l.lot
|
||||
lh.quantity_type = self.w.lot_state
|
||||
lh.quantity = round(l.lot_quantity_new,5)
|
||||
lh.gross_quantity = round(l.lot_gross_quantity_new,5)
|
||||
LotHist.save([lh])
|
||||
l.lot.lot_qt = l.lot_qt
|
||||
|
||||
if self.w.lot_update_state :
|
||||
l.lot.lot_state = self.w.lot_state
|
||||
Lot.save([l.lot])
|
||||
diff = round(Decimal(l.lot.get_current_quantity_converted() - quantity),5)
|
||||
if diff != 0 :
|
||||
#need to update virtual part
|
||||
l.lot.updateVirtualPart(-diff,l.lot.lot_shipment_origin,l.lot.getVlot_s())
|
||||
if l.lot.line:
|
||||
affected_lines.append(l.lot.line)
|
||||
if l.lot.sale_line:
|
||||
affected_lines.append(l.lot.sale_line)
|
||||
#adjuts fee ordered with new quantity
|
||||
fees = FeeLots.search(['lot','=',l.lot.id])
|
||||
for f in fees:
|
||||
f.fee.sync_quantity_from_lots()
|
||||
f.fee.adjust_purchase_values()
|
||||
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
|
||||
@@ -340,18 +340,113 @@ class ContractFactory:
|
||||
qt = source['quantity']
|
||||
|
||||
if type_ == 'Purchase':
|
||||
if cls._attach_or_split_source_lot_qt(source, lot, type_):
|
||||
return
|
||||
if not lot.updateVirtualPart(qt, shipment_origin, vlot):
|
||||
lot.createVirtualPart(qt, shipment_origin, vlot)
|
||||
|
||||
# Decrease forecasted virtual part non matched
|
||||
lot.updateVirtualPart(-qt, shipment_origin, vlot, 'only sale')
|
||||
else:
|
||||
if cls._attach_or_split_source_lot_qt(source, lot, type_):
|
||||
return
|
||||
if not vlot.updateVirtualPart(qt, shipment_origin, lot):
|
||||
vlot.createVirtualPart(qt, shipment_origin, lot)
|
||||
|
||||
# Decrease forecasted virtual part non matched
|
||||
vlot.updateVirtualPart(-qt, shipment_origin, None)
|
||||
|
||||
@classmethod
|
||||
def _attach_or_split_source_lot_qt(cls, source, new_virtual_lot, type_):
|
||||
"""Reuse the selected forecast line instead of create/decrease."""
|
||||
pool = Pool()
|
||||
LotQt = pool.get('lot.qt')
|
||||
|
||||
quantity = cls._normalize_quantity(source['quantity'])
|
||||
source_lqt = source.get('lqt')
|
||||
if not source_lqt:
|
||||
source_lqt = cls._find_source_lot_qt(source, type_)
|
||||
if not source_lqt:
|
||||
return False
|
||||
|
||||
remaining = cls._normalize_quantity(source_lqt.lot_quantity) - quantity
|
||||
if remaining < 0:
|
||||
return False
|
||||
|
||||
if remaining:
|
||||
matched_lqt = LotQt()
|
||||
matched_lqt.lot_p = (
|
||||
new_virtual_lot.id
|
||||
if type_ == 'Purchase'
|
||||
else source_lqt.lot_p)
|
||||
matched_lqt.lot_s = (
|
||||
source_lqt.lot_s
|
||||
if type_ == 'Purchase'
|
||||
else new_virtual_lot.id)
|
||||
matched_lqt.lot_shipment_in = source_lqt.lot_shipment_in
|
||||
matched_lqt.lot_shipment_internal = source_lqt.lot_shipment_internal
|
||||
matched_lqt.lot_shipment_out = source_lqt.lot_shipment_out
|
||||
matched_lqt.lot_move = source_lqt.lot_move
|
||||
matched_lqt.lot_av = source_lqt.lot_av
|
||||
matched_lqt.lot_status = source_lqt.lot_status
|
||||
matched_lqt.lot_unit = source_lqt.lot_unit
|
||||
matched_lqt.lot_quantity = quantity
|
||||
source_lqt.lot_quantity = remaining
|
||||
LotQt.save([source_lqt, matched_lqt])
|
||||
else:
|
||||
if type_ == 'Purchase':
|
||||
source_lqt.lot_p = new_virtual_lot.id
|
||||
else:
|
||||
source_lqt.lot_s = new_virtual_lot.id
|
||||
LotQt.save([source_lqt])
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _find_source_lot_qt(cls, source, type_):
|
||||
pool = Pool()
|
||||
LotQt = pool.get('lot.qt')
|
||||
lot = source.get('lot')
|
||||
if not lot:
|
||||
return None
|
||||
|
||||
domain = []
|
||||
if type_ == 'Purchase':
|
||||
domain.extend([
|
||||
('lot_s', '=', lot.id),
|
||||
('lot_p', '=', None),
|
||||
])
|
||||
else:
|
||||
domain.extend([
|
||||
('lot_p', '=', lot.id),
|
||||
('lot_s', '=', None),
|
||||
])
|
||||
cls._add_shipment_domain(domain, source.get('shipment_origin'))
|
||||
domain.append(('lot_quantity', '!=', 0))
|
||||
lqts = LotQt.search(domain)
|
||||
quantity = cls._normalize_quantity(source['quantity'])
|
||||
for lqt in lqts:
|
||||
if cls._normalize_quantity(lqt.lot_quantity) >= quantity:
|
||||
return lqt
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _add_shipment_domain(domain, shipment_origin):
|
||||
domain.extend([
|
||||
('lot_shipment_in', '=', None),
|
||||
('lot_shipment_internal', '=', None),
|
||||
('lot_shipment_out', '=', None),
|
||||
])
|
||||
if not shipment_origin:
|
||||
return
|
||||
model, record_id = shipment_origin.split(',', 1)
|
||||
record_id = int(record_id)
|
||||
if model == 'stock.shipment.in':
|
||||
domain[-3] = ('lot_shipment_in', '=', record_id)
|
||||
elif model == 'stock.shipment.internal':
|
||||
domain[-2] = ('lot_shipment_internal', '=', record_id)
|
||||
elif model == 'stock.shipment.out':
|
||||
domain[-1] = ('lot_shipment_out', '=', record_id)
|
||||
|
||||
@staticmethod
|
||||
def _get_shipment_origin(ct):
|
||||
if ct.shipment_in:
|
||||
|
||||
Reference in New Issue
Block a user