fee mode rate sale side
This commit is contained in:
@@ -542,6 +542,25 @@ Owner technique: `a completer`
|
|||||||
- Priorite:
|
- Priorite:
|
||||||
- `importante`
|
- `importante`
|
||||||
|
|
||||||
|
### BR-PT-016 - Les fees `% rate` utilisent la BL Date estimee
|
||||||
|
|
||||||
|
- Intent: aligner le calcul des frais financiers `% rate` entre achat et vente.
|
||||||
|
- Description:
|
||||||
|
- Pour un `fee.fee` en mode `rate`, le calcul ne depend pas du
|
||||||
|
`payment_term`.
|
||||||
|
- La date de fin est toujours issue de l'onglet `Estimated date` de la ligne
|
||||||
|
achat ou vente:
|
||||||
|
- chercher `trigger = bldate`
|
||||||
|
- prendre `estimated_date`
|
||||||
|
- ajouter `fin_int_delta`
|
||||||
|
- Resultat attendu:
|
||||||
|
- purchase et sale appliquent la meme formule:
|
||||||
|
`fee_date -> BL Date + financing delta`
|
||||||
|
- si aucune Estimated Date `bldate` n'est renseignee, aucun montant `% rate`
|
||||||
|
n'est calcule
|
||||||
|
- Priorite:
|
||||||
|
- `importante`
|
||||||
|
|
||||||
## 4) Exemples concrets
|
## 4) Exemples concrets
|
||||||
|
|
||||||
### Exemple E1 - Augmentation simple
|
### Exemple E1 - Augmentation simple
|
||||||
|
|||||||
@@ -372,10 +372,18 @@ class Fee(ModelSQL,ModelView):
|
|||||||
|
|
||||||
return round(factor * self.line.unit_price * self._get_amount_quantity() * sign,2)
|
return round(factor * self.line.unit_price * self._get_amount_quantity() * sign,2)
|
||||||
if self.sale_line:
|
if self.sale_line:
|
||||||
if self.sale_line.sale.payment_term:
|
if self.sale_line.estimated_date:
|
||||||
beg_date = self.fee_date if self.fee_date else Date.today()
|
beg_date = self.fee_date if self.fee_date else Date.today()
|
||||||
est_date = self.sale_line.sale.payment_term.lines[0].get_date(beg_date,self.sale_line)
|
est_lines = [
|
||||||
logger.info("EST_DATE:%s",est_date)
|
dd for dd in self.sale_line.estimated_date
|
||||||
|
if dd.trigger == 'bldate'
|
||||||
|
]
|
||||||
|
est_line = est_lines[0] if est_lines else None
|
||||||
|
if est_line and est_line.estimated_date:
|
||||||
|
est_date = est_line.estimated_date + datetime.timedelta(
|
||||||
|
days=est_line.fin_int_delta or 0
|
||||||
|
)
|
||||||
|
logger.info("EST_DATE:%s", est_date)
|
||||||
if est_date and beg_date:
|
if est_date and beg_date:
|
||||||
factor = InterestCalculator.calculate(
|
factor = InterestCalculator.calculate(
|
||||||
start_date=beg_date,
|
start_date=beg_date,
|
||||||
@@ -385,8 +393,10 @@ class Fee(ModelSQL,ModelView):
|
|||||||
convention='ACT/360',
|
convention='ACT/360',
|
||||||
compounding='simple'
|
compounding='simple'
|
||||||
)
|
)
|
||||||
logger.info("FACTOR:%s",factor)
|
logger.info("FACTOR:%s", factor)
|
||||||
return round(factor * self.sale_line.unit_price * self._get_amount_quantity() * sign,2)
|
return round(
|
||||||
|
factor * self.sale_line.unit_price
|
||||||
|
* self._get_amount_quantity() * sign, 2)
|
||||||
|
|
||||||
elif self.mode == 'perqt':
|
elif self.mode == 'perqt':
|
||||||
if self.shipment_in:
|
if self.shipment_in:
|
||||||
|
|||||||
@@ -273,6 +273,35 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
|||||||
|
|
||||||
self.assertEqual(fee.get_amount(), Decimal('13.33'))
|
self.assertEqual(fee.get_amount(), Decimal('13.33'))
|
||||||
|
|
||||||
|
def test_sale_rate_fee_amount_uses_bl_date_estimate(self):
|
||||||
|
'sale rate fee amount uses BL estimated date plus financing delta'
|
||||||
|
Fee = Pool().get('fee.fee')
|
||||||
|
fee = Fee()
|
||||||
|
fee.mode = 'rate'
|
||||||
|
fee.price = Decimal('12')
|
||||||
|
fee.fee_date = datetime.date(2026, 4, 23)
|
||||||
|
fee.quantity = Decimal('10')
|
||||||
|
fee.unit = Mock()
|
||||||
|
fee.shipment_in = None
|
||||||
|
fee.line = None
|
||||||
|
fee.sale_line = Mock(
|
||||||
|
unit_price=Decimal('100'),
|
||||||
|
lots=[],
|
||||||
|
estimated_date=[
|
||||||
|
Mock(
|
||||||
|
trigger='bldate',
|
||||||
|
estimated_date=datetime.date(2026, 5, 23),
|
||||||
|
fin_int_delta=10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch('trytond.modules.purchase_trade.fee.Pool') as PoolMock:
|
||||||
|
PoolMock.return_value.get.return_value = Mock(
|
||||||
|
today=Mock(return_value=datetime.date(2026, 4, 23)))
|
||||||
|
|
||||||
|
self.assertEqual(fee.get_amount(), Decimal('13.33'))
|
||||||
|
|
||||||
def test_create_pnl_price_from_line_keeps_finished_physical_sale_line(self):
|
def test_create_pnl_price_from_line_keeps_finished_physical_sale_line(self):
|
||||||
'purchase valuation keeps finished sale-side pnl on physical lots'
|
'purchase valuation keeps finished sale-side pnl on physical lots'
|
||||||
Valuation = Pool().get('valuation.valuation')
|
Valuation = Pool().get('valuation.valuation')
|
||||||
|
|||||||
Reference in New Issue
Block a user