Jauge tolerance

This commit is contained in:
2026-05-17 17:22:40 +02:00
parent 9d436d6ea0
commit b35fa829e2
9 changed files with 317 additions and 5 deletions

View File

@@ -273,11 +273,17 @@ class Purchase(metaclass=PoolMeta):
to_location = fields.Many2One('stock.location', 'To location', required=True,domain=[('type', "!=", 'supplier')])
shipment_in = fields.Many2One('stock.shipment.in','Purchases')
broker = fields.Many2One('party.party',"Broker",domain=[('categories.parent', 'child_of', [4])])
tol_min = fields.Numeric("Tol - in %", required=True)
tol_max = fields.Numeric("Tol + in %", required=True)
tol_min_qt = fields.Numeric("Tol -")
tol_max_qt = fields.Numeric("Tol +")
certif = fields.Many2One('purchase.certification',"Certification", required=True,states={'invisible': Eval('company_visible'),})
tol_min = fields.Numeric("Tol - in %", required=True)
tol_max = fields.Numeric("Tol + in %", required=True)
tol_min_qt = fields.Numeric("Tol -")
tol_max_qt = fields.Numeric("Tol +")
tolerance_used = fields.Function(
fields.Numeric("Tolerance used"), 'get_tolerance_used')
tolerance_min = fields.Function(
fields.Numeric("Tolerance min"), 'get_tolerance_min')
tolerance_max = fields.Function(
fields.Numeric("Tolerance max"), 'get_tolerance_max')
certif = fields.Many2One('purchase.certification',"Certification", required=True,states={'invisible': Eval('company_visible'),})
wb = fields.Many2One('purchase.weight.basis',"Weight basis", required=True)
association = fields.Many2One('purchase.association',"Association", required=True,states={'invisible': Eval('company_visible'),})
crop = fields.Many2One('purchase.crop',"Crop",states={'invisible': Eval('company_visible'),})
@@ -395,6 +401,62 @@ class Purchase(metaclass=PoolMeta):
def default_tol_max(cls):
return 0
def _line_quantity_in_unit(self, quantity, from_unit, to_unit):
if not from_unit or not to_unit or from_unit == to_unit:
return Decimal(str(quantity or 0))
Uom = Pool().get('product.uom')
factor = None
rate = None
if from_unit.category.id != to_unit.category.id:
factor = 1
rate = 1
return Decimal(str(Uom.compute_qty(
from_unit, float(quantity or 0), to_unit, True, factor, rate)))
def _line_lot_quantity_for_tolerance(self, line):
LotQt = Pool().get('lot.qt')
quantity = Decimal(0)
unit = getattr(line, 'unit', None)
for lot in getattr(line, 'lots', None) or []:
if getattr(lot, 'lot_type', None) == 'physic':
quantity += Decimal(str(
lot.get_current_quantity_converted(unit=unit) or 0))
continue
if getattr(lot, 'lot_type', None) != 'virtual':
continue
for lqt in LotQt.search([('lot_p', '=', lot.id)]):
quantity += self._line_quantity_in_unit(
getattr(lqt, 'lot_quantity', 0),
getattr(lqt, 'lot_unit', None),
unit)
return quantity
def _tolerance_totals(self):
theoretical = Decimal(0)
actual = Decimal(0)
for line in self.lines or []:
if getattr(line, 'type', None) != 'line':
continue
theoretical += Decimal(str(
getattr(line, 'quantity_theorical', None)
or getattr(line, 'quantity', None)
or 0))
actual += self._line_lot_quantity_for_tolerance(line)
return theoretical, actual
def get_tolerance_used(self, name):
theoretical, actual = self._tolerance_totals()
if not theoretical:
return Decimal(0)
return round(
((actual - theoretical) / theoretical) * Decimal(100), 5)
def get_tolerance_min(self, name):
return -Decimal(str(self.tol_min or 0))
def get_tolerance_max(self, name):
return Decimal(str(self.tol_max or 0))
@staticmethod
def _has_matched_physical_lots(purchase):
for line in purchase.lines or []: