According to Wiktionary, French spacing is "the archaic practice (though
still current in French) of inserting a space around colons, semicolons,
question marks, and exclamation marks". This is not standard practice in
English and most languages of the world.
The purpose of this commit is to start purging the code from this typo,
as it may reflect poorly on the software for some people.
closesodoo/odoo#114533
Related: odoo/enterprise#37853
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Steps to reproduce:
1. Create a membership product for a period of time in the past,
and one including the current day
2. Create a member, make him non-free
3. Create an invoice for the member for the past membership, cancel
the invoice
4. Note that membership state is not updated to `cancelled` (Problem 1)
5. Change the `date_cancel` on membership.membership.line
to a date in the past
6. Add an invoice for the current membership, note that the state is
updated to `cancelled`
7. confirm the invoice and register payment, note that the state is
not update to `paid` (Problem 2)
This line in `_compute_membership_state` causes the bug to appear:
```
if partner.membership_cancel and today > partner.membership_cancel:
partner.membership_state = 'free' if partner.free_member else 'canceled'
continue
```
To solve the issue, we remove the lines of code that made the state
to be stuck and use the membership lines only to calculate the correct
state.
opw-2978902
closesodoo/odoo#106179
X-original-commit: addd3fbfebddab7572a785a3c27c9f90ddc3408b
Signed-off-by: Grazioso Andrea (agr) <agr@odoo.com>
Signed-off-by: Khanalizadeh Ahmad (khah) <khah@odoo.com>
Refactor the `load_views` API so it no longer sends multiple times the same
fields description.
e.g.
When `load_views` is called to get the kanban, tree and form views,
the list of fields of the model was sent 4 times:
- Once for each view, with only the fields used in the view,
in `['fields_views']['kanban']['fields']` for instance
- Once globally, with all the fields of the model, in `['fields']`
The goal of this revision is to change that so it sends the list of all fields
only once.
In addition, if a view contains x2many fields,
the fields description of the comodel is also sent.
It was sent in the `views` key of the view fields dict.
e.g.
When calling `load_views` of `res.partner` to get the kanban,
tree and form views,
the `res.partner` fields description was actually sent 6 times:
- Once for each view
- Once globally
- Once for each view of the many2many field `child_ids` of the form view, in
- `['fields_views']['form']['fields']['child_ids']['views']['kanban']['fields']`
- `['fields_views']['form']['fields']['child_ids']['views']['form']['fields']`
The change suggested in this revision is to:
- Remove the fields description for each view in `['fields_views']`.
As it no longer contains the fields,
the key becomes `['views']` instead of `['fields_views']`.
- Replace the dict key `['fields']` by `['models']`,
which is a dict with as key the model name and as values
the model fields description. It contains the fields description
for all models implied in the view:
the model of the main view and the model of all one2many and many2many fields.
With this change, the fields description will only be sent once by model
implied in the view.
In addition, the web client was getting the information about the fields
sometimes in the global fields description list (e.g. `['fields']`),
sometimes in the fields description list of the view type
(e.g. `['fields_views']['form']['fields']`),
making it a pain to try to make changes / performance gain
in these field description dictionaries, because you never knew in which dict
the web client was getting its info.
Now, as there is only one place to get the fields description from,
it's clearer and cleaner.
- one2many and many2many fields views are passed directly in the main view
architecture rather than being put in the `views` key
of the field description.
This is actually easier to treat by the web client,
and this will allow in a future work to cache an entire view in one block
of text rather than having to combine multiple cached blocks of text
to return one view.
- one2many and many2many fields which do not have directly embedded views
have their views directly injected in the architecture,
so the web client doesn't have to do RPC calls to `load_views`
for each one2many and many2many fields not having embedded views.
For instance, this allow to reduce the number of RPC calls to `load_views`
from 8 to 1 when loading the form of `product.product`.
Currently, this behavior is limited to 1 level deep but we consider making it
go all the way down in future works. We did not do it for the moment because
in certain cases it rises the processing time and the size (bytes) too much.
e.g. the sale.order view can be 5 levels deep,
meaning you can reach 4 dialogs on top the main view.
```
sale.order form > order_line > sale.order.line form > invoice_lines >
account.move.line form > asset_ids > account.asset form >
depreciation_move_ids > account.move form.
```
This will also benefit in future works to cache an entire view in one block
of text rather to having to combine multiple cached block of text
to get one view.
- `fields_view_get` becomes `get_view`.
As it no longer returns the fields description,
keeping the `fields` in the name `fields_view_get` no longer makes sense.
Hence removing `fields` from the method name, it becomes `view_get`.
As it gets renamed anyway, we take the opportunity to rename it `get_view`,
which is more in line with the general getter/setter guidelines
in the model object world.
- `_fields_view_get` becomes `_get_view`. For the same reasons than above.
- `load_views` becomes `get_views`.
This is not mandatory, there is no technical reason to rename `load_views` as
it practically sends the same info as before,
the view architectures and their fields description. Just in another way.
We just take the opportunity of this pull request to suggest a cleaner API:
`_get_view`, `get_view` and `get_views`.
- Arguments `toolbar=False, submenu=False` fo the methods
`_fields_view_get` and `fields_view_get` are converted to a kwargs `**options`
in `_get_view` and `get_view`.
The rationale is that submenu was already no longer used (deprecated)
and the mobile options is introduced.
The mobile options is necessary to tell the server to send the mobile views
for x2many fields (kanban instead of tree).
Instead of adding a new argument each time we add a new option to
`fields_view_get`, it seems wiser to have a kwargs `**options` to avoid
to re-write all overrides each time a new option is introduced.
- `_fields_view_get` returned a dict containing the arch in text and some of the
view information. Now, `get_view` returns a tuple with the view architecture
as an `etree` node, and the view as a browse record. The rationale is that all
overrides of `_fields_view_get` were about modifying the arch only
(e.g. changing the address format/re-organizing the address related field
nodes of the partner according to the company country).
To do so, all these overrides were doing `etree.fromstring` to parse the arch
which was sent in text to convert it to an `etree`,
then operations were done on the `etree`,
and then `etree.tostring` was called to convert back the arch to string.
With this change of signature to send the arch as an `etree`,
all these back and forth `etree.fromstring` -> `etree.tostring` are avoided,
allowing some performance gain and less code in the end.
- A cleanup of the keys returned in the dict of `fields_view_get`
has been performed in `get_view`:
- `fields` is removed, as explained above,
- `view_id` is renamed `id`,
- `name` is removed, it was unused by the web client,
- `type` is removed, it was unused by the web client,
- `field_parent` is removed, it was unused by the web client,
- `base_model` is removed, it was unused by the web client.
- `filters` is moved from the global dict returned by `load_views`
(now `get_views`) to the dict returned by `fields_view_get` (now `get_view`)
as it applies only to the `search` view type.
- Retro-compatible methods for the 3 methods
`fields_view_get`, `_fields_view_get` and `load_views` are provided,
with deprecation warnings in them.
- The web client could cache the model fields description
(as it already caches the views),
so it doesn't need to fetch them again if it asks for another view of a model
for which he already has the fields description.
If we do so, `get_views` could return only the list of models used by
the views, without the fields description as of now,
and the web client would then call `fields_get` independently only for
the models for which it doesn't have yet the fields description.
This would avoid the server to return the fields description
and to call `fields_get`, which is costly, for each `get_views`,
therefore gaining performances.
- Inject the views of the one2many and many2many fields all the way down,
unlimited depth level, as explained above.
- Cache with `ormcache` the architecture of back-end views.
This is already done for qweb views, it's not done for back-end views.
Therefore the postprocessing of the views is performed for each `get_views`,
which is costly, while the view architecture doesn't change for users
belonging to the same groups, according to the groups implied by the view.
This pull request is co-authored by
Aaron Bohy (aab) for the web client part and
Denis Ledoux (dle) for the server part.
Part-of: odoo/odoo#87522
Having a non paid membership for last year and being associate with
someone having a non paid membership was dispalying an 'old' membership
state instead if a 'non' membership.
Assumption:
If an associate member is added, take the state of the associate member
(tooltip of associate member).
In case the associate member is a 'non member', it's stupid to associate
with someone that is paying or have paid as it won't consider the state of
the current paid member, the link has to be made on the other side:
the 'non' paying will be associate with the 'paid'.
Create membership for
a/ 2019 (1jan to 31dec)
> For the calculation of the 'old' state
b/ 2020 (1jan to 31dec)
> For the calculation of the 'paid' state
Create few res.partner:
AA: No associate.
2019 - Paid
2020 - Paid
>> Paid member
(= ok)
CC Case 1:
Associate with AA
2019 - Invoiced (but not paid)
2020 - None
>> Paid member due to association with AA
(= ok)
CC Case 2:
Not associate:
2019 - Invoiced (but not paid)
2020 - None
>> Before fix: Old member
(= nok)
>> After fix: Non member
(= ok) As he never paid and not linked to someone that paid.
DD: Associate with AA
2019 - Invoiced not paid
2020 - Paid
>> Paid member (with or without association with AA)
(= ok)
EE Case 1:
Not associate:
2019 - Paid
2020 - None
>> Old member
(= ok)
Case 2:
Associate with DD
2019 - Invoiced (not paid)
2020 - None
>> Paid member (due to association with DD)
(= ok)
Case 3:
Associate with CC
2019 - Invoiced (not paid)
2020 - None
>> Before fix: Old member (due to none having a current 2020 invoiced)
(= nok it should take the state of CC)
>> After fix: Non member (as CC is not a member)
opw-2287050
closesodoo/odoo#55773
X-original-commit: 5e7b7b0a645bcff175bf8d2483eae5ffd4aaf89b
Signed-off-by: agr-odoo <agr-odoo@users.noreply.github.com>
time.clock is deprecated since python 3.3 and no longer exists in python 3.8
time.process_time was introduced in python 3.3
Replace "is" by "==" as this produces a SyntaxWarning in python 3.8
Fixesodoo/odoo#41313closesodoo/odoo#44502
X-original-commit: f03b4cb5576f264b6845242ba112f02422af4f5f
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
- 'partial' payment state corresponds to invoices whose payable/receivable move line has been partially reconciled with some other line.
- 'reversed' payment state corresponds to entries that have been cancelled by the creation of a single reverse entry (using the dedicated button on the form view). This state can be set on invoice as well as on regular entries.
=> To stay consistent with the naming conventions, this commit also renames invoice_payment_state field to payment_state, since it's no longer only applicable on invoices.
closesodoo/odoo#41723
Related: odoo/enterprise#7202
Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
This commit deletes account_cancel module and squash it into account.
The 'update_posted' field is changed by 'restrict_mode_hash_table' field.
If 'restrict_mode_hash_table' is true, you have a hash chain on your account journal.
These hash chains prove the inalterability of your accounting.
l10n_fr_certification module is deleted and all hashing method are moved in account module.
Now, you can download a PDF report about your inalterability in the company settings.
If you have l10n_fr or l10n_post_cert installed you have more information on this report
like the inalterability of pos orders, etc.
Task ID: 2039160
This branch is the combination of several optimizations in the ORM:
* store field values once in the cache: the cache reflects more
faithfully the database, only fields that explicitly depend on the
context have an extra indirection in the cache;
* delay recomputations by default: use method `recompute` to explicitly
flush out pending recomputations;
* delay updates in method `write`: updates are stored in a data
structure that can be flushed efficiently to the database with method
`flush` (which also flush out recomputations);
* make method `modified` take advantage of inverse fields to inverse
dependencies;
* filter records by evaluating a domain on records in Python;
* a computed field with `readonly=False` behaves like a normal field
with an onchange method;
* computed fields are computed in superuser mode by default.
Work done by Toufik Ben Jaa, Raphael Collet, Denis Ledoux and Fabien
Pinckaers.
closesodoo/odoo#35659
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
Multi is the default api for methods, it is not necessary to explicitly
decorate methods with it, adds clutter and most people use it because
they see that the rest of the code uses it.
Done with `find . -type f -name '*.py' | xargs sed -i '/@api.multi/d'`
Since previous commit moved decimal_precision module's feature into base,
use the new syntax for fields declaration
Remove the imports to the removed module
Remove the module from dependency in manifest
sed -i "s|digits=dp.get_precision('\([A-Z a-z]*\)')|digits='\1'|" **.py
sed -i "/from odoo.tools import decimal_precision as dp/d" **py
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
In a still-to-determnie situation, a cyclic dependency with
`associate_member` is observed, preventing the installation of the
module.
We remove the dependency, and trigger a recompute on the parent members.
opw-2005325
closesodoo/odoo#33977
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
Purpose of this commit is to give description more "business oriented"
because those descriptions appears in Odoo Studio which is supposed to be used by end users, not only by developers.
Related Task ID : 37311
Purpose: improve understanding of partner and product models as well as their
daily use. This is done by improving tooltips and labels of some fields
according to business logic.
This commit is related to task ID 1880696 and closes PR #27133 .
Thanks to @xmo-odoo for its in-depth review.
- Go to a contact C1 > Membership tab > Buy membership
- Create an invoice with the membership
=> It creates a membership line on C1
- Change the partner on the invoice to C2
The membership line and the membership status is not transfered to C2.
We first need to recompute on C1, and we also need to explicitly write
the new partner C2 on the membership lines.
opw-1875673
- Go to a contact > Membership tab > Buy membership
- Create an invoice with the membership
=> The status of the member goes to 'Waiting membership'
- Validate the invoice
=> The status of the member goes to 'Invoiced membership'
- Create a credit note to cancel the membership
=> The status of the member goes to 'Paid members'.
It shouldn't be the case because the client has canceled his membership.
We look on `payment_move_line_ids` instead of `payment_ids`. Indeed, the
latter doesn't list credit notes, while the first one lists all move
lines used for payment.
opw-1875673
From this commit onwards, Date fields will return datetime.date objects and Datetime fields will return datetime.datetime objects, this implies a number of things that are clearly explained both in the ORM API for master.
This commit also introduces a number of helper functions for dates and datetimes that are exposed in tools.date_utils and fields.Date[time], explained in the documentation as well.
Task-ID: 47189
``import odoo.addons.foo as bar`` doesn't seem to properly trigger the
import hook in Python 3 (it blows up on decimal_precision and
base). Thus convert *all* examples of that pattern to the more
sensible ``from odoo.addons import foo as bar``.
The signature _check_recursion already exists in odoo/models.py
So calling _check_recursion, the function which checks the constraint on
associate_member overwrote _check_recursion in "res.partner" model and
the function _check_parent_id defined in "res.partner" was completely
wrong because it needs _check_recursion defined in models.py
opw:710524
Purpose
=======
we use to make proforma invoice to get payment before the creation of the real invoice. In the current odoo, the proforma state is too late. Because you have to confirm the SO to generate the draft invoice and so the proforma. But, if you do that, you have generated a subscription or a delivery order in the mean time. A proforma is actually a quote. In old ERP they used to make proforma to send a quote and don't generate invoice number.
Specification
=============
- Remove everything related to Proforma from accounting
- Remove the configuration of pro-forma from account setting
- Invoice form, remove "Pro-froma" button, stage, report title
- Add proforma configuration option in sales setting under "Quotation and Sales" section
- In quote/sale, add Pro-forma under Print
- A pro-forma is a quote, but the title of the report is Pro-Forma and not Quotation
- button (secondary) on quotation form "SEND PRO-FORMA" to send proforma by mail attached with related report.
- button
- mail template
- when preparing a quotation this button is visible but if even one invoice this should be invisible (as confirming SO doesn't generate invoice currently)
Removed overridden unlink() of account.invoice/(.line) models by introducing ondelete='cascade'
for 'account_invoice_line' field for 'membership.membership_line' model
- Split compute function in res.partner into 4 functions as they no more share the same dependencies
- removed dead constraint from 'membership.membership_line' model. That constraint checks if the invoice's date
is greater than membership line's date but the membership line is created before the draft invoice is created
(and that too without date set), hence it can't be raised.(Though, it can be raised if we check it on 'state' field).