mirror of
https://github.com/ForgeFlow/stock-rma.git
synced 2025-01-21 12:57:49 +02:00
Merge pull request #403 from ForgeFlow/14.0-rma_account-anglo_saxon_in_lines
[14.0][FIX] rma_purchase: write-off differences in price between rma line and vendor refund
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import models
|
||||
from odoo.tools.float_utils import float_compare, float_is_zero
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
@@ -40,3 +41,105 @@ class AccountMove(models.Model):
|
||||
)
|
||||
amls.reconcile()
|
||||
return res
|
||||
|
||||
def _stock_account_prepare_anglo_saxon_in_lines_vals(self):
|
||||
lines_vals_list_rma = []
|
||||
rma_refunds = self.env["account.move"]
|
||||
price_unit_prec = self.env["decimal.precision"].precision_get("Product Price")
|
||||
for move in self:
|
||||
if (
|
||||
move.move_type != "in_refund"
|
||||
or not move.company_id.anglo_saxon_accounting
|
||||
):
|
||||
continue
|
||||
move = move.with_company(move.company_id)
|
||||
for line in move.invoice_line_ids.filtered(lambda l: l.rma_line_id):
|
||||
if (
|
||||
line.product_id.type != "product"
|
||||
or line.product_id.valuation != "real_time"
|
||||
):
|
||||
continue
|
||||
# Retrieve accounts needed to generate the price difference.
|
||||
debit_pdiff_account = (
|
||||
line.product_id.property_account_creditor_price_difference
|
||||
or line.product_id.categ_id.property_account_creditor_price_difference_categ
|
||||
)
|
||||
debit_pdiff_account = move.fiscal_position_id.map_account(
|
||||
debit_pdiff_account
|
||||
)
|
||||
if not debit_pdiff_account:
|
||||
continue
|
||||
rma_line = line.rma_line_id
|
||||
valuation_price_unit = rma_line._get_price_unit()
|
||||
price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
||||
price_unit_val_dif = price_unit - valuation_price_unit
|
||||
price_subtotal = line.quantity * price_unit_val_dif
|
||||
if (
|
||||
not move.currency_id.is_zero(price_subtotal)
|
||||
and not float_is_zero(
|
||||
price_unit_val_dif, precision_digits=price_unit_prec
|
||||
)
|
||||
and float_compare(
|
||||
line["price_unit"],
|
||||
line.price_unit,
|
||||
precision_digits=price_unit_prec,
|
||||
)
|
||||
== 0
|
||||
):
|
||||
# Add price difference account line.
|
||||
vals = {
|
||||
"name": line.name[:64],
|
||||
"move_id": move.id,
|
||||
"partner_id": line.partner_id.id
|
||||
or move.commercial_partner_id.id,
|
||||
"currency_id": line.currency_id.id,
|
||||
"product_id": line.product_id.id,
|
||||
"product_uom_id": line.product_uom_id.id,
|
||||
"quantity": line.quantity,
|
||||
"price_unit": price_unit_val_dif,
|
||||
"price_subtotal": line.quantity * price_unit_val_dif,
|
||||
"account_id": debit_pdiff_account.id,
|
||||
"analytic_account_id": line.analytic_account_id.id,
|
||||
"analytic_tag_ids": [(6, 0, line.analytic_tag_ids.ids)],
|
||||
"exclude_from_invoice_tab": True,
|
||||
"is_anglo_saxon_line": True,
|
||||
"rma_line_id": line.rma_line_id.id,
|
||||
}
|
||||
vals.update(
|
||||
line._get_fields_onchange_subtotal(
|
||||
price_subtotal=vals["price_subtotal"]
|
||||
)
|
||||
)
|
||||
lines_vals_list_rma.append(vals)
|
||||
|
||||
# Correct the amount of the current line.
|
||||
vals = {
|
||||
"name": line.name[:64],
|
||||
"move_id": move.id,
|
||||
"partner_id": line.partner_id.id
|
||||
or move.commercial_partner_id.id,
|
||||
"currency_id": line.currency_id.id,
|
||||
"product_id": line.product_id.id,
|
||||
"product_uom_id": line.product_uom_id.id,
|
||||
"quantity": line.quantity,
|
||||
"price_unit": -price_unit_val_dif,
|
||||
"price_subtotal": line.quantity * -price_unit_val_dif,
|
||||
"account_id": line.account_id.id,
|
||||
"analytic_account_id": line.analytic_account_id.id,
|
||||
"analytic_tag_ids": [(6, 0, line.analytic_tag_ids.ids)],
|
||||
"exclude_from_invoice_tab": True,
|
||||
"is_anglo_saxon_line": True,
|
||||
"rma_line_id": line.rma_line_id.id,
|
||||
}
|
||||
vals.update(
|
||||
line._get_fields_onchange_subtotal(
|
||||
price_subtotal=vals["price_subtotal"]
|
||||
)
|
||||
)
|
||||
lines_vals_list_rma.append(vals)
|
||||
rma_refunds |= move
|
||||
lines_vals_list = super(
|
||||
AccountMove, self - rma_refunds
|
||||
)._stock_account_prepare_anglo_saxon_in_lines_vals()
|
||||
lines_vals_list += lines_vals_list_rma
|
||||
return lines_vals_list
|
||||
|
||||
@@ -17,6 +17,10 @@ class TestRmaStockAccountPurchase(TestRmaStockAccount):
|
||||
cls.rma_operation_supplier_refund = cls.env.ref(
|
||||
"rma_account.rma_operation_supplier_refund"
|
||||
)
|
||||
acc_type = cls._create_account_type("expense", "other")
|
||||
cls.account_price_diff = cls._create_account(
|
||||
acc_type, "Refund Price Difference Expense", "rpde", cls.company, False
|
||||
)
|
||||
|
||||
def test_01_cost_from_po_move(self):
|
||||
"""
|
||||
@@ -140,3 +144,77 @@ class TestRmaStockAccountPurchase(TestRmaStockAccount):
|
||||
)
|
||||
self.assertEqual(sum(grni_amls.mapped("balance")), 0.0)
|
||||
self.assertTrue(all(grni_amls.mapped("reconciled")))
|
||||
|
||||
def test_03_return_and_refund_diff_price(self):
|
||||
"""
|
||||
Purchase a product.
|
||||
Then create an RMA to return it and get the refund from the supplier with
|
||||
a different price than the original purchase price
|
||||
"""
|
||||
self.product_fifo_1.categ_id.update(
|
||||
{
|
||||
"property_account_creditor_price_difference_categ": self.account_price_diff
|
||||
}
|
||||
)
|
||||
self.product_fifo_1.standard_price = 1234
|
||||
po = self.po_model.create(
|
||||
{
|
||||
"partner_id": self.partner_id.id,
|
||||
}
|
||||
)
|
||||
pol_1 = self.pol_model.create(
|
||||
{
|
||||
"name": self.product_fifo_1.name,
|
||||
"order_id": po.id,
|
||||
"product_id": self.product_fifo_1.id,
|
||||
"product_qty": 10.0,
|
||||
"product_uom": self.product_fifo_1.uom_id.id,
|
||||
"price_unit": 100.0,
|
||||
"date_planned": Datetime.now(),
|
||||
}
|
||||
)
|
||||
po.button_confirm()
|
||||
self._do_picking(po.picking_ids)
|
||||
self.product_fifo_1.standard_price = 1234 # this should not be taken
|
||||
supplier_view = self.env.ref("rma_purchase.view_rma_line_form")
|
||||
rma_line = Form(
|
||||
self.rma_line.with_context(supplier=1).with_user(self.rma_basic_user),
|
||||
view=supplier_view.id,
|
||||
)
|
||||
rma_line.partner_id = po.partner_id
|
||||
rma_line.purchase_order_line_id = pol_1
|
||||
rma_line.price_unit = 4356
|
||||
rma_line.operation_id = self.rma_operation_supplier_refund
|
||||
rma_line = rma_line.save()
|
||||
rma_line.action_rma_to_approve()
|
||||
self._deliver_rma(rma_line)
|
||||
|
||||
with Form(
|
||||
self.env["account.move"].with_context(default_move_type="in_refund")
|
||||
) as bill_form:
|
||||
bill_form.partner_id = rma_line.partner_id
|
||||
bill_form.invoice_date = Date.today()
|
||||
bill_form.add_rma_line_id = rma_line
|
||||
bill = bill_form.save()
|
||||
bill_form = Form(bill)
|
||||
with bill_form.invoice_line_ids.edit(0) as line_form:
|
||||
line_form.price_unit = 110
|
||||
bill = bill_form.save()
|
||||
bill.action_post()
|
||||
self.assertEquals(len(bill.invoice_line_ids), 1)
|
||||
self.assertEquals(bill.invoice_line_ids.rma_line_id, rma_line)
|
||||
grni_amls = self.env["account.move.line"].search(
|
||||
[
|
||||
("account_id", "=", self.account_grni.id),
|
||||
("rma_line_id", "=", rma_line.id),
|
||||
]
|
||||
)
|
||||
self.assertEqual(sum(grni_amls.mapped("balance")), 0.0)
|
||||
self.assertTrue(all(grni_amls.mapped("reconciled")))
|
||||
price_diff_amls = self.env["account.move.line"].search(
|
||||
[
|
||||
("account_id", "=", self.account_price_diff.id),
|
||||
("rma_line_id", "=", rma_line.id),
|
||||
]
|
||||
)
|
||||
self.assertEqual(sum(price_diff_amls.mapped("balance")), -100)
|
||||
|
||||
Reference in New Issue
Block a user