Commit Graph
18 Commits
Author SHA1 Message Date
Victor Piryns (pivi) 9ed8db4f6e [FIX] project: account invoices/bills in project update dashboard
Current behaviour:
In the project update dashboard, invoices and bills that are created
directly (without sales order or purchase order) are not taken into account
in the calculations for profits/costs.

Expected behaviour:
They should be taken into account, as long as the line on them has the
analytic account line on it.

Steps to reproduce:
- Install Project, Sales, Purchase, Accounting
- Activate "Analytic Accounting" in Settings
- Create a new Project and create a new analytic account for the project
- Create a Bill with a product (storable/consumable) and the analytic account
on the line
- Post the bill
- Go to your project update dashboard and notice the cost of the bill
is not taken into account, but we do have a smart button that goes to the bills

Reason for the problem:
Profits/Costs calculations are done based on the sales/purchase orders,
missing the "orphaned" invoices and bills. A side effect of this problem,
storable products on sales are also not taken into account, since Sales Orders
don't have an analytic account per line before version 16, unless that product
is a service (all services intrinsically have an analytic account)

Fix:
Get all invoices/bills that have lines with the project's analytic account,
and removing from those the lines that were already accounted for.

Affected versions:
- saas-15.3
- 16.0
- master

opw-3058198

closes odoo/odoo#108176

X-original-commit: 3d3f4109a06445b6ce9606770085c763ea206b35
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Signed-off-by: Piryns Victor (pivi) <pivi@odoo.com>
2022-12-16 17:20:00 +01:00
gawa-odoo b8dca3b174 [IMP] analytic, *: Json field for analytic distribution
The `analytic_distribution` field is a Json.
It was stored temporarily as a char.

Search is not available yet, so we do queries by hand when we need to search on keys.

Also added a constraint on account_analytic_distribution_model,
so we don't have models with accounts specific to a company when the model has no company or another company.
It would cause an issue when looking at the models from another company.

X-original-commit: 7064c95aa04e5138bb12ae97acfee04ebb67cc0e
Part-of: odoo/odoo#103097
2022-10-17 10:11:09 +02:00
gawa-odooandHabib 7e3403068f [REF] *: Analytic Apocalypse
The goal of this commit is to get rid of the analytic tags as they were confusing, serving tag purposes as well as distribution on analytic accounts.

Everywhere analytic tags were used as a distribution have been replaced with a new widget that will dispatch distribution on analytic accounts. If there was an analytic account field next to the tags, it has been included in the distribution.

Analytic tags that were used simply as information tags have been removed.

To fill the new widget, there are now 2 kind of rules that will help fill and prefill it.
The first are applicability: previous groups have been removed, and have by replaced by plans. Each account is required to have a plan. These plans define when they are available in the widget: a default applicability per plan and applicability lines that can specify rules following the context of the widget.

The second one are distribution models, that will replace previous default rules but follow the same principles. The accounts (and so the plans) that will be given by the distribution model can override the applicability rules from before.

closes odoo/odoo#98914

Related: odoo/upgrade#3885
Related: odoo/enterprise#30743
Signed-off-by: William André (wan) <wan@odoo.com>
Co-authored-by: Habib (ayh) <ayh@odoo.com>
2022-09-20 12:36:01 +02:00
Yolann Sabaux 04a352ea76 [FIX] purchase: update analytic account on change of the line
Steps to reproduce:
- create two products
- create two analytic accounts
- create two new analytic rules by assigning an account to a product
- Create a new PO and select on of the product
- On the same line, change the product to the other one

Issue:
- The analytic account won't be updated

Cause:
Bypass of the `account_analytic_id` whenever there is already on defined

Solution:
For the `Sale` fix, I added the `line.state == 'draft'`.
The reason? Because the compute is triggered after confirmation of the order due to:
https://github.com/odoo/odoo/blob/14.0/addons/sale/models/sale.py#L931-L935
Therefore, the compute won't also be triggered after confirmation of the SO.

opw-2948950

closes odoo/odoo#99858

X-original-commit: 61604e18128c1cfd0e6d4e510852f780491d6e4e
Signed-off-by: William André (wan) <wan@odoo.com>
2022-09-13 10:30:17 +02:00
Nasreddin Boulif (bon) d07209872d [FIX] purchase: Update price unit on new line even if confirmed RFQ
Steps to reproduce:

  - Install purchase
  - Go to Settings and activate `Variant Grid Entry`
  - Create a new Requests for Quotation
  - Add a customer and add a product that has a variant min 2 variant
  - Wizard should ask for the variant
  - Select 1 variant by increasing quantity in the grid and confirm
  - Confirm order
  - Add again a product variant with the wizard

Issue:

  Price unit is not set on the new line.

Cause:

  In `_onchange_quantity` (triggered by the purchase_product_matrix
  module), we do not update price unit if order line
  is in state `purchase` or `done`.

Solution:

  Replace condition to not perform `_onchange_quantity` if order line
  has an invoice line.

opw-2956755

closes odoo/odoo#99522

X-original-commit: 8f92146b2d4996be724213345567291f045aad85
Signed-off-by: Adrien Widart <awt@odoo.com>
Signed-off-by: Nasreddin Boulif (bon) <bon@odoo.com>
2022-09-04 02:57:57 +02:00
Nshimiyimana Séna 727fd4f208 [FIX] sale, purchase: fix invoicing interaction with “Invoicing Switch Threshold”
Steps to reproduce:
- Create a sale order with a product that's invoiced on delivered
  quantities.
- Set delivered quantity (partial delivery) and create an invoice based
  on the delivered quantity. Set the  "Invoice Date" to sometime in the
  past.
- Go to the settings and set  "Invoicing Switch Threshold" to any date
  in the future (so that the invoice you created has a date BEFORE the
  new threshold)
- The invoice will get the label "invoicing app legacy".
- Go back to the sales order and change the delivered quantity.
You should see that the invoiced quantity is automatically set to 0.
A similar behavior can be observed with purchase orders.

Why this is happening:
When a new “Invoicing Switch Threshold”  is set, all posted invoices
before the threshold are marked as `canceled`. In v15, changing the
delivered quantities  triggers the invoiced quantities to be
recalculated as well. However, computing invoiced quantities doesn't
take into account  invoices that are marked as `canceled`. This mean
that the newly computed invoiced quantities won't include invoices
posted before threshold.

opw-2896797

closes odoo/odoo#98909

X-original-commit: cc979734bd7ef3f2a94b411cb7b4f3e782b7ddab
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Nshimiyimana Serge Séna (sesn) <sesn@odoo.com>
2022-08-30 03:45:05 +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
Denis Ledoux 5ccc32fcf7 [IMP] tests: common.Form, can't write on invisible fields
In the web client, in a real use case, it's not possible
to write on fields which are invisible,
as it's not possible to write on fields which are readonly.

This is a first step in the goal to change the behavior
of the `groups=` attribute in the back-end views,
to remove them for the view instead of making them invisible.

This is mainly to reduce the diff of the revision that will introduce
the mentioned above behavior change.

As nodes with `groups=` will be removed from the view
when the user doesn't have the group, it's no longer possible
to set a value on a field having a `groups=` the user doesn't have
in the `Form` test class, as the field will no longer be at all in the
view.
However, these unit tests shouldn't have been able to set values
on invisible fields in the first place.
This revision therefore aims to correct the unit tests setting value
on fields which were invisible because the user executing the
test was not part of the required group(s) for these fields
to be visible in the view.

closes odoo/odoo#94337

Related: odoo/enterprise#28936
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2022-07-08 14:33:47 +02:00
Thomas Beckers 4e67c4adeb [FIX] purchase: don't mix PO's lines in generated invoices
If we use the auto-complete feature to add PO's lines to an bill or we select multiple PO's then use
'create bill' button, the generated invoice line will copy the sequence line from the PO's line. This
can lead to situation where we will have all the first lines of each PO then all the second, etc, ending
with a mix of all PO's in the bill.

Example:
Purchase order 1
- seq 10 line A
- seq 11 line B
- seq 12 line C

Purchase order 2
- seq 10 line A'
- seq 11 line B'
- seq 12 line C'

Invoice created from those PO's
- seq 10 PO1:line A
- seq 10 PO2:line A'
- seq 11 PO1:line B
- seq 11 PO2:line B'
- seq 12 PO1:line C
- seq 12 PO2:line C'

After this PR this PR the lines from the same PO's will be contiguous like:

Invoice created from those PO 1 and 2
- seq 10 PO1:line A
- seq 11 PO1:line B
- seq 12 PO1:line C
- seq 13 PO2:line A'
- seq 14 PO2:line B'
- seq 15 PO2:line C'

opw-2749682

closes odoo/odoo#95343

X-original-commit: cafe5c1aff1ca1632ce4924a6b027629c283a5e9
Signed-off-by: Steve Van Essche <svs@odoo.com>
Signed-off-by: Beckers Thomas (tbs) <tbs@odoo.com>
2022-07-06 08:18:08 +02:00
Ahmed Khalaf(ahkh) 3b88ed5ea4 [IMP] purchase: Supplier info added with sudo qty 1
This commit contains the following:
1) Added sudo to product record when adding supplier info during PO confirm, so that
supplier info is created regardless of who is confirming the PO.

2) the test test_multicompany_partner_bank was removed since it was creating two
res partner banks with the same partner and setting company_id to two seperate companies
while currently the company_id is related to the company partner thus this can no longer
happen.

3) test_message_qty_already_received was changed to not set the company_id explicitly as
it caused unexpected cache miss in the runbot.

task : 2764771

Part-of: odoo/odoo#91640
2022-06-03 12:02:06 +02:00
william-andre beb6e17066 [FIX] account: remove dead code complete_tax_set
This field was used in version 9.0 [1] to allow users to select their
tax rate, but it was removed in version 12 [2]

[1] https://github.com/odoo/odoo/commit/c04065abd8f62c9a211c8fa824f5eecf68e61b73
[2] https://github.com/odoo/odoo/commit/87f0d2eefb77bfc6a9a0fa7f7dcd1475c7c34639

closes odoo/odoo#80185

Related: odoo/enterprise#22441
Related: odoo/upgrade#3057
Signed-off-by: Quentin De Paoli <qdp@odoo.com>
2022-03-31 17:24:55 +02:00
Adrien Minet 34fea66e41 [FIX] purchase: partner_bank_id is wrongly set up
How to reproduce the bug ?

- install the accounting, contacts and purchase apps
- create several companies and enable the checkboxes of all
  these companies
- create a new contact and add a bank account for each company
- switch to a company different than the first one
- create a request for quotations in the purchase apps and
  confirm it
- in the accounting app, create a new vendor bill and use the
  auto-complete field to select the RFQ created earlier.

The bug:

When you try to create a vendor bill from a request for quotations,
the recipient bank is wrongly chosen. Because of that, there will be
2 issues. The first one is when you want to create the bill from the
RFQ: you will get an error and the invoice won't be created. The second
one is when you create an invoice then use the auto-complete field. In
this case, there won't be any error but the recipient bank will
be wrong.

opw-2731264

closes odoo/odoo#86078

X-original-commit: 074fee2e19547f4145ae0aa93d68741ab4aa9bae
Signed-off-by: Adrien Minet <admi@odoo.com>
Signed-off-by: Minet Adrien (admi) <admi@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
2022-03-10 12:58:42 +00:00
Audric Onockx (auon) 5c09a8d9f7 [FIX] purchase : Account analytic default changed by user is reset in invoice
Reproduce :
1. Add a default analytical rule: if Coin Gourmand partner then Administrative analytical account
2. Create a PO at the Coin Gourmand supplier, add a product, and select the Internal analytical account.
3. Bill for this product.

Result :
Internal analytical account has disappeared from the invoice line. It has been replaced by Administrative.

Issue :
AccountMove.create() computes an account in the move and this causes the analytic account to be reset at its default value from the rule.

Fix :
Since the account pocalypse in 13.0, account.move is making magic things during the creation of the invoice to create dynamically the invoice lines like account.invoice did before this huge refactoring.
The create is making a 'New' record to simulate the onchange but this code is a hack triggering unexpected recomputation like the analytic account.
To avoid that, we ensure to assign the minimum number of fields to preserve fields like the analytic account.

closes odoo/odoo#79321

X-original-commit: 876e2d1073312fe65cb6b2e3038235aeaa082c8a
Related: odoo/enterprise#22074
Signed-off-by: Laurent Smet <las@openerp.com>
Signed-off-by: Josse Colpaert <jco@openerp.com>
2021-11-03 13:26:55 +00:00
Martin Trigaux 9aedb999f5 [IMP] *: remove xmlid_to_object helper
Use env.ref instead of the xmlid_to_object
To make it more readable and be able to clean old helpers
2021-08-10 14:24:11 +02:00
Adrien Widart fdd4af3e2a [FIX] purchase: use Product Price precision in bills
When the Product Price precision is greater than the currency precision,
it can lead to incorrect data

To reproduce the error:
(Enable debug mode)
1. Settings > Technical > Database Structure > Decimal Accuracy, edit
Product Price:
    - Digits: 3
2. Create a PO
    - Add a product:
        - Quantity: 12
        - Unit Price: 0.001
3. Save, Confirm, Edit the PO:
    - Qty Received: 12
    - (Note that the total is $0.01)
4. Create a bill:
    - Add the PO to the field "Auto-Complete"

Error: The unit price is $0.000 and so does the total

The rounding of the unit price should be based on the Product Price
precision, not the currency precision.

OPW-2601867

closes odoo/odoo#74813

X-original-commit: 1123856c77cce4b69059b63c2bcbb382c7f0719e
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
Signed-off-by: Adrien Widart <adwid@users.noreply.github.com>
2021-08-06 13:00:24 +00:00
Adrien Widart 997086ba5f [FIX] purchase: auto-complete bill with multi-currency
When adding several PO to a bill, if they don't have the same currency,
it will lead to incorrect amounts

To reproduce the error:
1. In Settings, enable "Multi-Currencies"
2. Invoicing > Configuration > Currencies:
    - EUR: Active, Current Rate = 2
    - USD: Active, Current Rate = 1
3. Create a PO:
    - Currency: USD
    - Products:
        - One product, no taxes, unit price 1000
4. Confirm PO
5. Edit PO:
    - Qty Received: 1
6. Repeat 3 -> 5 with EUR instead of USD
7. Open a new Bill
8. Add the first PO to the field "Auto-Complete"
9. Add the second PO to the field "Auto-Complete"

Error: Both invoice lines are now expressed in EUR and both subtotals
are equal to 1000 even though the exchange rate isn't 1

This commit suggests not to change the currency of the account move if
the latter already has some AML. Moreover, the amounts must be converted
if they come from a PO that uses another currency

OPW-2573748

closes odoo/odoo#73483

X-original-commit: b299e880417026688b2fbde23307bd011de8c44d
Signed-off-by: Steve Van Essche <svs-odoo@users.noreply.github.com>
Signed-off-by: Adrien Widart <adwid@users.noreply.github.com>
2021-07-09 10:11:42 +00:00
Laurent Smet f0a50da53e [IMP] purchase: Remove dependency to AccountTestCommon
l10n runbot builds are all failing when running at least one test depending of AccountTestCommon bec
- doesn't create a sandboxed testing environnement to manage the multi-currency, multi-company, the
- doesn't setup a testing user then all tests are done using the superuser.
- doesn't provide a fully setup chart of accounts: exchange difference journal is not set, accounts
- is run sometimes at-install.

--task: 2301180
2020-07-31 07:11:32 +00:00
yhu-odoo d0455ae64b [IMP] purchase: make billing consitent with sale invoicing
========
Purpose
========

Currently, purchase missing some billing functions that we have in sale
invoicing:
 - Create credit note when necessary
 - Create vendor bill in batch in list view

========
Spec
========

 - In case of retures, when create a bill for a purchase order, we check
the total amount we want to bill to decide whether it's a vendor bill or
a credit note.
 - In the list view, add a new action to create vendor bill/credit note
for all selected order.

========
Links
========

Task 2170715
PR #44210

Related: odoo/upgrade#919
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
2020-03-27 09:33:21 +00:00