odoo/odoo#124844
Created by fw-bot
Statuses:
- legal/cla: Contributor License Agreement check
- ci/runbot: Odoo Test Suite
- ci/upgrade_enterprise: Test upgrades for enterprise master
- ci/template: Contact runbot team for help in case of failure.
- ci/style: Optional style check. Ignore it only if strictly necessary.
- ci/security: Required security check. Can only be ignored by security team.
- label
- odoo-dev:saas-16.1-16.0-OPW-3217215-stock_account_reverse_impact_pdiff-awt-CkZY-fw
- head
- 9cc4c2b341c38131c09e6efc635b4a4fa440817d
- merged
- 3 years ago by Bugfix, Adrien Widart (awt)
| odoo/odoo | |
|---|---|
| 16.0 | #122231 |
| saas-16.1 | #124844 |
| saas-16.2 | #124860 |
| saas-16.3 | #125016 |
| 17.0 | |
| 18.0 | |
| saas-18.2 | |
| saas-18.3 | |
| saas-18.4 | |
| 19.0 | |
| saas-19.1 | |
| saas-19.2 | |
| master | #126536 |
[FW][FIX] purchase_stock,stock_account: refund price difference
If a bill has a price difference with the PO, and if the user
refunds it, it will create some errors in the inventory valuation and
the accounting entries
To reproduce the issue:
(Need account_accountant)
1. Create a product category PC
- Costing method: FIFO
- Inventory valuation: Automated
2. Create a product P
- Type: Storable
- Category: PC
3. Confirm a PO with 1 x P at $10
4. Receive P
5. Bill it at $15
- It should create a price diff SVL, see inventory valuation
6. Refund
Errors: The inventory valuation is not impacted, it is still valued
at $15. Because of the refund, it should be $10 (i.e., the price
difference should be cancelled). Then, suppose the user creates a
new bill at $20, it won't do anything (the stock valuation will not
be impacted).
Long story short: the price difference feature, which is supposed to
impact inventory valuation/account entries, does not work if there
is a (partial/full) refund in the flow.
Now, let's think about a more complicated use case:
- Receive 12 products in several times
- Bill in several times (with different quantities than the receipts)
It could give something like (where x are products):
SVL01 SVL02 SVL03
/---------------\/---------\/------------------\
x x x x x x x x x x x x
\-----------/\-----/\--/\---------------/\------/
B01 B02 B03 B04 B05
('B' means Bill)
We observe that
- a bill could impact several layers
- a layers could be impacted by several bills
And here is the issue: currently in the code, we don't have a relevant
link between layers, account move lines and the quantity that links
both. The only thing we have is a link between the price difference SVL
and the account move line that has generated that SVL (see field
account_move_line_id on stock.valuation.layer). But this is
clearly not enough and is really problematic: if I refund BILL04, how
should it impact SVL02 ? Then, what if I return a part of the third
delivery before refunding BILL04 ? What if I deliver a part of the
received products before refunding several bills ? What if I refund
B02, B05, then I bill 4 products ?
-> You get the idea: we definitly need a clear link between account
move lines and stock valuation layers and that link has to give a
quantity.
Moreover, it is difficult to create an order between bills. We have
their name, their ID, but the posted time is actually a date. So, if
we mix reset & repost, a draft bill and a draft partial refund, and
so on, and if this mix happens the same day, it is very difficult to
define a clear order. But, considering the above schema, we see that
the order does matter (switch BILL02 and BILL03, the remaining
values of SVL01 and SVL02 will not be the same)
-> So, we also need a way to order the links between account move lines
and stock valuation layers.
Now, about the solution.
First, a disclaimer: We are in stable, we are limited by the stable
policy, and we can't let the above use cases unresolved. So, we took
some decisions to fix them and to repesct all the constraints we had.
This is clearly a (big) patch, it should be considered as such and
will be replaced by a cleaner/better solution on master as soon as
possible.
About the link between SVL and AML, we had the possibility to create
a new model in a new module. But this would have decreased the
impact of the fix deployment, would have created some
complications for support (different behaviours depending on whether
the module is installed or not) and would have make testing more
complicated (again, different behaviours depending on whether the
module is installed or not).
This is the reason why we decided to "replay the receipts and the
bills". That way, we know which layer is impacted by which invoices,
and vice versa. And, to set the order between all of them:
- For the layers, we use their create_date
- For the bills, we use a hack: each time an account move is posted,
because its state is tracked, a tracking value is posted on the
chatter, and this tracking value has a create_date (remind the
constraints explained above and the disclaimer...)
Forward-Port-Of: #122231