This revision is to make uniform the behavior of the `groups` attribute
on the Python model fields
and on the node in the view architecture.
In both cases, remove the node from the view completely.
Before this revision,
in a back-end view:
- In the Python model, if a field has the `groups` attribute set
and the user is not part of
the groups, the field is removed, completely, from the view.
- In the view architecture, if a node has the `groups` attribute set
and the user is not part of
the groups, the node is made invisible (not completely removed, just
made invisible).
in a front-end view:
- if a node has a "groups" or "t-groups" set and the user
is not part of the groups, the node is removed from the view.
So it's 2/3 cases removing nodes restricted to a group.
and 1/3 case making invisible nodes restricted to a group.
It's simpler to have a uniform behavior for the 3 cases,
simpler to understandard for developers.
In addition, this will help for the goal to cache back-end views.
It makes possible to convert views using the `groups_id` field
by moving the content of these views directly
in the view to which they add content which is suppose to be completely
removed when the user has not the according group.
By getting rid of the `groups_id` many2many field on `ir.ui.view`,
it makes possible to cache the view architecture without
requiring to use the groups in the cache key.
Currently, if we want to cache the view architecture,
it would be required to use the intersection of the user
groups with the `groups_id` groups of the view,
making it costly to compute the cache key,
therefore altering the performance point to cache the view
architectures.
closesodoo/odoo#95729
Related: odoo/enterprise#29592
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
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
closesodoo/odoo#96134
Related: odoo/upgrade#3715
Related: odoo/enterprise#29758
Signed-off-by: Laurent Smet <las@odoo.com>
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
closesodoo/odoo#97279
Signed-off-by: Fabien Pinckaers <fp@odoo.com>
When creating an invoice from a repair order, the account mapping of the
fiscal position doesn't apply even though the tax one does
Steps to reproduce:
1. Install Repair and Accounting
2. Go to Accounting > Configuration > Invoicing > Fiscal Positions and
create a new fiscal position with:
- Name: 'FP test'
- Tax Mapping from 'Tax 15.00%' to a new tax 'Tax 10.00%'
- Account Mapping from '400000 Product Sales' to '450000 Other
Income'
3. Go to Sales > Products and create a new product 'Product A' with:
- Product Type: 'Consumable'
- Customer Taxes: 'Tax 15.00%'
- Income Account: '400000 Product Sales'
4. Create another product 'Product B' with same values except type which
is 'Service'
5. Go to Repairs and create a new repair order with:
- Any Product to Repair
- Any Customer (once set, edit the customer's fiscal position to 'FP
test')
- Invoice Method: 'Before Repair'
- Parts: add a line of type 'Add' with product 'Product A'
- Operations: add a line with product 'Product A'
6. Confirm the order, create an invoice and open it: the account mapping
of the fiscal position didn't apply (it should be '450000 Other
Income')
Solution:
Apply the fiscal position mapping on the income account of the product
opw-2902056
closesodoo/odoo#96038
X-original-commit: 02975a8a7b1803167a5ba8365cfbf29f80f84b2e
Signed-off-by: Guillaume Merlin (megu) <megu@odoo.com>
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.
closesodoo/odoo#94337
Related: odoo/enterprise#28936
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This allows to create a repair.order record without
the need to call the onchanges to set the uom and locations
or to set them manually during the `create` call.
For instance, this makes easier to create repair orders
using XMLRPC when you do not use multiple UOMs or multiple locations.
closesodoo/odoo#95321
Signed-off-by: Raphael Collet <rco@odoo.com>
Remove most values uselessly specified because giving the same value as
the default one (see _DEFAULT_MANIFEST in odoo/modules/module.py)
* auto_install is Falsy by default
* author is Odoo SA by default
* summary & description are empty strings by default
* application is False by default
* test, demo, depends and data are empty lists by default
This will reduce noise/inconsistencies between manifests specifications,
simplify analysis of manifests content, ...
closesodoo/odoo#90209
Related: odoo/enterprise#26807
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This feature supports the use case of:
- a customer receives a delivery from you.
- there is a defective product in the delivery
- they schedule a repair (RO) + return (picking) for the product
We want to ease the creation/management of the repair order associated
with the return, therefore the following features are added:
- Create links between ROs and return pickings (smart button in return
of all repairs associated with it + field in RO)
- Option (requires active setting) to create RO(s) directly from a
return picking
Implementation notes:
- Because return picking type doesn't have its own "Type of Operation"
(it is 'code'='incoming'), we default to only incoming picking types
that have at least 1 other picking type it is the
'return_picking_type_id' of.
- Originally a Wizard for choosing which/how many products should have
ROs created for them was designed (i.e. to match return wizard + to
multi-create ROs), but this was determined to be too complicated due
to SN/lot selection. Instead simple approach of creating a single RO
each time button is pushed was implemented to match the helpdesk >
repair button workflow.
- ROs are purposely allowed for 'draft' and 'cancelled' returns/moves to
support different types of workflows (e.g. RO is confirmed before
return is)
closesodoo/odoo#85157
Task: 2732517
Signed-off-by: Arnold Moyaux <arm@odoo.com>
The contact widget supports displaying VAT but it was added manually in the reports after contact. This commit fixes this behavior and results in fewer code and an easier way for the l10n modules which may modify VAT display.
closesodoo/odoo#83733
Related: odoo/enterprise#25195
Signed-off-by: Laurent Smet <las@odoo.com>
Reduces load_menus answer size by 32% (between 20kb and 200kb savings
for the initial loading of the backend, depending on the number of apps
installed). Support for SVG icons in the web client for menus/apps.
Reduced PNG icons for apps list (8 bits PNG instead of 24 as our icons
don't need more colors as they are flat designs)
closesodoo/odoo#84280
Related: odoo/enterprise#24200
Signed-off-by: Fabien Pinckaers <fp@odoo.com>
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
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.
closesodoo/odoo#83015
Signed-off-by: Fabien Pinckaers <fp@odoo.com>
Suppose a tracked-by-usn and consumed product returns in the stock
thanks to a repair order. Using again this component in a new
manufacturing order will raise an error
To reproduce the issue:
1. In Settings, enable "Storage Locations"
2. Create two products P_finished, P_compo
- Storable
- P_comp tracked by USN
3. Update the quantity of P_compo:
- WH/Stock: 1 x Lot01
4. Create a manufacturing order MO:
- Product: P_finished
- Components:
- 1 x P_compo
5. Confirm, Check availability and Mark MO as Done
- (Lot01 should be consumed)
6. Create a repair order RO:
- Product: P_finished
- Parts:
- Type: Remove
- Product: P_compo
- Lot: Lot01
- Destination Location: WH/Stock
7. Confirm RO, Start RO, End RO
- (There should be one Lot01 available in stock)
8. Repeat 4-5
Error: When checking the availability on the MO, Lot01 is correctly
reserved. However, when marking the second MO as done, a User Error is
displayed: "The serial number Lot01 used for component P_compo has
already been consumed" although this lot should be available
When checking the uniqueness of the lot, nothing includes the products
back in stock thanks to the repair orders.
OPW-2701668
closesodoo/odoo#82544
X-original-commit: 3d9355f90fa1dd9436f1745c515c89947ed04de0
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
* Do not rely on context, everything should be cleary specified through
parameters
Catch context keys in an unique targeted place to improve code clarity
* Drop strange old API
* do not provide unused partner parameter anymore
* do not provide products, qty as a list of tuple, we only request the
same qty for all products anyway
* Clear methods, add/adapt comments and docstrings
* Reduce potential side-effects of context content.
This commit rename product_uom_qty into reserved_uom_qty and product_qty
into reserved_qty on stock move line to stop mistake them with the stock
move quantities fields.
Task: 2648449
Part-of: odoo/odoo#80434
RATIONALE
Currently we can specify email used for notification layouting through context
use in mail composer. It is then propagated to message_post, stored on
mail.message and used to encapsulate emails sent based on posted messages.
SPECIFICATIONS
Get rid of context usage (``custom_layout``) and use a real field on composer
model: ``email_layout_xmlid``. Use now a default value coming from context
(default_email_layout_xmlid) instead of custom_layout.
Support old context key in composer for backward compatibility, working like
a default value for the field itself.
Task-2621326 (Mail: add 'view' button in 'light notification template')
Task-2647302 (Mail: add layout field in composer)
UPG odoo/upgrade#2829
Part-of: odoo/odoo#76418
This reverts commit 3b3a47f0d3414ae5bee159f6ec4644e64441040f.
task-2667207
closesodoo/odoo#79333
X-original-commit: 09cb77ebf6915e6a98bc3d36869b71f5b495d878
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
Steps to follow
- Enable group_show_line_subtotals_tax_included
- Create a repair order and add a tax to a line
-> The subtotal doesn't contain the tax amount
opw-2513287
closesodoo/odoo#78631
X-original-commit: 133888a1859d81a252177b58b046b54d22ba5ca8
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Signed-off-by: Hubert Van De Walle <hubvd@users.noreply.github.com>
When find a location_id for repair.line, we didn't restrict the location
to have same company_id with the repair.order. Add it.
closesodoo/odoo#78350
X-original-commit: dff911a1b006a542bf9b082c76910a2d8346fef1
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit fixes two issues
* better handle void partner_id;
* get back ``object.origin`` that was removed when converting into QWeb
at odoo/odoo@0a180d04b0
Task-2657930
closesodoo/odoo#77451
X-original-commit: 3b3a47f0d3414ae5bee159f6ec4644e64441040f
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Jinja as a templating engine was problematic in differents respect:
- introduce external dependency to Odoo (less controll)
- add another templating mechanism in the stack
- specific feature in qweb cannot be reused
- difficulty in rendering easily editable templates
- more knowledge required with no betterment
By replacing jinja with qweb we can now build tools to edit a qweb
that will work with the previously jinja encoded document
(essentially `mail.template` records).
There is a catch however. Some email fields (eg. email_to) used jinja
syntax for rendering dynamic variables (ie. ${object.something} and
${object.something_that_should_not_be_escaped | safe}).
We still want user to use dynamic variables for some char fields (eg.
subject, from, to, ...). We made a new rendering engine called
"inline_template" that will render an expression enclosed by `{{` and
`}}`.
To be able to edit the templates from the backend interface, a
plugin to the Odoo editor has been made for seamlessly edit the
document.
This qweb plugin includes:
- make dynamic variables (eg. `<t t-out="variable"/>`) not editable
(for preventing the user to shoot himself in the foot)
- group and hide related logical branching (ie. t-if, t-elif, and t-else)
in order to see only one at once
- a floating select input to switch visibility of a particular logical
branching
Task-27033
X-original-commit: odoo/odoo@68182baff4
Part-of: odoo/odoo#77377
Before this commit, User was allowed to delete repair order which
is linked to posted invoice by moving it to Draft.
With this commit, user is not allowed to delete repair order linked to
a posted Invoice.
closesodoo/odoo#75109
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
Followup of odoo/odoo@cb4f597410 and odoo/enterprise@971f3ed9ae
We have converted string into markup string in repair as we cannot concatenate
strings directly to Markup string. And if we try to do it we will see the
html elements '<br/>' in field value, so we have to convert '<br/>' string
into markup language to avoid this.
Also avoid adding pseudo-void html content in narration.
LINKS
Task Id-2558824
PR odoo/odoo#74795
PR odoo/enterprise#20117
How to reproduce the problem:
- Install the repair App
- Repairs -> Create (a Repair Order) (and activate the debug mode)
- Change the Location Field to something else (than the usual default WH/Stock)
- Open Developer Tools -> Set Defaults
- For Defaults, choose "Location = [the changed Location]", "All Users" -> Save Default
- Create a new Repair Order: the Location is not set to the default we set earlier through the Developer Tools
Cause of the problem : an Onchange method was overriding the default Location
Solution : it will now check, in the onchange, if the change is necessary, before overriding the default.
opw-2545876
closesodoo/odoo#74871
X-original-commit: 9877ad1599513338c5333d3a728edb8d6ebcac26
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
The license is missing in most enterprise manifest so
the decision was taken to make it explicit in all cases.
When not defined, a warning will be triggered starting from
14.0 when falling back on the default LGPL-3.
closesodoo/odoo#74245
Related: odoo/design-themes#48
Related: odoo/enterprise#19862
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Define `data-hotkey` on most used action buttons.
For the modals, the following keys are dedicated for "special"
actions:
- Alt+G: add
- Alt+V: save
- Alt+Z: cancel
closesodoo/odoo#73275
Taskid: 2588233
Related: odoo/enterprise#19464
Signed-off-by: Kevin Baptiste <kba@odoo.com>
Before this commit, suppose we have a scenario like below
Task-A:
Activity-1:
name: Email ( Today )
Assigned to: User-1
Task-B:
Activity-1:
name: Email ( Today )
assigned to: User-2
Activity-2:
name: Call ( Due in 3 Days )
assigned to: User-1
When User-1 goes through the systray 'Today' filter shortcut he gets both
Task-A and Task-B in the list instead of only Task-A. Indeed currently
activities are not filtered based on current user with its deadlines.
However purpose of systray is to indicate activities current user has to
perform instead of global activities.
After this commit activities will be filtered based on deadlines as well as the
current user. In order to achieve this behavior we needed to pass a domain like
[
('activity_ids.date_deadline','=', fields.Date.today()),
('activity_ids.user_id','=', 1)
]
And for that purpose we introduced a non-stored compute field with a search
method.
Task ID-2438822
COM PR odoo/odoo#72219
X-original-commit: f4eaf4d8fb2f97240201104dcd4fc7e2674bce02
Replace text fields to html fields as we have our own 'OdooEditor'.
Indeed, it gives more options to users in the way they format their
content without weighting too much on the UI
(tools appear on demand and not by default).
Models -> fields
1) maintenance.request -> description
2) maintenance.equipment -> note
3) maintenance.equipment.category -> note
4) mrp.workcenter -> note
5) mrp.workorder -> operation_notes
6) mrp.routing.workcenter -> note
7) repair.order -> internal_notes
8) repair.order -> quotation_notes
Task Id: 2499504
X-original-commit: 0cca26b5358cd9d69a65c6b93cfecb33d7e659c5
It replace text fields to html fields as we have our own 'OdooEditor'.
Indeed, it gives more options to users in the way they format their
content without weighting too much on the UI
(tools appear on demand and not by default).
Models -> Fields
1) sale.order -> note
2) sale.order.template -> note
Task Id: 2499504
X-original-commit: 6a345c2695129a5cd907e5e23e057871ebf9ebfa
Purpose is to have all mail template into a mail_template_data.xml file
when possible. It eases maintenance and update when having to work globally
on template records.
Also update some ``body_html`` declarations still using ``xml`` instead of
``html``.
Task ID-2534550 (Template usage improvement)
Task ID-2477164 (Composer mixin)
Prepares Task ID-27033 (QWeb in templates)
COM PR odoo/odoo#70889
ENT PR odoo/enterprise#18352