Commit Graph
313 Commits
Author SHA1 Message Date
Adrien Widart (awt) c321f825f9 [FIX] purchase_stock,stock_account: reconcile lines
In some cases, when billing a received quantity that is already
delivered, the account move lines of Stock Interim (Received) will
not be reconciled

To reproduce the issue:
(Need account_accountant, sale_management)
1. Create a product category PC:
   - Costing Method: FIFO
   - Inventory Valuation: Automated
2. Create a product P
   - Type: Storable
   - Category: PC
3. Create and confirm a PO with
   - 5 x P at $50
4. Process the receipt R
5. Create and confirm a SO with
   - 5 X P
6. Process the delivery
7. Create and post partial bill B01 related to PO:
   - 1 x P @ $60
8. Accounting > Accounting > Journal Items
   - Group By: Account
   - Note: There are three lines in Stock Interim (Receipt):
     - [AML01] Debit: 0, Credit: 250 (receipt R)
     - [AML02] Debit: 60, Credit: 0 (bill B01)
     - [AML03] Debit: 0, Credit: 10 (price diff from B01 because
       quantity already delivered)
     There is a partial reconcile between AML01 and AML02, AML03 is
       not part of this partial reconciliation
9. Create and post partial bill B02 related to PO:
   - 4 x P @ $60
10. Accounting > Accounting > Journal Items
    - Group By: Account

Error: The lines of account 'Stock Interim (Received)' are not
reconciled while it should

When confirming B01, we try to reconcile AML01, AML02, AML03. In the
reconciliation process, we first sort the AMLs and try to create a
partial reconciliation:
https://github.com/odoo/odoo/blob/01cb7e960f912c4758d30c04653b599937785799/addons/account/models/account_move_line.py#L2282-L2293
Because of the sorting, here is the order of the AMLs:
- [AML01] Debit: 0, Credit: 250
- [AML03] Debit: 0, Credit: 10
- [AML02] Debit: 60, Credit: 0

In `_create_reconciliation_partials`, we consume the AMLs in that
specific order. So, it first uses one credit line and a debit one:
https://github.com/odoo/odoo/blob/01cb7e960f912c4758d30c04653b599937785799/addons/account/models/account_move_line.py#L1863-L1872
(i.e. AML01 and AML02) and creates a partial reconciliation for
theses AMLs. It gives a temporary credit line of 190, but there is
no more debit lines, so the partial reconciliation is stopped (this
explains the note at step 8)

Later on, while posting B02, we try again to reconcile the lines of
Stock Interim (Received)
https://github.com/odoo/odoo/blob/493020b9317a439c0a61a34f37cc92b6779ef633/addons/stock_account/models/account_move.py#L249
At that point, we have three AMLs:
- [AML01] Debit: 0, Credit: 250 (same as above)
- [AML04] Debit: 0, Credit: 40 (price diff from B02)
- [AML05] Debit: 240, Credit: 0 (B02)

Back in the reconciliation progress, we try to get all involved AMLs:
https://github.com/odoo/odoo/blob/01cb7e960f912c4758d30c04653b599937785799/addons/account/models/account_move_line.py#L2284-L2287
It will be used later for the full reconciliation. To get the
involved ones, we recursively get the AMLs implied in the partial
reconciliation of AML01, AML04, AML05:
https://github.com/odoo/odoo/blob/01cb7e960f912c4758d30c04653b599937785799/addons/account/models/account_move_line.py#L2481-L2489
Therefore, because of the first partial reconciliation explained above,
we will find AML02 but not AML03. This is the reason why the full
reconciliation will not happen.

Working on the assumption that the note of step 8 is not a bug (i.e.,
AML03 is not expected to be part of the first partial reconciliation),
we need to provide as much AML as we can when calling the
reconciliation process.

OPW-3040171

closes odoo/odoo#107908

X-original-commit: 3050e23f94c865f9938863f191076f761b80fedb
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-12-14 10:35:28 +01:00
Adrien Widart (awt) 48f6cb4597 [FIX] purchase_stock,stock_account: balance Stock Interim
(Received)

In auto-avco, if a user delivers a products before billing its
receipt, the account Stock Interim (Received) will be unbalanced

To reproduce the issue:
(Need account_accountant, sale_management)
1. Create a product category PC:
   - Costing Method: FIFO
   - Inventory Valuation: Automated
2. Create a product P
   - Type: Storable
   - Category: PC
3. Create and confirm a PO with
   - 1 x P at $50
4. Process the receipt R
5. Create and confirm a SO with
   - 1 X P
6. Process the delivery
7. Create the bill B related to PO
8. Set the bill line unit price to $60
9. Confirm
10. Accounting > Accounting > Journal Items
    - Group By: Account

Error: The account 'Stock Interim (Received)' is not balanced
(Debit: 60, Credit: 50)

The account entries are:
- Credit 50 related to R
- Debit 60 related to B

There isn't any line for the price difference. Since [1], we don't
generate any price difference layer for the already-delivered
quantities. Before this commit, a layer was generated and posted on
account-side:
https://github.com/odoo/odoo/blob/a5b985e8449a1e858c3fb9a0a90a6d203e16f739/addons/stock_account/models/account_move.py#L68-L69
But, as explained in [1], we should generate the price diff layers
only for the remaining quantities, otherwise it would lead to some
errors on both stock and account side. That being said, we still
have something to do with the price diff related to the out
quantities. This is what this commit is about. In such case, we
generate some journal entries:
- we credit the account 'Stock Interim (Received)' with the price
  diff (the account is then balanced)
- we debit the account 'Expenses'

To do so, we:
- Bring back the method
  `_stock_account_prepare_anglo_saxon_in_lines_vals` from [2]
- Fix that method because both fields `analytic_account_id` and
`analytic_tag_ids` do not exist anymore [3]
- Update it so it behaves as described above

Note 01: in the steps, we have removed the case 'Receive, Return and
Receive again'. Such a flow breaks the whole accounting and would
not work with some other features. Therefore, we consider such a
flow as invalid (the user could rather create a new purchase order
to receive the quantities again)

Note 02: This behaviour is not supposed to work with the kits. This
commit prevents the lines to be posted in such situation. Suppose
the flow is in a "standard" order (PO, Bill, SO), we also do not
create layers for the price difference:

[1] 18912b05239e6fc5dab26ec4c930f9080882d127
[2] 35d6c58f86
[3] odoo/enterprise@a1eaf200d0

OPW-3040171
OPW-3071238

X-original-commit: 84733fb89faffe2480def97f076633056e16572f
Part-of: odoo/odoo#107908
2022-12-14 10:35:28 +01:00
Florent de Labarre ab1e076224 [FIX] purchase, stock : datetime is not correctly converted in date
With this commit datetime of stock move are correctly converted with the current timezone.

closes odoo/odoo#106886

X-original-commit: 242da76b2763d5add36da6e23d4b1f7e640c72aa
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
2022-11-30 19:05:53 +01:00
Jérôme Hellinckx 86ad480b72 [FIX] purchase_stock: avoid PO exception propagation to DONE receipts on less received quants
Before this commit:
1. Create PO with quantity 10, confirm (creates receipt-1)
2. Receive 2 quantities on first receipt (receipt-1), backorder (receipt-1 is 'done', creates receipt-2)
3. Receive 3 quantities on second receipt (receipt-2), backorder (receipt-2 is 'done', creates receipt-3)
4. Change quantity to 5 in PO
5. An exception is created on all receipts (1, 2 and 3)

In the scenario above, receipt-1 and receipt-2 are partial receipts that are set to 'done'.
It is not necessary to create an exception in these receipts when the quantity is changed to less than originally expected in the PO.
Since the system checks that the new quantity has to be equal or greater than the received quantities, the already received quantities cannot be impacted.

After this commit:
The exception is only propagated to the receipts that are not done.
e.g. in the example above, an exception appears only in receipt-3.

task-2648209

resolves #76297

closes odoo/odoo#106633

X-original-commit: d6fad232c3dd4a4f7cd54bd255b75314d54ed065
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-11-28 14:51:42 +01:00
William Henrotin 9ee9be3f4d [PERF] mrp,stock,purchase: sql improvement
First correction: replace call to `read_group` to `_read_group` in order
to avoid useless joints on table product_template and ir_translation
when the grouping key is a Many2One.

Second correction: add an index on workorder's `state` field. The
get_conflicted_workorder_ids() method search for ready workorders that
are in conflict relate to their planning. The state value is searched to
many times to not index it

closes odoo/odoo#106582

Task: 2852423
X-original-commit: b5019eec76845316e554f2dd11a6d8bbf6fea433
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-11-25 18:56:02 +01:00
Adrien Widart (awt) a2f4a53148 [FIX] mrp_subcontracting_dropshipping,purchase_stock: return to supplier
When returning a dropshipped and subcontracted product to the supplier
location, the received quantity of the PO line will be incorrect

To reproduce the issue:
1. Create two storable products P_compo, P_Finished
2. Create a BoM:
    - Product: P_finished
    - Type: Subcontracting
    - Subcontractors: a subcontractor S
    - Components: 1 x P_compo
3. Create and confirm a PO:
    - Vendor: S
    - Deliver To: Dropship
    - Drop Ship Address: a partner P
    - Products: 1 x P_finished
4. Validate the receipt
5. Create a return with 1 x P_finished:
    - Update SO/PO quantities: True
    - Return Location: Partner Locations/Vendors
6. Validate the return
7. Go back to the PO

Error: The qty received is 2, it should be 0

There is currently no code to handle the return of a dropshipped product

OPW-3030895

closes odoo/odoo#105863

X-original-commit: 0a03678889d46dfc39922c0df965c06457f28d79
Signed-off-by: Adrien Widart <awt@odoo.com>
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-11-16 13:23:41 +01:00
Touati Djamel (otd) 4cc2b3bcca [FIX] sale_stock, purchase_stock: use product name as stock.move name
Steps to reproduce the bug:
- Create a Kit product "Kit 1":
    - Add a BOM with a component “C1”
    - Add a sales description
- Create another kit product without a sales description "Kit 2":
    - Add a BOM with a component "C2"
- Make sure you have a qty of “C1” and "C2"
- Create a SO:
    - Add "Kit 1" and "Kit 2"
    - Add any other storable product
    - Confirm the SO
- Go to the delivery → validate it
- Print the delivery slip

Problem:
The report doesn’t contain the kit product.

Because in the report, the `stock.move.line` are filtered by checking
the name of their move if it has the same name as the product in
the bill of material, but like the `stock.move` has the name
('description') of the `sale.order.line` instead of the product name,
the lines are filtered and not displayed:
https://github.com/odoo/odoo/blob/14.0/addons/mrp/report/report_deliveryslip.xml#L9

The behavior is the same for purchase orders

opw-2960467

closes odoo/odoo#105158

X-original-commit: be25cea0d882bb03a4873821fdb788a0890ba49a
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
2022-11-07 14:52:56 +01:00
svs-odoo 0ebbc8f1d5 [FIX] purchase(_stock): don't recompute price unit
Before this commit, when the quantity of a PO line is changed, its unit
price is recomputed, which means it will be set to 0 if there is no
compatible vendor price for the selected partner/product.
It can be annoying because if the price unit was set manually by the
user, this info is lost.
To avoid that, we don't recompute the unit price if the PO line matches
the following conditions:
- The PO line has already a price unit;
- There is actually no vendor price list for the partner (in such case,
  we prefer to avoid to stick to a price who doesn't match that list);
- The UoM wasn't changed, because if the UoM was changed, the price
  should obviously recomputed (the price unit for 1 unit is not the same
  than for 1 dozen).

How to reproduce:
- Install Stock and Purchase modules;
- In purchase settings, enable "Purchase Agreements";
- Create a product and in its vendor price list (in "Purchase" tab), add
  a price for Partner A (e.g. 10$);
- Create a PO for Partner B, add a PO line for the created product and
  set the `price_unit` higher than the created vendor price (e.g. 15$);
- Confirm the order and go in the "Alternatives" tab;
- Click on "Create Alternative" and select Partner A as the vendor;
- Click on "Compare Product Lines" and choose the line for Partner A;
- Go back in the first created PO (with Partner B as vendor)
  -> the PO line's quantity is to 0, which is good, but its unit price
     is also set to 0 which is annoying.

Additionnaly, in `_get_stock_move_price_unit`, `float_round` the value
just before it was returned because previously, the rouding was done
before the multiplication by the UoM's factor which can cause some
rounding issue if the rouding is not done after that.

closes odoo/odoo#104206

X-original-commit: f5a24b10cb3a4cf32c6c185df65f3099c8da3ff1
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
2022-10-27 10:37:40 +02:00
David (dafr) ddfae4b760 [FIX] purchase_stock: get ID of buy_route only if it exists
# How to reproduce:
- Delete external ID "purchase_stock.route_warehouse0_buy"
- Try to create a Product

"purchase_stock.route_warehouse0_buy" was meant to be optional. We can only get the id after checking that it exist.

OPW-2972494

closes odoo/odoo#102872

X-original-commit: 1b7b4cdbee07c325753c1b9362414e8309ef8718
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: DavidFesquet <dafr@odoo.com>
2022-10-10 16:10:58 +02:00
clesgow 93ed42f12e [FIX] purchase_stock: confirm push pickings
When creating a Purchase Order with multi-step reception, the pickings
created by the push rules won't get confirmed as they should be (like in
the sales multi-step flow).

This creates issues further down with auto-batch as created pickings
don't get auto-batched even if the picking type is set to do it.

Task-2971346

X-original-commit: dc517bbe7ffbae8a8774f705c9431dce45c461ba
Part-of: odoo/odoo#102382
2022-10-06 18:00:48 +02:00
Adrien Widart b62e6d45d4 [FIX] purchase_stock, mrp_subcontracting_dropshipping: dropship to subcontract
A user can not buy a subcontracted product and directly deliver it
(dropship) to another subcontractor. Moreover, in such situation, the
received quantity is not correctly computed.

To reproduce the issue:
(Enable debug mode)
1. In Settings, enable "Storage Locations"
2. Create three products:
    - P1:
        - Storable
        - With a vendor V1
    - P2:
        - Storable
        - With a vendor V2
    - P3:
        - Consumable
3. Edit V1:
    - Customer Location: Physical Locations/Subcontracting Location
4. Create two BoMs:
    - Product: P1
        - Type: Subcontracting
        - Subcontractors: V1
        - Components: 1 x P2
    - Product: P2
        - Type: Subcontracting
        - Subcontractors: V2
        - Components: 1 x P3
5. Create a PO:
    - Vendor: V2
    - Deliver To: Dropship
    - Drop Ship Address: V1
    - Products: 1 x P2
6. Confirm the PO

Error: a Validation Error is raised at `mrp.production` creation because
of a missing field (`picking_type_id`).

In some cases, when getting the values to create the MO, the basic
`_prepare_subcontract_mo_vals` does not return any `picking_type_id`.
That's the reason why an override has been added in
`/mrp_subcontracting_dropshipping` (see [1] for more details). Thanks to
this override, if the usage of the destination location is `customer`,
we know that we are in a "dropship" situation and we manually define the
`picking_type_id`:
https://github.com/odoo/odoo/blob/d73e70f22e47e81e59aff0c9f578aff260447256/addons/mrp_subcontracting_dropshipping/models/stock_picking.py#L15-L17
However, in the above case, the subcontracted stock move starts from a
subcontracted location and also goes to a subcontracted location
(because of step 3). As a result, the if-condition is not respected and
the `picking_type_id` is not defined.

Once this issue is solved, there is a second one: suppose the PO
confirmed. The user validates the transfer. New error: the received
quantity on the PO is not updated. This is because of an incorrect
condition in `/purchase_stock._compute_qty_received`:
https://github.com/odoo/odoo/blob/d0537e32e5aa4b0fe2ad674ab3ec7c42ae1a12f9/addons/purchase_stock/models/purchase.py#L306-L315
Added by [2] and modified by [3], this condition checks that:
- the destination location usage is `internal` (correct, this is a
subcontracting location)
- the source location usage is not `supplier` (correct, this is a
subcontracting location, so it is `internal`)
- the destination location is not part of the warehouse children (here
is the issue: the SM does not have any warehouse, so it gives a false
positive)

So, because of the incorrect third condition, the condition is
respected. And because `to_refund` is `False` (which is correct), we
don't do anything. That's the reason why the received quantity is not
updated.

[1] d73e70f22e47e81e59aff0c9f578aff260447256
[2] e6a1e240f1
[3] fd22fe221026e353aac7414348b029ae7e290b2f

OPW-2922546

closes odoo/odoo#102224

X-original-commit: a51b4158b964a11fa371a9eb8c877c9ec395f412
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-10-05 14:26:14 +02:00
Arnold Moyaux 9f046d538f [IMP] purchase_stock, stock_account: handle invoice before receipt
In some buisness case when the invoice is done before the receipt, the
`stock.valuation.layer` price unit will be taken on the invoice rather
than the `purchase.order.line`

Part-of: odoo/odoo#99411
2022-09-12 13:49:17 +02:00
Arnold Moyaux ccc1fa5d37 [IMP] purchase_mrp: cost share for kit
Be able to define a cost share on kit's components. The purpose, define
a cost repartition closer to the reality.

If the cost share is not define, it will split by the number of lines.

Part-of: odoo/odoo#99411
2022-09-12 13:49:16 +02:00
Arnold Moyaux 35d6c58f86 [REF] purchase_stock, stock_account: remove price difference account
Invoice a different amount than on the purchase order will not
use the price difference account anymore. Instead it will create
a layer with the difference. It means the stock valuation will be
base on real quantity invoiced rather than the purchase order.

Since the price different account does not exists:
- Invoice correction is only done on `account.move.line` linked to a
  `purchase.order.line`. It means that additional lines won't be
 corrected and will debit the stock_input instead (that should be empty
 manually)

Part-of: odoo/odoo#99411
2022-09-12 13:49:16 +02:00
svs-odoo acc1c48921 [MOV] purchase_stock: create stock_move own file
Separates the inheritance of the `stock.move` model in `purchase_stock`
in its own file.

Part-of: odoo/odoo#99411
2022-09-12 13:49:15 +02:00
Ahmed Khalaf (ahkh) 0ff3ab2f21 [IMP] purchase_stock: remove onchange order pick type
This commit removes onchange on picktype in PO replacing it with compute

Part-of: odoo/odoo#95770
2022-09-09 00:02:17 +02:00
clesgow ddfbfddf3c [FIX] purchase_stock: Fix receipt auto-batch
When using the auto-batch feature for receipt, when creating a purchase,
it wouldn't batch pickings that matched the group-by conditions.

The issue is that the _create_picking() called when validating a
Purchase Order creates the picking, then creates its moves and then
validates them. Doing it this way avoids the trigger for the auto-batch
feature located in picking's action_confirm().

By calling action_confirm() on the created picking, we force the trigger
of the auto-batch, while not confirming the moves a second time since
their state isn't 'draft' anymore.

opw-2961618

closes odoo/odoo#99466

X-original-commit: 7d091ba995d13fa8f692827b33aad0982c2a65fa
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
2022-09-02 15:28:05 +02:00
Rémy Voet (ryv) 318888fd83 [IMP] *: add missing indexes
By observing the slowest queries in our servers, we find some indexes
to add (and verify the pertinence of each) :
- Add a index on `sale_id` of `stock_picking` because, it has a one2many inverse highly used.
- Add a index on `product_id` of `purchase_order_line` because, it has a one2many inverse in purchase_stock and there are some search with it (in `_compute_purchased_product_qty`).
- Add a index on `product_id` of `sale_order_line` to improve the `sale.report` view and it is also called by `_compute_sales_count`.
- Add a index `btree_not_null` on `created_purchase_line_id` of `stock.move` because its one2many inverse `move_dest_ids` is highly used.
- `key` on `ir_ui_view`: Backport of https://github.com/odoo/odoo/pull/97478

closes odoo/odoo#99130

X-original-commit: da55c8d88b846d9d1841712b6bd96799e2768a5b
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Rémy Voet <ryv@odoo.com>
2022-08-30 02:51:05 +02:00
clementmbr 1cce589a65 [FIX] purchase_stock: avoid updating kit components price_unit
closes odoo/odoo#97656

X-original-commit: d491d2054ecb8852b0921a7b863f108a0b62155e
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-08-08 23:45:51 +02:00
william-andre d8d47f9ff8 [REF] accounting v16. Yeeeeaah
TLDR:
* invoices are implemented using computed methods instead of onchange
* the synchronization only happens when switching tabs in the Form view
  to improve perfs.

_______________________________________________________________________

The whole engine of the synchronization of Invoices to the Journal
Entries has been refactored
* by using computed fields instead of onchange functions
* by synchronizing only from invoice to journal entry in `create` and
  `write`
* by saving when switching tabs on the Invoice form, to synchronize
  before showing the values

This comes with numerous advantages:
* no need to call the onchange methods manually
* no need to use the Form emulator to build invoices (i.e. EDI, OCR,
  intercompany, ...)
* the performance for invoices with many lines improves drastically, going
  from 2 minutes to 4 seconds to create an invoice with 500 lines
* the model is more declarative, we can now see how the values are computed
  instead of having the values being copied from various places.
* remove the hack in `onchange` that disabled the recursivity of it,
  which was unexpected and needed to be managed manually in all the
  onchange methods

This means that:
* Some fields need to be exclusively computed on journal entries values
  or invoice values, more specifically the Tax Summary widget.
  It is now
    - computed from entry lines, when opening the view
    - computed from invoice lines when changing those, because the tax lines
      will need to be recomputed anyways, erasing previously set values
    - set with an inverse function when saving; after the sync has been done
* Some possible operations previously possible have been dropped.
  (i.e. look at the removed test test_in_invoice_line_onchange_accounting_fields_1)
  This is because such a behavior was undefined (how is changing the balance going
  to affect the unit price? How is the amount currency going to affect it?)

_______________________________________________________________________

Implementation Details
----------------------

The "dynamic lines", meaning the payment terms and the tax lines are now
only created in the `create` and `write` functions.
In order to reduce code duplication, it has been implemented using
context managers used in both `account.move` and `account.move.line`
These context managers help comparing the values before/after, acting
like a local `onchange`, but getting benefit from the dirty flags from
the `compute` dependences.
This is relying on computed fields on the move (`needed_terms`) and on
the lines (`compute_all_tax`) which contain the values needed for the
related move.
Depending on the needed values and the existing values (`term_key` and
`tax_key`, respectively) the context manager will determine what needs
to be created/updated/deleted.

Some related changes are to produce a `dict` instead of a `str` for the
`tax_totals` (previously `tax_totals_json`) fields, by simplicity to
reduce the complexity of IO, and simplicity of debugging, because the
logic of the field needed to change (cannot be computed at the same time
anymore since it needed the lines to be synced)

By simplicity, and also because it makes more sense, some boolean fields
have been merged into `display_type`:
* `is_rounding_line`
* `exclude_from_invoice_tab`
* `is_anglo_saxon_line`

The `price_unit`, `quantity` and other "invoice fields" are now not set
anymore on lines that are not product lines since it didn't make any
sense to have it.

Performances
------------

You have to keep in mind that a simple `create` didn't compute a lot of
fields, for instance not taxes were set, no payment terms,...
Now it does.

```python
import random
from timeit import timeit
from odoo import Command
domain = [('company_id', 'in', (False, self.env.company.id))]
products = self.env['product.product'].search(domain).ids
partners = self.env['res.partner'].search(domain).ids
taxes = self.env['account.tax'].search(domain).ids
def create(nmove, nline):
    self.env['account.move'].create([
        {
            'move_type': 'out_invoice',
            'partner_id': random.choice(partners),
            'invoice_line_ids': [
                Command.create({
                    'name': f'line{i}',
                    'product_id': random.choice(products),
                    'tax_ids': [Command.set([random.choice(taxes)])],
                })
                for i in range(nline)
            ]
        }
        for j in range(nmove)
    ])
                                                             # After  | Before
print(timeit("create(1, 1)", globals=globals(), number=1))   # 0.11   | 0.09
print(timeit("create(100, 1)", globals=globals(), number=1)) # 2.76   | 2.50
print(timeit("create(500, 1)", globals=globals(), number=1)) # 14.56  | 12.34
print(timeit("create(1, 100)", globals=globals(), number=1)) # 1.03   | 5.52
print(timeit("create(1, 500)", globals=globals(), number=1)) # 3.99   | 125.02
print(timeit("create(50, 50)", globals=globals(), number=1)) # 19.44  | 79.55
```

Another metric that can be used is running the test suite with
`--test-tags=/account` (only `account` installed)
* before: 404s, 267127 queries (366 tests)
* after: 318s, 232125 queries (362 tests)

Why this commit title?
----------------------

Someone told me that this was the perfect way of naming your commits.
c04065abd8

task-2711317

closes odoo/odoo#96134

Related: odoo/upgrade#3715
Related: odoo/enterprise#29758
Signed-off-by: Laurent Smet <las@odoo.com>
2022-08-03 13:44:49 +02:00
Fabien Pinckaers 3363e55cac [IMP] cleanup of help messages in all modules
This commit aims at removing unuseful help message to:
1/ reduce translators work, to focus on more useful translations
2/ not sending unuseful information in load_views
3/ reduce help message to useful messages, so that we can mark
   fields having a tooltip in the future UI.
4/ some cleanup of existing messages too

The main use cases:
- REMOVED: help redundant with the field name, providing no extra info
- MOVED TO COMMENT: technical help messages, that should not be in UX

closes odoo/odoo#97279

Signed-off-by: Fabien Pinckaers <fp@odoo.com>
2022-08-02 00:26:53 +02:00
PNO 33ed562cab [FIX] mrp: Wrong replenishment order notification
On the commit 69dcdd4, the order='create_date desc'
 was removed and the way of getting the MO for the notification changed. Now, the context is used, it should be written_after instead of written_date.
(The MO created is correct, only the notification is wrong)

OPW-2877457

closes odoo/odoo#96856

X-original-commit: b80287b265a4c01babedcbb58459c35d36a48066
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-07-28 05:04:26 +02:00
Hugo Adan 3e0230ead3 [REF] purchase_stock: Split _get_quantity_in_progress method in order to make it more inheritable
closes odoo/odoo#96555

X-original-commit: cb9314e902fc899c5ab42b6fd4d8c1ed811c24e7
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-07-22 17:38:52 +02:00
Miquel Raïch a33df16130 [FIX] purchase_stock: propagate PO line sequence to stock moves
The default order of the picking moves generated from a purchase order should be the same order as the purchase order lines.

Steps to reproduce:
- Create a purchase order with several purchase lines.
- Change the order of the purchase lines.
- Confirm the purchase order.
  => The moves of the picking don't maintain same order as set before.

closes odoo/odoo#95582

X-original-commit: c18b2ce767dd5a5b4dbe766b849b56243dffb723
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-07-08 14:34:10 +02:00
svs-odoo d62d7e65fe [FIX] purchase_stock: removes filtered
In the `_stock_account_prepare_anglo_saxon_in_lines_vals` method, we
loop the moves' invoice lines but we called `filtered` on it to remove
ineligible lines.
That said, we have a conditional `continue` at the beginning of the loop
precisely for the same reason, which is redundant.

As it's better to filter out inside a loop instead of call `filtered`
(one loop instead of two), this commit removes the call to `filtered`.

closes odoo/odoo#94456

X-original-commit: a0a90fb20410d663d4615e7a055fce18c868116b
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
2022-06-24 10:29:41 +02:00
Andrea Grazioso (agr-odoo) 75245f4765 [FIX] purchase_stock: wrong amount in price difference account
1. Activate anglo saxon accounting
2. Create product with automated inventory valuation and standard pricing
3. Set decimal accuracy to 6
4. Set product cost price to 0,01719
5. Create PO for 30.000 items -> price = 0,01782 -> total = 534,6
6. Receive goods -> stock journal entry = 515,7 (based on the cost, ok)
7. Create vendor bill

Price difference is incorrect if you have a tax rate in the vendor bill
`price_unit_val_dif` will be rounded to 0.02
Multiplied by a great quantity the result will be wrong (84.30)
Without using the tax rate the price difference amount is the expected one

This commit partially revert 643d91ef5ebfb29fde142294ced82c470d42c136
to improve the original fix.

opw-2849074

closes odoo/odoo#94346

X-original-commit: 315a18f12f9d67284bbd8b027ca652db17aae9d2
Signed-off-by: Laurent Smet <las@odoo.com>
Signed-off-by: Grazioso Andrea (agr) <agr@odoo.com>
2022-06-23 11:15:57 +02:00
Piero (pca) b6c12771d9 [FIX] purchase_stock: restrict recomputation of qty_received_method to unconfirmed POs
This commit adds a search restriction on _compute_qty_received_method which will prevent the received method field from recomputing on orders that have already been finished.

This method is only called on the installation of this module and is used to update order lines of consumable products to use the standard computation of stock moves. In cases where purchase orders were completed ahead of this module's installation, this method effectively undoes all received quantities and resets them to zero. In orders that were already confirmed and billed, this displays the order lines with zero received quantities and no way to functionally change it.

opw-2854810

closes odoo/odoo#94325

X-original-commit: 849a561ebb26e7dca9018c6f81b8492ef21d7a7a
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-06-22 18:26:56 +02:00
Ivan Yelizariev 8b7a705861 [FIX] purchase_stock: keep qty on return
When purchase is returned, the product may move to internal location first. If
option `Update quantities on SO/PO` is active, it does decrease the qty.
However, when the option is disabled, it increase the qty instead of doing
nothing.

Fix it by making a proper if-else block structure

STEPS:

- Create a PO, confirm it and receive the product
- On the transfer, make a return to a location that is not a child of your warehouse (PhysicalLocations/W/...), for instance, choose the location Physical Locations/Subcontracting Location
- Untick the "Update quantities on SO/PO" (visible in debug), and validate the return transfer
- Check your initial PO

BEFORE: the received quantities have been updated, even if we asked not to do it
AFTER: the received quantities is not changed

opw-2858390

closes odoo/odoo#93471

X-original-commit: eb16b4ece9766d4fea85d88ad72e25e8ada209ac
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Ivan Elizaryev (iel) <iel@odoo.com>
2022-06-14 09:36:05 +02:00
Nicolas Pierre 5b2d16360d [FIX] purchase_stock: days to purchase not used in orderpoint action
Since https://github.com/odoo/odoo/pull/86682, when a user opens
the replenishment view, the  Days to Purchase are not taken into
consideration when calculating the forecast of a product.
This was due to the fact that the Days to Purchase are now taken from the
orderpoint and not from the company settings. This is fixed by taking
the company setting if no value from the orderpoint is sent to the
method.

closes odoo/odoo#93252

Task-id: 2871408
X-original-commit: ac1df1949e4523aff65543f1381300fc7de3b4e4
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: npi-odoo <npi@odoo.com>
2022-06-10 09:28:13 +02:00
Ahmed Khalaf(ahkh) 7253130cb1 [IMP] {purchase, sale}_stock: Incoterm Location field
Added Incoterm Location field in SO and PO forms and reports

Task: 2764771
Part-of: odoo/odoo#91640
2022-06-03 12:02:05 +02:00
Nicolas Pierre 87d33596d1 [IMP] mrp, purchase_stock: visibility days and days to prepare MO
- Add the concept of 'Days to Prepare MO' in  mrp, similar to 'Days to
Purchase' but defined at the product level. Both concepts are merged into
Days to Order at the orderpoint level, taking the value of Days to Purchase
for orderpoints with a buy route and Days to Prepare MO for orderpoint with a
manufacturing route.
 - Add the concept of 'Visibility Days' on orderpoints. The idea is to
avoid to create through reordering rules multiple small orders for  the
same product on a small time frame but rather to order directly a bigger
quantity. When Visibility Days are defined, the quantity of the orders
created by a RR is not the quantity forecasted at Today + Lead times
(quantity that triggered the order according to the RR), but the
quantity forecasted at Today + Lead Times + Visibility days.
The Visibility Days are different for purchase and manufacturing.
Changing the route of the orderpoint will change its value. They
can be defined at the company level and further fine-tuned on the
orderpoint. In case of change of the parameters at the company level,
only orderpoints without a specific value of Visibility Days  will
be changed.
 - Alignement between Manufacturing and Purchase Security Lead Time
(previously the Manufacturing Security Lead time didn't impact the
procurement date, instead the manufacturing time was made longer).

closes odoo/odoo#86682

Task-id: 2738838
Pr: https://github.com/odoo/odoo/pull/86682
Related: odoo/upgrade#3415
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-05-31 19:16:55 +02:00
Arnold Moyaux 86878dd13e [FIX] mrp,purchase_stock,stock: avoid new param
following commit 55398263f9297ab2709e4c4c2a9c6c3ee7f59c8a
Introduce a new param to fix a notification issue. However
we could use the context instead of a new parameter in order
to avoid breaking the customisation.

Linked to PR #88303 discussion

closes odoo/odoo#92353

X-original-commit: 69dcdd410adcefe29bfa4fecd2e7c50fe3465b19
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-05-27 15:42:40 +02:00
Touati Djamel (otd) 537e82d78d [FIX] purchase_stock: update the move price after changing the PO line price
Steps to reproduce the bug:
- Create a storable product “P1”:
    - Standard price: 20$
    - Add vendor in the Purchase tab:
        - name: Azure Interior
        - min qty: 10
        - price: $15

- Create a PO:
    - Vendor: "Azure Interior"
    - Product line: “P1”
Automatically, the Quantity field will automatically get populated as 10 Units
and price:$15 as per the pricelist

- Confirm the PO
A picking will be created containing a stock_move with a price of $15 and a QTY of 10

- Edit the Quantity to 9 Units and save the PO
The price will be updated to $20 on the PO line, but not in the `stock.move`

Problem:
When we update the qty in the PO line, a new move with a quantity of “-1” and
a price of “$20” will be created.
Then, it will be merged with the initial move, but since they are not identical in the price,
we can't merge them, so a new picking is created:
https://github.com/odoo/odoo/blob/dda9700d8236091626cbd78efc0ca4116e1e1acd/addons/stock/models/stock_move.py#L869-L881

Solution:
when the price is updated in a PO line, the price of its linked `stock.move` must also be updated

opw-2825160

closes odoo/odoo#92208

X-original-commit: c8d74a1cb4bfed8226e52e0bc6f243b4e483fc98
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-05-27 10:46:33 +02:00
Pieter Claeys (clpi) b3305b1886 [FIX] stock,purchase_stock,mrp: replenishment notification
When clicking order now on a replenishment line (orderpoint) for a manufacture or WH resupply route, it will sometimes show a notification for a purchase order that was created earlier instead of the correct one.

closes odoo/odoo#91404

X-original-commit: 9ca9bcc51fa289ddb0548f81a795755d196e31ca
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Tiffany Chang <tic@odoo.com>
2022-05-16 10:09:52 +02:00
Adrien Widart f6ee398deb [FIX] purchase_stock: trigger RR with a defined supplied
In a 2-steps configuration, trigger a reordering rule with the vendor
defined will raise an error

To reproduce the issue:
1. In Settings, enable "Multi-Step Routes"
2. Edit the existing warehouse:
    - Incoming Shipments: 2 steps
3. Create a product P:
    - Type: Storable
    - Add a vendor V
    - Routes: Buy
4. Create a reordering rule R for P:
    - Trigger: Manual
    - Min = Max = 1
5. Open the Replenishment page and edit R:
    - Preferred Route: Buy
    - Vendor: V
6. Trigger the orderpoint

Error: An Odoo Server Error is displayed "AttributeError:
'product.supplierinfo' object has no attribute 'name'"

When triggering the orderpoint, it leads to
https://github.com/odoo/odoo/blob/c75a1a8ac9eef6c7d7c95b7bbbb22d919b952e26/addons/purchase_stock/models/stock_rule.py#L331
However, since [1], the `name` of a `product.supplierinfo` has been
renamed to `partner_id`

[1] f3fe2d50d9

OPW-2780562

closes odoo/odoo#90597

X-original-commit: bda8b0e610f7ec9b0bcb76de3bb52fb6049f62ff
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-05-05 16:23:14 +02:00
Adrien Widart 63ef74bdee [FIX] {sale,sale_purchase,purchase}_stock: cancel SO linked with a PO
When the user cancels a SO, if there is an associated PO, there won't be
any activity logged on the PO about the SO cancellation.

To reproduce the issue:
1. Unarchive the MTO route
2. Create a product P:
    - Type: Storable
    - Routes: MTO & Buy
    - Add a vendor V
3. Create and confirm a SO with 1 x P
    - Note: a PO is generated
4. Cancel the SO
5. Open the PO

Error: There isn't any information about the cancellation of the SO. An
activity should be added to the PO.

Since [1], if the PO is a draft, we no longer log an activity when the
quantity of the related SO is reduced:
https://github.com/odoo/odoo/blob/3bd9b7a77a1e0e05ea479945d5cd8085f6981feb/addons/purchase_stock/models/stock.py#L103-L105

However, when cancelling a SO, we call the activity logger:
https://github.com/odoo/odoo/blob/846ad1f978fe36db892a9902bb4657c2079d1756/addons/sale_stock/models/sale_order.py#L184-L189
So, since the PO is not yet confirmed, we ignore it and do not log any
activity

[1] bda3225c6cc27bb2c2933eda3cc68c6f9708daf3

OPW-2820242

closes odoo/odoo#90553

X-original-commit: de485a39c9ee88aa31f9330a468ad31cc05842bc
Signed-off-by: Steve Van Essche <svs@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-05-05 16:22:52 +02:00
Merlin (megu) 90569e55ab [FIX] purchase_stock: use a valid route as default buy route
In a multi-company environment, creating a product template will always
try to assign it's route to `route_warehouse0_buy` but this throws an
error if the current company is not the one of the route

Steps to reproduce:
1. Install Inventory and Purchase
2. Go to Settings > Inventory > Warehouse and enable Multi-Step Routes
3. Open Inventory and go to Configuration > Warehouse Management >
Routes
4. Open the 'Buy' route, assign it to one of the company for example 'My
Company (San Fransisco)' and save
5. Go to Products and select an other company for example 'My Company
(Chicago)'
6. Click on `CREATE`
7. An error is thrown, preventing the user from creating new products

Problem:
Function `_get_buy_route` always fetched the same route but this route's
company might have been changed so an error is thrown when trying to
access it from the other company

Solution:
Check if we have access to `route_warehouse0_buy` before using it.

opw-2805154

closes odoo/odoo#90093

X-original-commit: 1a733ae0bfd9f1cb1e90a2cab80af290560c6f12
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Guillaume Merlin (megu) <megu@odoo.com>
2022-04-29 12:06:18 +02:00
Adrien Widart 31fd543ba8 [FIX] purchase_stock: create new POL if different RR
If the user triggers several orderpoints one by one, some purchase order
lines may be merged while they shouldn't.

To reproduce the issue:
1. In Settings, enable "Storage Locations"
2. Create a product P:
    - Type: Storable
    - With a vendor V
    - Route: Buy
3. Add two reordering rules to P:
    - Min=Max=1 at WH/Stock
    - Min=Max=2 at WH/Stock/Shelf 1
4. Inventory > Operations > Replenishment, trigger the orderpoints of P
(one by one)
5. Open the generated PO

Error: There is only one line with 3 x P, there should be two lines (1 x
P + 2 x P, one for each orderpoint). If the user confirms the PO and
receives the products, the destination location will be Stock or Shelf 1
(depending on the last orderpoint triggered)

Running the orderpoint leads to `_run_buy`, where we try to find an
existing PO line so we can update it (else we will create a new one):
https://github.com/odoo/odoo/blob/5b34adb51eda978aa9ef1a434ab77257d73b9594/addons/purchase_stock/models/stock_rule.py#L122-L129

Here is the issue: the filter in `_find_candidate` contains an `or True`
that makes a whole condition useless.

Considering [1], the condition on `move_dest_ids` is only relevant when
an orderpoint is defined. Therefore, we can remove the `or True` and
improve the condition

[1] 63fffa0bee

OPW-2720868

closes odoo/odoo#88959

X-original-commit: 0802d4c61d7b47f0b32a36c5bb0ec49a0f425043
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-04-19 09:48:06 +02:00
Guillaume (guva) 4432ce5f7f [FIX] purchase_stock: price diff on vendor bill
Steps to reproduce:

• Create Record: Product Category
- Costing Method: Average
- Inventory Valuation: Automated
- Specify a price difference account (may create new account).
- Ensure Stock Interim (Received) account is reconcilable.

• Create Record: Product
- Product Type: Storable
- Cost Price: 1.01
- Product Category: New Product Category

• Create bill with this product, for a quantity of 10.5

-> The is price difference of 0.1

Issue comes from this commit 286ea6b681e9ba77357f91b546052449f6342f20
which doesn't round if there is a discount.

With this commit we isolate the latter case in order to keep the
price unit rounded if there is no discount.

closes odoo/odoo#88734

X-original-commit: 643d91ef5ebfb29fde142294ced82c470d42c136
Signed-off-by: Florian Gilbert <flg@odoo.com>
2022-04-14 07:17:53 +02:00
Arnold Moyaux 470b756297 [IMP] purchase_stock, sale_stock: pickings status
Add a reception/delivery status on sale orders and purchase orders.
The idea is to have an indication in list view about the situation
of pickings linked to the SO/PO.

Inside the document itself, the quantity delivered decoration are
designed to indicate if everything is correctly deliver or if
it still something to do. (red if the delivery/receipt is late and
incomplete)

Task-2381757

closes odoo/odoo#63356

Signed-off-by: Arnold Moyaux <arm@odoo.com>
2022-04-04 17:48:08 +02:00
Gorash 880954ebfc [IMP] *: remove _render from ir.ui.view and simplify report
There were inconsistencies in the calls to `_render`.
* the view context could contain information that misled developers.
Indeed, the context and value of the view are not supposed to be found
in the rendering. Thus by calling `ir.qweb` with the name of the
template, we ensure that there is no unwanted information and in
addition the cache key is that of the name of the template which saves
a query.
* the context used for rendering was modified by a method on
`ir.ui.view`, except this is not information used by this model. There
is now a `_prepare_environment` method residing on `ir.qweb`. This
method allows to modify the value dictionary as well as the context in
which the rendering will be done. This preparation of the data as well
as my security check is done only once per rendering. This also saves
some queries
* Freeze options for rendering were inconsistent. It could be that
options on which rendering depends were not part of the cache key. Thus,
depending on the user who generated the generation of the rendering
function, there was or was not information in the template. For example
for automatic branding. This is no longer possible, because it is the
context that is used. The options serving as a cache key are only
recorded for information (for the profiling system for example). A
simplification of the `ir.qweb.field` models could be made.

The report rendering and call `ir.qweb` instead of `ir.ui.view`.

Part-of: odoo/odoo#85110
2022-03-29 10:56:15 +02:00
svs-odoo a53344c34d [FIX] purchase_stock: duplicate partner_id key
In `account.move` `_stock_account_prepare_anglo_saxon_in_lines_vals`,
the `partner_id` is set two times, following those PR:
  - odoo/odoo#75038
  - odoo/odoo#84468

closes odoo/odoo#86154

X-original-commit: 3db2db30a22b0da968c1c739d53dec40a4cabed8
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
2022-03-10 08:11:13 +00:00
clesgow 49f61225ff [FIX] purchase_stock: Apply po_lead only to buy orderpoints
Changes made in #78199 would remove the Purchase Security Lead Time from
any orderpoint as long as the 'purchase_stock' module was installed,
whether the orderpoint was related to purchase or not.

Task-2721378

closes odoo/odoo#85594

X-original-commit: 3bd9b7a77a1e0e05ea479945d5cd8085f6981feb
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
2022-03-01 17:25:31 +00:00
Brice bib Bartoletti c11ae302fc [FIX]purchase_stock,stock_account:partner on aml
The aim of this commit is to set partner on anglosaxon
aml in order to help our client in their stock
reconciliation process in case it hasn't been done automatically.

Before this commit:
anglosaxon line were created without partner

After this commit:
A partner is set when anglosaxon line are created

closes odoo/odoo#84547

Ticket: 2692308
Community-pr: https://github.com/odoo/odoo/pull/84468
X-original-commit: abfe37fcea5b20f77799d9331d4d011530880669
Signed-off-by: William André (wan) <wan@odoo.com>
2022-02-14 19:25:06 +00:00
Arnold Moyaux c75a1a8ac9 [FIX] purchase_stock: Wrong delivery date on purchase line
Usecase to reproduce:
- Create product 1 with supplier `Vendor` and a delay of 3 days
- Create product 2 with supplier `Vendor` and a delay of 4 days
- Create two procurements with a need for stock at 01-01-2022 (warehouse
1 step)
- Run procurement for product 1
- Run procurement for product 2

The PO contains the two product but the order date is for 3 days before
and not 4. Also the line for product 2 is planned for the 02-01-2022

It happens because the delivery date is computed base on the purchase
order date and the supplier but the procurement is totaly ignore

X-original-commit: aec7fcdb693729f432ae2341c00ef317b65fbcbc
Part-of: odoo/odoo#83430
2022-02-02 16:40:48 +00:00
Arnold Moyaux 476394c580 [FIX] purchase_stock: propagate supplier in multi steps
X-original-commit: 1e550be1cc968940dd5c263160b8cc38e9d4e72b
Part-of: odoo/odoo#83430
2022-02-02 16:40:48 +00:00
Raphael Collet a1904aa6f6 [IMP] core: field index names
The possible index names have been renamed "btree", "btree_not_null"
(instead of "not null") and "trigram" (instead of "gin").

Task 2742526

Part-of: odoo/odoo#83274
2022-01-28 14:10:01 +00:00
Fabien Pinckaers eedf37d6e2 [IMP] Better handling of indexes
Three supported types:
- btree (default for index=True)
- btree not null (when >90% of the data are null)
- gin trigram search (for char fields)

Review of indexes on all objects.

closes odoo/odoo#83015

Signed-off-by: Fabien Pinckaers <fp@odoo.com>
2022-01-19 16:52:23 +00:00
Touati Djamel (otd) 4f0dd2271a [FIX] purchase_stock: fix system parameter access right
You are blocked with an access error when you try to replenish a product with `”Buy”` route if you don't have the settings rights,
because the code tries to read a system parameter.

Solution:
To avoid this error, we need to read it as superuser.

opw-2725702

closes odoo/odoo#82814

X-original-commit: dff238959f46708b68cda4b03f8f6981f7245ee7
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
2022-01-14 18:24:04 +00:00
Adrien Widart c2bfba7ff2 [FIX] purchase_{stock,mrp}: compute price difference of a kit
In automated-AVCO configuration, buying a kit at a higher price than its
cost can create inconsistencies in the accounting.

To reproduce the issue:
(Need account_accountant. Use demo data)
1. Create a product category PC:
    - Costing Method: AVCO
    - Inventory Valuation: Automated
    -  Set up the Price Difference Account PDA
2. Create 3 products P_kit, P_compo01, P_compo02
    - Type: Storable
    - Category: PC
    - P_compo01:
        - Cost: 10
    - P_compo02:
        - Cost: 20
3. Create a bill of materials:
    - Product: P_kit
    - Type: Kit
    - Components:
        - 1 x P_compo01
        - 1 x P_compo02
4. On P_kit's form, "Compute Price from BoM":
    - The cost should be $30
5. Create a purchase order PO with one line:
    - Product: P_kit
    - Quantity: 1
    - Unit Price: 100
6. Confirm PO and process the receipt
7. Create and Post the bill

Error: There is an error in the journal items of the bill: the value for
PDA is $85

When posting the bill, for each account move line, the module computes
the stock valuation of the associated product and the price difference.
To do so, it sums the valuation of all related outgoing stock moves and
divides by the quantity to get the value per unit, then it compares with
the unit price used on the PO's line. Here is the issue: in case of a
kit, there is one outgoing move per component while the PO's line is
linked to the kit itself.

Therefore, in the above case, it uses the outgoing moves of P_compo01
and P_compo02, adds up their value ($10 + $20 = $30) and then divides by
the total quantity (one P_compo01 and one P_compo02, thus $30 / 2 =
$15). This is the reason why it considers that the unit value of P_kit
equals $15. Then, since the unit price on the PO's line is $100, it gets
a price difference value equal to $85.

When comparing the unit value of the kit and its unit price, the unit
value should not be divided by the quantity of components ($30 should
not be divided by 2). Moreover, when buying such a kit at $100, the
surplus ($70) should be distributed among each component. However, it is
difficult to define a rule to correctly weight this distribution.
Therefore, this surplus will be considered as a price difference.

OPW-2566546

closes odoo/odoo#82463

X-original-commit: 20888055d4271bf3cf9e7bc3d42150a1f72e4495
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
2022-01-10 14:49:52 +00:00