Currently, when reinvoicing an expense, an SOL with
the expense product is added to the selected SO but,
the 'quantity' field remains at 0.
But when added expense product to SO we need to change the sales order
price because it will be charged to the customer in the end.
So n this commit, Set the quantity on the SOL equal to
the quantity set on the expense.
closesodoo/odoo#56718
Task-id: 2320167
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
l10n runbot builds are all failing when running at least one test depending of AccountTestCommon because it:
- doesn't create a sandboxed testing environnement to manage the multi-currency, multi-company, the default company's currency, the exchange rates...
- 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 have bad types, etc...
- is run sometimes at-install.
--task: 2301180m
l10n runbot builds are all failing when running at least one test depending of AccountTestCommon because it:
- doesn't create a sandboxed testing environnement to manage the multi-currency, multi-company, the default company's currency, the exchange rates...
- 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 have bad types, etc...
- is run sometimes at-install.
--task: 2301180
Impacted modules:
hr, hr_contract, hr_recruitment, hr_payroll, fleet, hr_skills, hr_appraisal, ....
Several onchanges have been converted to computed fields in the following modules :
Community :
- hr
- hr_contract
- hr_recruitment
- hr_work_entry
- hr_maintenance
- hr_expense
- hr_expense_check
- hr_holidays
- sale_expense
- account_analytic_default_hr_expense
Enterprise:
- hr_contract_salary
- hr_referral
- hr_payroll
- hr_payroll_expense
- test_l10n_be_hr_payroll_account
There are still 2 onchanges with complex behavior that couldn't be converted easily:
- an onchange that updates "tz" (timezone) that is defined as a related field
to "resource_id.tz". Apparently it is useless except to initialize the default
value of "tz".
- an onchange that updates "name" that is defined as a related field to
"resource_id.name".
the applicant.
closesodoo/odoo#45414
Taskid: 2169099
Related: odoo/enterprise#8572
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Since 12.0, we wanted the employee to select directly the sales order on which
the expense should be reinvoiced. The goal was to avoid employee to select the
analytic account (too technical and usually unknown for employee). Problem is
that we had to give read access to SO to simple employee, breaking the access
rules "See your own document".
As we want to allow all internal employees to determine if the expense should
be reinvoice and on which sales order it should be, we need to allow them to
select that sales order.
This commit allows user to search on SO (simply get their name_get), no information
more to avoid breaking "See your own document" for salesman. Falty ir.rule and
access rights are now removed.
We now clearly split the cost tracking and reinvoicing flow:
- the analytic account field (visible only with group 'analytic' as considered
as advance feature) allows user to track their expenses in some accounts.
- the sales order is displayed for users or approvers to reinvoice the expense.
As this operation implies the tracking, if the AA is not give, the SO will create
its own AA in which the expense will be tracked.
This SO field is only relevant when the product has a reinvoice policy, so we hide
it if there is no reinvoice policy defined.
Reinvoicing an expense has now a different flow from reinvoicing a "Vendor Bill",
which still do magic to determine the SO from the AA set on its lines.
Technical:
to allow user to select SO from a m2o dropdown, the `name_search` is done in `sudo`
for internal user. This is a borderline 'feature' of the system. A few thing show
that the system does completely supports this ("Search More" gives access error, ...).
We still keep this solution, as we don't want a sub group giving access to SO to all
employee (aka an option allowing people to break the sales rights).
Task-1843241
This commit merges the following models
* account.invoice and account.move
* account.invoice.line and account.move.line
* account.voucher and account.move
* account.voucher.line and account.move.line
It was the opportunity for a big cleanup of the code, so it also restructures the whole account module, its different models/fields, the tests etc. for a better world and a better code readability.
==== Rationale ====
The rationale of this huge change is that we want journal entries / invoices to be easily edited, and changes reflected in the other model. It's a HUGE feature and very strategic for the fiduciary companies. For example, changing the account of a journal entry needs to be automatically reflected on the related invoice.
The same reasoning applies to sale/purchase vouchers.
==== Changes made in features =====
When creating an invoice, you are now creating a journal entry directly.
--> The object account.invoice no longer exists.
In the same fashion when creating an invoice line, you're now adding journal items directly in the journal entry representing the invoice. If this invoice line has some tax, it may create additional journal items as well.
--> The models account.invoice.line & account.invoice.tax no longer exist
Identically, when creating a sale/purchase receipt with its lines, you are now creating a journal entry directly and there's no more usability difference between encoding a receipt or an invoice.
--> The object account.voucher no longer exists.
--> The object account.voucher.line no longer exists.
--> The whole account_voucher module no longer exists.
Positive side-effects coming from these changes are
* draft invoices/bills/sale or purchase receipts now create a draft accounting entry. Validate these objects now simply post its journal entry. That means that draft invoices/bills/sale or purchase receipt can straightforwardly be included in reporting or budgets.
* opening a journal entry in form view will now always open the correct view: if it's a sale/purchase journal entry we will have a customer invoice/vendor bill view or a sale/purchase receipt view, whatever the menu we're coming from.
* code & business logic simplification. It is also condensed in a single place instead of being partially duplicated on invoices, vouchers and journal entries.
There should be no feature loss, except the one allowing to group multiple journal items together based on the same product during the invoice validation.
==== Changes made in models =====
* account.invoice: model removed. Instead, now use account.move with following mapping
field (account.invoice) field (account.move)
----------------------- --------------------
name invoice_payment_ref
number name
reference ref
comment narration
user_id invoice_user_id
amount_ total_company_signed amount_total_signed
residual amount_residual
state state + invoice_payment_state /!\ selection changed
date_invoice invoice_date
date_due invoice_date_due
sent invoice_sent
origin invoice_origin
payment_term_id invoice_payment_term_id
partner_bank_id invoice_partner_bank_id
incoterm_id invoice_incoterm_id
vendor_bill_id invoice_vendor_bill_id
source_email invoice_source_email
vendor_display_name invoice_vendor_display_name
invoice_icon invoice_vendor_icon
cash_rounding_id invoice_cash_rounding_id
sequence_number_next invoice_sequence_number_next
sequence_number_next_prefix invoice_sequence_number_next_prefix
'invoices' subset of account.move can be accessed by using the selection field 'type' or one of the many helpers like is_invoice()
* account.move: now has a valid state 'cancel' that has to be excluded from all business logic
* account.move: field 'amount' renamed into 'amount_total'
* account.move: field 'reverse_entry_id' renamed into 'reversed_entry_id'
* account.move.line: now has a field 'display_type' that has to be excluded from all business logic, in order to support invoice layouting
* account.invoice.line: model removed. Instead, now use account.move.line with following mapping
field (account.invoice.line) field (account.move.line)
---------------------------- -------------------------
invoice_id move_id
uom_id product_uom_id
invoice_line_tax_ids tax_ids
account_analytic_id analytic_account_id
'invoice lines' subset of all account.move.line from a journal entry can be accessed by using the boolean field 'exclude_from_invoice_tab'
* account.invoice.tax: model removed. Instead, now use account.move.line with following mapping
field (account.invoice.tax) field (account.move.line)
--------------------------- -------------------------
invoice_id move_id
account_analytic_id analytic_account_id
amount price_unit
base tax_base_amount
'tax lines' subset of all account.move.line from a journal entry can be accessed by using the relational field 'tax_line_id'
* account.invoice.confirm: model removed. Instead, now use the 'post()' function of account.move
* account.invoice.refund: model removed. Instead, now use account.move.reversal to reverse the entries with the same options as we had for invoices
* account.voucher: model removed. Instead, now use account.move of type in ['out_receipt', 'in_receipt]
* account.voucher.line: model removed. Instead, now use account.move.line
==== Changes made in functions ====
* on account.move, method _run_post_draft_to_post() renamed into _autopost_draft_entries()
* on account.move, method action_account_invoice_payment() renamed into action_invoice_register_payment()
* on account.move, method action_invoice_reconcile_to_check() renamed into action_open_matching_suspense_moves()
* on account.move, method _get_domain_edition_mode_available() renamed into _get_domain_matching_supsense_moves()
* on account.move, method _get_intrastat_country_id() renamed into _get_invoice_intrastat_country_id()
* on account.move.line, method _get_domain_for_edition_mode() renamed into _get_suspense_moves_domain()
* in account.bank.statement, contextual key 'edition_mode' renamed into 'suspense_moves_mode'
Was task 1917430
Purpose
=======
The method named "action_invoice_create" in the sale_order model did not make sense:
- this method is not an action (it returns the ids of created invoices)
- it is not used as an action on any xml buttons
- it has no reason to be private
This was probably a "real" action somewhere in the past but now it's just too confusing.
(The method in repair.order was also renamed for the same reasons).
[MOV] move sale_payment into sale
=================================
Almost all use cases of sale require sale_payment down the line.
There is only one case which does not: using sale_management without website_sale or website_quote.
However, since we want to move most of the features of website_quote into sale_management, moving sale_payement first will make the task easier.
[MOV] move website_quote into sale and sale_management
======================================================
We want to use some features of website_quote without having to install the whole module.
The main issue with website_quote was that it had a requirement on website.
What is common to website_sale and sale_management has been moved into sale. This is primarily the sales order portal view.
What is only related to sale_management has been moved into it. This is notably: sales order templates, optional products, sign and pay, ...
Everything that requires website has been moved into a new module named sale_quotation_builder. This is related to using the HTML builder to customize the quotation view.
Models, files and routes have been renamed to better convey their purpose and to follow guidelines more closely.
[IMP] merge sales order portal views
====================================
The old sales order view on the portal has been merged into the one from website_quote. The new view contains features of the two.
A lot of fixes and improvements have also been done, related to BS4 issues but also to improve the sales order view in general.
[IMP] add new settings
======================
The commit adds new settings related to activating the features that previously were activated by installing website_quote.
PR: #26345
Task: 49205, 1838924
Moves UoM models, test and data to a new addon in
order to be able to use uom without product.
A simple example is be to be able to use UoM for
timesheets.
This commit only move code, and adapt xml ids
without chaging any feature or functionnal
behavior.
Note: 'product' module now depends on new
'uom' module.
A product can be sell or expense, but for some cases the product
configuration make both flow incompatible. Indeed, when expensing
the delivered qty was computed based on the AAL total amount, and
manually editable.
Before the delivered qty refactoring, reexpensing erased the manual
value.
This came from the fact product expense policy is wrongly used: the
delivered qty of expensable product is not manually editable, which
is a problem for milestones (and other consumable product when stock is
no installed).
The new refactoring of deli qty API force the expense line to be
completely
readonly, but the problem is not completely solved; we still can't sell
properly a expensable product.
To do so, the SO line must be flag as coming from an expense or vendor
bill, and the reinvoice product policy should only be used to calculate
the price of new SO line.
This commit:
1) reinforces the readonly caracter of expense SO line, by making the
expense policy independent of the computation method for delivered qty
on SOL.
2) prevents generate picking when updating ordered quantity on a expense
SOL with a stockable product.
3) allows service to sell a task with zero hours as ordered quantity.
(it still prevents task/project creation for expense SOL).
4) does not increment anymore an existing line when expensing product
at sales price and invoicing at 'delivered qty'. The only line to be
incremented will be the expense line (and not the native SOL).
Impacted modules: sale, sale_timesheet, sale_expense, sale_stock
and sale_mrp
This commit uniformizes the API of computing the delivered quantity on a
SO line for expense, manual, service and stock lines.
The delivered qty of so line can be computed differently. This is the
role of the 'qty_delivered_method' field:
- manual: the quantity is set manually, when creating or editing the
line
- analytic: handle in sale module, the quantity is the sum of the
unit_amount of analytic lines coming from expense or vendor bills
- timesheet: handle by sale_timesheet module, the quantity of a product
service with timesheet is compute as the sum of the hours of timesheet
lines linked to the SO line.
- stock_move: handle by sale_stock module, the delivered quantity comes
from the validated pickings of the SO line, for stockable or consummable
products.
When the computing method is 'manual' the value is stored in
'qty_deliverec_manual' field. This field is 'technical' and should not
really be used, as the real field to read/write is 'qty_delivered'.
To extend the mecanism of computing delivered quantity on SO line, a
module should provide its own method for 'qty_delivered_method' and extend
'_compute_qty_delivered' method to compute the effective quantity.
Purpose: When running tests, all the tests for the installed/updated
files are done. This commit adds a 'tagged' decorator that can be used to
tag tests. Combined with a new 'test-tags' CLI option, it adds the ability
to filter which tests are executed. For example, @tagged('slow') will
add a tag 'slow' to the test. The CLI option 'test-tags="slow"' will
only run tests tagged 'slow'.
One can use prefixes to select cases with tags.
'+' or no prefix means that the tests tagged with this tag are selected
for execution. '-' prefix will exclude the tests tagged with this tag.
Exclusion takes precedence over inclusion.
Also, by default, all Odoo tests cases are tagged 'standard' and with
the technical name of the module.
This means that when selecting tests with the 'test-tags'
parameter, if '-standard' is not specified, all tests tags are
going to be executed.
When tagging tests, one can remove such automatic tag by prefixing the
tag name with '-'. E.g. @tagged('-standard') will remove the standard
tag from the test.
Another example, if one wants to test the 'sale' module alone,
even without adding any 'tagged' decorator thos tests can be selected
like that: --test-tags="sale"
Tests are selected or deselected using a TagsSelector. When instanciated,
a string is passed with comma separated tests selectors like
'+slow,-standard'. When the 'check' method is called with a test as argument,
it returns True or False if the test has to be executed or not.
This commit make expense test depending on the
same common class as the other (in sale_expense).
Some data were badly defined (test data), using
field only existing when sale is installed. So move
this part in sale_expense.
Expense tests now check analytic entries when
sumbitting an expense.
Accounting tests are executed post install to be sure a chart
of account is install. However, for some case, we might want
to run test at module installation, involving accounting, without
being sure a chart of account is installed.
This commit provides a base common test class with a minimal chart
of account (some journals and accounts) allowing to start tests at
installation. this class should be extended in sale or expense for
this modules to be tests at installation. We will required this for
reinvoice test in sale later (test consumable product when sale_stock
is not installed, but maybe without a chart of account). The idea is
each test suite can call method to setup their own data.
This commit also use this common test class in sale_expense.
Since this field is an analytic account and not a project, its
name should be more explicit. This commit makes the code more
understandable. Naming things correctly improve developper's
sleep.
stock_landed_costs: on nightly, the localization installed may not have stock properties accounts defined. If it's not, we create them on the fly with a random account
sale, sale_expense: fix broken tests due to mismatch currency:
On 10.0-nightly, the currency of the company is not the same that the product.list0
that leads to assertion errors.
In Python 3:
* various builtins and dict methods were changed to return
view/iterable objects rather than lists
* and the separate Python 2 view/iterable builtins and methods were
removed altogether
This is problematic when using these items as list (which the happens
repeatedly in Odoo), but more viciously when iterating *multiple times*
over them (which also happens, which I've messed up multiple times while
writing this, and which is a pain to debug even when you've just created
the issue).
Convert all code using these to semantics-matching cross-version
helper functions to get the LCD behaviour between P2 and P3, and
forbid the builtins via lint.
issue #8530
NB:
- The option no_delete is not working, a fix will come from chm
- The many2many widget on a sheet creation is not working correctly as
the called command is a (1, id, values) without a (4, id, _) before.
A fix will also come from chm, but a disgusting hack has been
provided for this particular case (to remove after chm fix)
The test does not have hardcoded values referring to demo data anymore.
Moreover, in the test, we now use values which are different from the
demo data (621.54 instead of 700). Overall, this will make the test more
robust.
hr_expense: change car travel sale price
Car Travel Expense is used as a product invoiced at sale price.
Therefore, it is more useful to have a cost price and a sale price which
are different.
The whole idea of this commit is to avoid having the same values
everywhere.