This commit is contained in:
2026-03-23 10:10:53 +01:00
parent afdbd05375
commit b5d771341d
2 changed files with 28 additions and 12 deletions

View File

@@ -812,26 +812,41 @@ class PenaltyRuleTier(ModelSQL, ModelView):
threshold_unit = fields.Many2One('assay.unit', "Unit")
deduction_per_unit = fields.Numeric("Deduction / unit")
penalty_value = fields.Numeric("Penalty Value (USD/DMT)")
mode = fields.Selection([
('excess', 'Excess above threshold'),
('full', 'Full grade in tier'),
('min_or_both', 'Min(grade, cap) — full tier amount'),
], "Mode")
@classmethod
def default_mode(cls):
return 'excess'
def compute_tier_penalty(self, grade):
"""
Retourne la pénalité USD pour ce palier uniquement.
grade : Decimal teneur brute de l'élément
dry_weight_dmt: Decimal poids sec en DMT
"""
grade = Decimal(str(grade))
# Grade en dessous du seuil bas → ce palier ne s'applique pas
if grade <= self.threshold_from:
return Decimal(0)
# Excès au-dessus du seuil bas, plafonné au seuil haut si existant
excess_top = grade if self.threshold_to is None else min(grade, self.threshold_to)
excess = excess_top - self.threshold_from
if self.mode == 'excess':
# Ton comportement actuel : on paye seulement l'excès au-dessus du seuil bas
# Ex Codelco : As=0,7% → palier 0,2-0,5% donne 0,3% d'excès
excess_top = grade if self.threshold_to is None else min(grade, self.threshold_to)
taxable = excess_top - self.threshold_from
# USD/DMT × DMT
return (excess * self.penalty_value).quantize(Decimal('0.01'))
elif self.mode == 'full':
# Pénalité sur toute la teneur dans ce palier dès déclenchement
# Ex : As=0,7% → palier 0,5-1,0% donne 0,7% entier (pas 0,2%)
taxable = grade if self.threshold_to is None else min(grade, self.threshold_to)
elif self.mode == 'min_or_both':
# Pénalité sur min(grade, plafond) — utile quand le contrat dit
# "si As dépasse X%, pénalité sur la tranche entière jusqu'à Y%"
# Ex vente fichier : palier 0,3-0,9%, As=0,6% → taxable = min(0,6%, 0,9%) = 0,6%
cap = self.threshold_to if self.threshold_to is not None else grade
taxable = min(grade, cap)
return (taxable * self.penalty_value).quantize(Decimal('0.01'))
class PenaltyRule(ModelSQL, ModelView):
"Penalty Rule"

View File

@@ -1,4 +1,5 @@
<tree editable="1">
<field name="mode"/>
<field name="threshold_from"/>
<field name="threshold_to"/>
<field name="threshold_unit"/>