Commit Graph
126133 Commits
Author SHA1 Message Date
Aaron Bohy d36695cbc7 [REF] web: Calendar: apply coding guidelines 2018-02-27 12:18:55 +01:00
Nicolas Lempereur 60974227cf [FIX] product: create_variant forward-port 5c2380e
In 5c2380e9f an issue when modifying variants values was solved when an
attribute on the product variant had "create_variant" unset.

This commit forward-port what was lost of it in 11.0, that part was
probably lost because the code was previously changed when adapting to
python3.

Without the change, the added test failed creating a new variant keeping
the existing one. With this change, 'nocreate' value are ignored when
computing new variants to create.

opw-1815226
closes #23332
2018-02-27 12:06:49 +01:00
Nicolas Martinelli aff954bd63 [FIX] account: link bank to partner
Changes to a bank account should not be happening without approval and
not in an in-transparent way. In some cases, a third party can pay an
invoice for another account

opw-1817138
2018-02-27 11:31:09 +01:00
Goffin Simon d3843d7ed0 [FIX]fleet: Error when clicking on the costs of a vehicule
Steps to reproduce the bug:

- Go to Fleet
- Group by status
- Click on a vehicule
- Click on Costs

Bug: A traceback was raised because a group_by was made on the model "fleet.vehicle.cost"
for the field "state_id" and this field doesn't exist on this model.

opw:1815454
2018-02-27 09:42:40 +01:00
Hiral Bhavsar 03645bc51f [FIX] account: filters on invoices and bills
- Removed 'Invoices' and 'Credit Notes' filters.
- Removed inherited view of filters to remove the 'Not Draft' filter.
- Renamed 'Not Paid' to 'Open' filter.
- Added new filter 'Paid'.
- When click on 'Invoices/Bills' or 'Credit Notes' link of 'View'
  column from 'Customer Invoices' and 'Vendor Bills' dashboard, it
  should be open invoices with a specific domain instead of default
  filters.

Co-authored-by: Nicolas Martinelli <nim@odoo.com>
opw-1817236
2018-02-27 09:03:57 +01:00
Christophe Monniez 02d826e1a7 FIX] web: increase timeout of test_01_js
The web test suite is increasing, so the test duration increases too.
6 minutes is not enough on some runbot instances.
2018-02-27 08:50:39 +01:00
qdp-odoo 9bc9c86470 [IMP] account, account_bank_statement_import: create res.partner.bank only when statement lines get processed
Previously, bank accounts were created at the line creation, even if the partner was unknown. That was a very weird behavior since
- that use case of a res.partner.bank belonging to no one is meaningless
- the default partner was actually set to the current'user company, which was even more wrong.

This has been already improved by https://github.com/odoo/odoo/commit/7b322d08de2b5343cdf6935a7ae4a12f1fd61958 but that first patch ignored the use case of res.partner.bank created thr$
2018-02-26 18:05:06 +01:00
Alexis de Lattre 1f8835568b l10n_fr: chart of accounts: use bank account type only for accounts linked to bank journals (fixes bug #23040) 2018-02-26 17:22:41 +01:00
Yannick Tivisse 6f614c3254 [FIX] payment: Be less resrictive for payment journals on acquires
Purpose
=======

It looks a little to restrictive to only allow bank journals on payment acquirers.

For example on could want to define a manual payment acquirer linked with a journal of type "cash".

Allow both journal types instead of only bank.
2018-02-26 17:17:33 +01:00
Yannick Tivisse dc6913e2e0 [FIX] payment: Avoid to reset journal_id on acquirer edition
Coming from https://github.com/odoo/odoo/pull/17067

Don't reset the journal but make it required on the form view instead.
2018-02-26 17:17:33 +01:00
Martin Trigaux a546b34f52 [FIX] mail: use correct emoji for shortcode
:) is not the shortcode for 😊
:-) is not the shotcode for 😂
source https://emojipedia.org
2018-02-26 17:14:02 +01:00
Thibault Delavallée f727e9d9b6 [REF] rating: avoid storing rating_value on mail.message
Currently the rating value coming from the rating application is stored
on the message it belongs to. However storing it is not necessary as
there is no direct search using it. Having a computed field is sufficient
for all use cases we currently have in Odoo.

Removing the store allow to gain queries. Indeed the field is not
computed anymore after each message creation meaning we save queries
by not having to check existing ratings. It allows to gain a lot of
computation as mail.message is a critical model.

On the whole community runbot when installing all modules this leads to
a gain of more than 14K queries on 585K which means 2.4% of performances
increase. Considering the code size of this optimization this is quite an
interesting result.

Looking at test_mail performance tests we gain several queries (2/3) for
each new message which is coherent with the model change.

Finally it allows to lessen the performance difference between tests done
with test mail only and tests done with other modules already installed.
This is especially simple mail thread-enable records.

Related to task ID 51523. #Closes #23294. Done with blessing of @jem-odoo .
2018-02-26 16:58:35 +01:00
Ayman Adam Dawood e7c81ce536 [CLA] aymanadam5 signs Odoo CLA
Closes #23295
2018-02-26 16:38:10 +01:00
Patrick Tombez f435bc4fe9 [CLA] adds p-tombez to camptocamp's CLA
Closes #23329
2018-02-26 16:36:29 +01:00
Christophe Monniez 82e9cc7f97 [IMP] test_pylint: test the presence of python debuggers
From time to time, it happens that a developper forget to remove debuggers.
This commit adds a test to find such imports (pdb and pudb). The test
will fail if that kind of import is found. The Odoo runbot should run
this test and prevent developper from those small mistakes.
2018-02-26 16:12:54 +01:00
Adrian Torres d33ce2b4d1 [FIX] base_import_module: don't assume data/ exists
Before this commit, while performing a check on whether a customization
being imported was done using studio or not, we would assume that the
.zip would, at the very least, contain a data folder.

This is not the case as loose files can be imported and the data folder
is only generated by studio customizations.

To solve this, we walk over the whole zip instead of walking over the
data/ folder only (which may be non-existant), so loose files, files
inside the data folder and potentially files in other folders can be
parsed without raising unexpected errors.
2018-02-26 15:33:37 +01:00
qdp-odoo 25b49fe624 [FIX] account: don't _post_validate() an account.move after a reconciliation
Previously, trying to register a payment on today towards an invoice posted with a date prior to the FY lock date, was raising an error... which was completely wrong.
2018-02-26 15:30:16 +01:00
XavierDo 5bb0318ab4 [Imp] product: move uom in a new addon
Adapt enterprise branch to match changes applied in commit 1b64b193f9a6cfd26dee3d723eac968fa4c5000e
2018-02-26 15:14:36 +01:00
Adrian Torres 30db4cdd75 [FIX] stock: remove existing demo data on reinstall
Previous to this rev.:
    *Install stock w/ demo data
    *Uninstall stock
    *Reinstall stock

Result: Boom! Installation crashes.

Reason: The demo data installed with stock is not properly deleted after
the module is uninstalled, which causes issues/conflicts upon
reinstallation of the same demo data.

Solution: Remove any demo data of stock models upon installation if any
exist through a pre_init_hook, ideally this would be done by overriding
the unlink() of the affected models / setting some ondelete='cascade',
or even a uninstall_hook, however these solutions prove insufficient for
databases that are currently affected by the problem.

Fixes #22243
2018-02-26 15:12:25 +01:00
XavierDo 2966d4faed [IMP] product: rename product.uom into uom.uom
Also rename product.uom.categ into uom.category to
 give it a decent name.
2018-02-26 14:27:26 +01:00
XavierDo 6a378e3839 [IMP] product: move uom in a new addon
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.
2018-02-26 14:27:26 +01:00
Thibault Delavallée 9de5d41754 [MERGE][REF] mail, various: remove dead code and perform some small code renaming and optimization
Purpose of this merge is to clean a bit various methods and remove some
dead code. All those commits come from other work-in-progress branches
in mail aiming at improving performances and reducing code size. We can
already merge some light cleaning in order to lessen diff and ease
understanding of real feature-based branches.

It contains

 * some renaming in notification methods to match the _notify prefix used
   in most of them;
 * removal of  some dead code coming from old implementations of chatter;
 * removal of unnecessary context switch in email sending process;
 * small cleaning of notification group methods in various addons;

It allows to gain some queries in various test_mail performance test as
stated in the test_performance file update. When notification emails are
sent 4 queries are gained with this merge. On the whole community runbot
the impact is small (about 1K queries) probably because most of email
sending part is skipped on runbot.

This merge is related to the task Id 59039. #Closes #23089.
2018-02-26 14:24:47 +01:00
Thibault Delavallée 86350c56ff [REF] various: clean override of _notify_get_groups
Overrides of _notify_get_groups are used to add some buttons in notification
emails and control the display of "Access document" button. This commit
cleans some overrides :

 * accounting: portal users that are not the customer have no access to the
   invoice and should not have the access button;
 * project: remove unnecessary override on project model and consider portal
   users have access to the document through customer portal;
 * sale: portal users that are not the customer have no access to the sale
   order and should not have the access button;
 * website_blog: display access button to everyone only if the post is
   published; otherwise keep standard behavior;
 * website_forum: display access button to everyone only if the post
   has not been closed or deactivated; otherwise keep standard behavior;
 * website_slides: display access button to everyone only if the slides
   has been published; otherwise keep standard behavior;
2018-02-26 14:15:12 +01:00
Thibault Delavallée 6eda1dcb7a [REF] mail: simplify email send code and remove unnecessary methods
Send methods of mail.mail model are set private and simplified. Those
methods have been written when a lot of overrides were necessary to
generate notification emails. Since then the flow has changed but
methods have not been updated completely. This commit therefore simplified
a bit the call chain and parameters.

This commit is purely technical and does not hold any functional change.
Purpose is to clean code in order to prepare future changes in mail
application.
2018-02-26 14:15:08 +01:00
Thibault Delavallée d46e358d3e [REF] mail: rename notification methods related to recipients
This commit renames some internal mail.thread methods linked to the
notification process. This is the next commit of a series aiming at
improving code readability and method finding through prefixes. See
notably cae1c3977f, cdfe479e2e and fc1348dd3d.

This commit does not change any functional feature. It does only
rename notification-related methods, using the _notify prefix to
ensure they are private and to mark they are part of the notification
process.
2018-02-26 14:14:12 +01:00
Thibault Delavallée 2238408d51 [REM] mail: remove unnecessary context switch in mail send method
Commit 0d3d0e9563 added a key in context when sending emails to know
the target model name. It was used at that time to forge for footer of
notification emails.

Since that time notification emails have evolved a lot. The code based on
that context key has been removed. Context key has been transformed into a
context switch. However it is not used anymore and can be removed. It allows
to clean a bit the code and save a context switch.

This commit is purely technical and does not hold any functional change.
Purpose is to clean code in order to prepare future changes in mail
application.

This commit allows to gain some queries in mail sending process, meaning
removing context switch is interesting. One query is gained when using
the send process. Complex performance test involving several message post
gain 3 queries each.
2018-02-26 14:14:10 +01:00
Thibault Delavallée 97ee12e9c7 [REF] mail: simplify parent fetch when posting a message
1d57a09112 added a two-steps parent fetch when posting a message
on a discussion thread. At the time this commit was done responsible were
notified of the first thread message. It was helpful to notify them of the
original email that created the thread instead of the "document created"
generic message. Indeed for documents like leads or issues having the
original email containing the customer question is interesting when being
notified. This is why this commit was done.

However since quite a long time responsible notifications have changed.
They now receive an email notification telling they have been assigned on
a document. This commit is not necessary anymore and we therefore remove
it in order to clean a bit the message_post process.

This commit globally reverts 1d57a09112. Please note that @beledouxdenis
agreed after a long thinking.

This commit has a slight impact on mail performance tests, allowing to save
one query in some more complex test case.
2018-02-26 14:11:32 +01:00
oco-odoo 60aa7596e5 [FIX] account, purchase: Recurrent vendor bills (#23320)
- set due date based on payment terms at generation for recurring bills
- do not generate "This vendor bill has been created form POXXX" for bills that have been generated by cron
2018-02-26 14:04:30 +01:00
qsm-odoo c254c4c684 [FIX] web_editor: stop crashing on applying fonts with standalone summernote
Commit https://github.com/odoo/odoo/commit/137c4f5d76b55c3dd3c4f593de484aadfcf5e6da?w=1#diff-6a334b274d95fb88a4fbc29b910fbb59R2120
introduced a bug as it is using a function which is defined in another
asset. This is fine for connected users but not for summernote-only
users like public users on the forum.

The reason the line was introduced is unsure so it is simply removed for
now. The bug it was supposed to fix will be fixed later if it ever needs
to be.
2018-02-26 12:58:28 +01:00
Aaron Bohy 034c075e7e [FIX] web: default_get returning unknown field
Before this rev., it crashed when trying to create records of the
res.users model. This is due to commit ad1cceb.

The 'default_get' of 'res.users' always returns a value for field
'groups_id', whereas the docstring of 'default_get' states that it
only returns default values for fields given in arguments.

Rev. ad1cceb changed a bit the way the result of 'default_get' was
processed, by iterating over the values instead of over the fields
in the view. So, before ad1cceb, 'groups_id' was simply ignored,
and after, the BasicModel tried to process it and it crashed when it
attempted to retrieve its fieldsInfo, as this field isn't in the
view.

This rev. restores the previous behavior.

Fixes #23303
Fixes #23305
2018-02-26 12:45:10 +01:00
Thibault Delavallée 74d4b3902d [REF] mail: consider body in message_post is always html
Purpose of this commit is to simplify a bit message_post API. It has
a content_subtype parameter allowing to receive plaintext content.
It is then automatically converted into html.

This commit removes the parameter and consider the content is always
html. Code calling message_post should handle the conversion. In Odoo
the only use was in the chat_post controller that now perform the
plaintext to html conversion before calling message_post.

This commit is purely technical and does not hold any functional change.
Purpose is to clean code in order to prepare future changes in mail
application.
2018-02-26 12:15:31 +01:00
Thibault Delavallée a6c187a01c [REM] mail, hr: remove old redirection when posting on users
Posting on users is not supported anymore. It was implemented in a time
we thought having a twitter-like behavior in Odoo was a good idea.
Posting on users was redirected on its related partner in mail. It was
redirected on its related employee in hr. It does not make sense anymore
as employee are records with limited access and partners used for other
purpose than discussing notably in accounting.

Now that we have chat channels it makes no sense to have this kind of
behavior still implemented. Let us remove it. No functional change
should occur with this commit.
2018-02-26 12:15:30 +01:00
Thibault Delavallée 1b5b2b9dd0 [FIX] mail: correctly propagate message_post parameters to redirection
Propagation was not correctly done at 8a026e26c6 . This commit
ensures all parameters are passed to sub-calls when redirection is done
in message_post.
2018-02-26 12:15:01 +01:00
Thibault Delavallée f6dd602530 [DOC] mail: update test performance counters
A test_mail only counter was not updated correctly after changes done
in user assignation notification (see a6e1324873).
2018-02-26 12:14:45 +01:00
jao-odoo 5d2c63bf49 [IMP] purchase_requisition : Remove field account_analytic_id from purchase requisition (#22910)
This field was already on the product lines.
2018-02-26 11:52:10 +01:00
Laurent Smet 5450c5c3f7 [IMP] account: allow partial reconciliation with write-off
Suppose you have an invoice of 3000. You want to pay with paypal
    3 x 1000 but having of fee of 10 in each transaction. So, you attempt
    to reconcile 3000 with 3 x (990 + 10) that is not possible with the
    reconciliation widget.

Was PR #17489. Was task: https://www.odoo.com/web#id=23384&view_type=form&model=project.task&action=333&active_id=967&menu_id=4720
opw-815421
2018-02-26 10:37:39 +01:00
Olivier Dony 12b15cb554 [FIX] website_mail_channel: fix P3 compatibility of comparison
`msg_more_count` can be undefined, and therefore evaluates to None, which
makes the comparison with 0 invalid in Python 3.
2018-02-26 09:23:44 +01:00
Alexandre Kühn 742ac28a44 [FIX] web: doAction always resolved with the action
Before this commit, doAction returns a deferred that is
resolved when the action is performed (the exact moment
depends of the type of the action).

However, the deferred was not resolved with the action.

This is misleading, hence a traceback in the web_client
when clicking on 'Run JS Tests' in debug mode (enterprise):
after doAction, the web_client should hide the home_menu
depending on the type of the action.

With this commit, any doAction returns a deferred that is
resolved with the performed action.
2018-02-26 09:16:00 +01:00
Nicolas Martinelli e2c2a2fc69 [FIX] mail: rotate image in preview
When uploading an image as attachment, the document viewer doesn't
support the EXIF data. Therefore, a picture taken with a non-zero angle
will not appear with the right orientation (preview or full-size image).

Unfortunately, supporting EXIF data is not trivial in Python or
JavaScript without external libraries. Therefore, we add a rotate button
which allows the user to rotate the image by 90°. Moreover, we add the
`image-orientation: from-image` CSS property, which is only supported by
Firefox.

opw-1814407
2018-02-26 08:24:08 +01:00
Aaron Bohy a16013be66 [FIX] web: multi pages ordered o2m with onchange
Let's assume a one2many displayed over several pages with a default
order such that a record, say R, that would normally be on page 1
is actually on another page. Moreover, there is an onchange on that
one2many which converts all commands 4 (LINK_TO) into commands 1
(UPDATE), which is standard in the ORM.

When the first line of the one2many was edited, the record R was
fully loaded, whereas it shouldn't have been (as it is not on the
current page). So basically, a useless read was performed.
Moreover, if there was an x2many field in the one2many list, a
crash occurred because relational data of R that shouldn't have
been read wasn't postprocessed by the BasicModel.

The useless read occurred because the one2many subrecords weren't
correctly sorted before checking if some of them/some of their
fields should be read. This is not the case anymore.

OPW-1816800
2018-02-26 08:14:08 +01:00
Joren Van Onder 5b769650d6 [FIX] point_of_sale: allow refunds on non-cash journals
A customer can pay an order with a non-cash journal (e.g. a credit
card through a stand-alone terminal).

When this order has to be refunded later it should be possible to do
so on that same journal.

Some code prevented this from happening, notably a check in
order_is_valid which explicitly prevented this for an unknown
reason. There is no explanation in the
commit (4647f896a4) introducing that.

This commit allows the following:

1. input what you want to refund with a negative qty
2. click 'Payment'
3. click the Credit Card (type Bank) journal
4. (amount is auto-populated)
5. click 'Validate'

opw-805302
2018-02-25 19:35:11 -08:00
Odoo Translation Bot 141a2acdd8 [I18N] Update translation terms from Transifex 2018-02-25 04:54:25 +01:00
Odoo Translation Bot 3535904bce [I18N] Update translation terms from Transifex 2018-02-25 01:38:10 +01:00
Romain Derie bc75ec7c14 [IMP] sale_coupon, website_sale_coupon: add tests
Commit a42c27f99e0061b7c4f recently fixed some bugs on sale_coupon.
This commit add some tests to be sure theses bugs are fixed and won't appear
again.

This closes #1744
2018-02-23 18:37:20 +01:00
Romain Derie 5db5f8e981 [IMP] sale_coupon, website_sale_coupon: add tests
Commit a42c27f99e0061b7c4f recently fixed some bugs on sale_coupon.
This commit add some tests to be sure theses bugs are fixed and won't appear
again.

This closes #1744
2018-02-23 18:37:20 +01:00
Romain Derie c69778fe6f [IMP] sale_coupon, website_sale_coupon: add tests
Commit a42c27f99e0061b7c4f recently fixed some bugs on sale_coupon.
This commit add some tests to be sure theses bugs are fixed and won't appear
again.

This closes #1744
2018-02-23 18:37:20 +01:00
Romain Derie d8ea1d04d5 [FIX] sale_coupon: fix some use cases
Some use cases were wrong, this commit attempt to fix those.
Here is the most important ones:

1. Discount was offered on free product 'value' aswell

Cart: 4 iPad Mini + one free offered + 10% discount

                      |    qty | unit value |   line total |
	----------------------------------------------------
	iPad Mini     |      4 |        320 |         1280 |
	- 10% discount|      1 |        128 |          128 |
	= 1152
	- free product|      1 |        320 |          320 |
	= 832

Should be

	              |    qty | unit value |   line total |
	----------------------------------------------------
	iPad Mini     |      4 |        320 |         1280 |
	- free product|      1 |        320 |          320 |
	= 960
	- 10% discount|      1 |         96 |           96 |
	= 864

The error result is $32 which is the 10% discount applied on the free iPad.

2. Decreasing product quantity below the minimum threshold to be elligible for
the promotion doesn't remove the product

  - (With a promotion offering a free iPad when you buy 3 (fourth is free))
  - Create a quotation with 3 iPads Mini, save and update promotions, you don't
    have a free one, which is 'correct'
  - Edit, change the quantity to 4 iPads, save, update promotions, you have a
    free iPad (reduced from total), still correct
  - Edit, change the quantity back to 3 ipad, update ptomotions, you still have
    a free iPad even if you only bought 3 of them (the way it is designed, the
    free iPad should only appears when you order your fourth).

The error result in a 'loss' of $320 since at the end we are offering a free
iPad and the user only pays 2 instead of 3.

3. Free product will be considered as regular product when updating quantity
of regular product afterward

This error is kind of exponential: the more you play with the flow explained
bellow, the more incorrect it becomes.

Buy 100 iPads, get 25 free iPads.
Then set quantity (on regular iPad) to 50, it will recalculate the amount of
free iPad thinking the 25 previous free iPads are regular iPad.
(50 + 25) = 75 regular iPads = 18 free iPads (25 previous free iPads were
wrongly used for the calculation but they are simply gone at this point).
Cart is now 50 regular iPads and 18 free one, total: $10240 (50×320 - 18×320).
It should be 12 free iPads, not 18, so $12160 (50×320 − 12×320)

The error result in a loss of $1920: ~ 20% of the total amount of the order.

This error will also appear the other way around if you add quantity instead of
removing some.
Playing with this error multiple times, you can arrive to a negative total
(more free than paid products), 0 total or very low total ($320 for 100 iPads).

4. Free product are wrongly calculated, user get too many of them

  - Create a quotation with 10 iPads, you get 3 free iPads instead of 2
  - Indeed, your first 4 iPads should give you a free one
  - Your next 4 iPads should give you a second one (you got 8)
  - The last 2 (to reach 10) are not enough to give you a third free iPad

The error result in a loss of $320 out of a total of 2560$ which is ~ 15%

5. Paid/regular products related to a promotion won't be taken into account
 when checking if you have the minimum amount threshold to apply the promotion

Promotion: 3 Computer Case(25$) = 1 Free Little Server (40.000$), auto applied
  -Have a cart with 3 'Computer Case' and 2 'Little Server'
  -One little server of the 2 is free (because you have 3 computer cases)
  -You so pay 3x25 + 1x40000 which is 40075$
  -Create a promo code that will give you 10% discount if you bought over $2000
  -You won't get the reduction even if you bought over $40.000 because the
   little server you pay is considered as the product of the reward product
   even if you dont have it free. It doesn't check how many regular product
   should be substracted according to the number of free product you have

6. Wrong product is checked for the required quantity to apply the promotion

Promotion: 3 iPads Mini ($320) = 1 free Bose Mini Bluetooth Speaker ($247)

  - Add 8 iPads Mini and a Bose Mini Bluetooth Speaker to your cart
  - The system should give you a free Bose Mini Bluetooth Speaker since you
    only have one regular Bose
  - But the system is giving you 2 free Bose Mini Bluetooth Speaker

Cart is: 8 iPad ($2560), 1 Bose ($247), 2 free Bose (-$496)
The system think that it should give you 2 free Bose because you are eligible
to, since you have 8 iPad, but it doesn't check that you have enough regular
Bose.

The error result in a loss of $247 out of a total of $2311

7. Auto applying promotion are not applied if there is already a promotion code
Promotion:
  - Free iPad Mini if you buy 3 (so the fourth become free), auto applied
  - 10% discount with code '10pc'

  - Add 4 iPads Mini, you got a free one
  - Set quantity back to 1 iPad, free one is gone
  - Add code 10pc, you got a 10% reduction line
  - Set quantity to 4 iPads again, you dont have the free iPad since there is
    already a promo code

This could make sense but it is not coherent since the 2 promotions would be
applied if they were both on auto apply mode.
Note:
  - If both promotions are on auto apply, you will get both
  - If 10% discount becomes auto applied and iPad promotion now has a code
    (reverse situation) it will work

8. Discount is only applied on untaxed amount, not on tax

Discount will ONLY be calculated on the untaxed amount and then reduced from
the sale order/cart total.
The taxes would be unchanged and charged like the product was full price.

Let's illustrate with a $100 product, a 15% tax and a 20% discount:

1. Tax included:
$100   : Product with 15% included taxes
$86.96 : Untaxed product
$13.04 : Taxes

After aplying 20% discount, result should be:
$80    : Product with 15% included taxes
$69.57 : Untaxed product
$10.43 : Taxes

Instead we have:
$82.61 : Product with 15% included taxes
$69.57 : Untaxed product
$13.04 : Taxes

There is a difference of $2.61 which is the result of the taxes not being
discounted: 13.04-10.43 = 2.61

2. Tax excluded:
$115 : Product with 15% excluded taxes
$100 : Untaxed product
$15  : Taxes

After aplying 20% discount, result should be:
$92  : Product with 15% included taxes
$80  : Untaxed product
$12  : Taxes

Instead we have:
$95  : Product with 15% included taxes
$80  : Untaxed product
$15  : Taxes

There is a difference of $3 which is the result of the taxes not being
discounted: 15-12 = 3

9. Taxes of the free shipping reward would be considered as paid value when
checking if required threshold is met.

------------------------------------------

Not really a bug, more an improvement:

1. The way it was designed, the rule_minimum_amount would check if your order
amount was over the required threshold to be eligible for the reward.
'Problem' is that it your order has already a discount (eg: 10%), it would
check if the price without discount is above the required amount.
I don't think it is coherent, let's illustrate:
  - First pomotion (auto applied): 1 iPad Mini for free if you buy over $2000
  - Second promotion (auto applied): 50% on order

If an user is buying for $2000, he is actually paying $1000 thanks to the 50%
discount.
Should we give him the free iPad?
The current implementation is giving it, which is not convenient IMHO.
Now, we use the amount the user really pay to check if he is elligible.

2. Since new promotions have the same sequence by default, they will be sorted
and applied by their creation order. This will result in inconsistent behavior:
  - Promotion 1 : 10% discount
  - Promotion 2 : free shipping
  - Both promotion are auto applied and need a minimum of $872.73 tax excluded

Let's illustrate with a $873 order:
If the promotions were created in the order above, you won't get both rewards
since the 10% discount will be applied first and will lower the SO total.
The order will then fall below the $872.73 required amount and won't be
eligible for the free shipping.
But if you created the free shipping promotion before the discount one, you
will be eligible for both since the free shipping will be applied first and
won't change the SO total.

To keep the same behavior independently of the promotion creation order, we now
sort by reward_type ('discount' > 'free_shipping' > 'product' to apply
discounts first.
This is better IMHO, since you want to give promotions with a minimum threshold
ONLY if the user really pays that amount. It wouldn't be the case if the total
is checked before the discount is applied.
2018-02-23 18:36:19 +01:00
Romain Derie ef5d056403 [FIX] sale_coupon: fix some use cases
Some use cases were wrong, this commit attempt to fix those.
Here is the most important ones:

1. Discount was offered on free product 'value' aswell

Cart: 4 iPad Mini + one free offered + 10% discount

                      |    qty | unit value |   line total |
	----------------------------------------------------
	iPad Mini     |      4 |        320 |         1280 |
	- 10% discount|      1 |        128 |          128 |
	= 1152
	- free product|      1 |        320 |          320 |
	= 832

Should be

	              |    qty | unit value |   line total |
	----------------------------------------------------
	iPad Mini     |      4 |        320 |         1280 |
	- free product|      1 |        320 |          320 |
	= 960
	- 10% discount|      1 |         96 |           96 |
	= 864

The error result is $32 which is the 10% discount applied on the free iPad.

2. Decreasing product quantity below the minimum threshold to be elligible for
the promotion doesn't remove the product

  - (With a promotion offering a free iPad when you buy 3 (fourth is free))
  - Create a quotation with 3 iPads Mini, save and update promotions, you don't
    have a free one, which is 'correct'
  - Edit, change the quantity to 4 iPads, save, update promotions, you have a
    free iPad (reduced from total), still correct
  - Edit, change the quantity back to 3 ipad, update ptomotions, you still have
    a free iPad even if you only bought 3 of them (the way it is designed, the
    free iPad should only appears when you order your fourth).

The error result in a 'loss' of $320 since at the end we are offering a free
iPad and the user only pays 2 instead of 3.

3. Free product will be considered as regular product when updating quantity
of regular product afterward

This error is kind of exponential: the more you play with the flow explained
bellow, the more incorrect it becomes.

Buy 100 iPads, get 25 free iPads.
Then set quantity (on regular iPad) to 50, it will recalculate the amount of
free iPad thinking the 25 previous free iPads are regular iPad.
(50 + 25) = 75 regular iPads = 18 free iPads (25 previous free iPads were
wrongly used for the calculation but they are simply gone at this point).
Cart is now 50 regular iPads and 18 free one, total: $10240 (50×320 - 18×320).
It should be 12 free iPads, not 18, so $12160 (50×320 − 12×320)

The error result in a loss of $1920: ~ 20% of the total amount of the order.

This error will also appear the other way around if you add quantity instead of
removing some.
Playing with this error multiple times, you can arrive to a negative total
(more free than paid products), 0 total or very low total ($320 for 100 iPads).

4. Free product are wrongly calculated, user get too many of them

  - Create a quotation with 10 iPads, you get 3 free iPads instead of 2
  - Indeed, your first 4 iPads should give you a free one
  - Your next 4 iPads should give you a second one (you got 8)
  - The last 2 (to reach 10) are not enough to give you a third free iPad

The error result in a loss of $320 out of a total of 2560$ which is ~ 15%

5. Paid/regular products related to a promotion won't be taken into account
 when checking if you have the minimum amount threshold to apply the promotion

Promotion: 3 Computer Case(25$) = 1 Free Little Server (40.000$), auto applied
  -Have a cart with 3 'Computer Case' and 2 'Little Server'
  -One little server of the 2 is free (because you have 3 computer cases)
  -You so pay 3x25 + 1x40000 which is 40075$
  -Create a promo code that will give you 10% discount if you bought over $2000
  -You won't get the reduction even if you bought over $40.000 because the
   little server you pay is considered as the product of the reward product
   even if you dont have it free. It doesn't check how many regular product
   should be substracted according to the number of free product you have

6. Wrong product is checked for the required quantity to apply the promotion

Promotion: 3 iPads Mini ($320) = 1 free Bose Mini Bluetooth Speaker ($247)

  - Add 8 iPads Mini and a Bose Mini Bluetooth Speaker to your cart
  - The system should give you a free Bose Mini Bluetooth Speaker since you
    only have one regular Bose
  - But the system is giving you 2 free Bose Mini Bluetooth Speaker

Cart is: 8 iPad ($2560), 1 Bose ($247), 2 free Bose (-$496)
The system think that it should give you 2 free Bose because you are eligible
to, since you have 8 iPad, but it doesn't check that you have enough regular
Bose.

The error result in a loss of $247 out of a total of $2311

7. Auto applying promotion are not applied if there is already a promotion code
Promotion:
  - Free iPad Mini if you buy 3 (so the fourth become free), auto applied
  - 10% discount with code '10pc'

  - Add 4 iPads Mini, you got a free one
  - Set quantity back to 1 iPad, free one is gone
  - Add code 10pc, you got a 10% reduction line
  - Set quantity to 4 iPads again, you dont have the free iPad since there is
    already a promo code

This could make sense but it is not coherent since the 2 promotions would be
applied if they were both on auto apply mode.
Note:
  - If both promotions are on auto apply, you will get both
  - If 10% discount becomes auto applied and iPad promotion now has a code
    (reverse situation) it will work

8. Discount is only applied on untaxed amount, not on tax

Discount will ONLY be calculated on the untaxed amount and then reduced from
the sale order/cart total.
The taxes would be unchanged and charged like the product was full price.

Let's illustrate with a $100 product, a 15% tax and a 20% discount:

1. Tax included:
$100   : Product with 15% included taxes
$86.96 : Untaxed product
$13.04 : Taxes

After aplying 20% discount, result should be:
$80    : Product with 15% included taxes
$69.57 : Untaxed product
$10.43 : Taxes

Instead we have:
$82.61 : Product with 15% included taxes
$69.57 : Untaxed product
$13.04 : Taxes

There is a difference of $2.61 which is the result of the taxes not being
discounted: 13.04-10.43 = 2.61

2. Tax excluded:
$115 : Product with 15% excluded taxes
$100 : Untaxed product
$15  : Taxes

After aplying 20% discount, result should be:
$92  : Product with 15% included taxes
$80  : Untaxed product
$12  : Taxes

Instead we have:
$95  : Product with 15% included taxes
$80  : Untaxed product
$15  : Taxes

There is a difference of $3 which is the result of the taxes not being
discounted: 15-12 = 3

9. Taxes of the free shipping reward would be considered as paid value when
checking if required threshold is met.

------------------------------------------

Not really a bug, more an improvement:

1. The way it was designed, the rule_minimum_amount would check if your order
amount was over the required threshold to be eligible for the reward.
'Problem' is that it your order has already a discount (eg: 10%), it would
check if the price without discount is above the required amount.
I don't think it is coherent, let's illustrate:
  - First pomotion (auto applied): 1 iPad Mini for free if you buy over $2000
  - Second promotion (auto applied): 50% on order

If an user is buying for $2000, he is actually paying $1000 thanks to the 50%
discount.
Should we give him the free iPad?
The current implementation is giving it, which is not convenient IMHO.
Now, we use the amount the user really pay to check if he is elligible.

2. Since new promotions have the same sequence by default, they will be sorted
and applied by their creation order. This will result in inconsistent behavior:
  - Promotion 1 : 10% discount
  - Promotion 2 : free shipping
  - Both promotion are auto applied and need a minimum of $872.73 tax excluded

Let's illustrate with a $873 order:
If the promotions were created in the order above, you won't get both rewards
since the 10% discount will be applied first and will lower the SO total.
The order will then fall below the $872.73 required amount and won't be
eligible for the free shipping.
But if you created the free shipping promotion before the discount one, you
will be eligible for both since the free shipping will be applied first and
won't change the SO total.

To keep the same behavior independently of the promotion creation order, we now
sort by reward_type ('discount' > 'free_shipping' > 'product' to apply
discounts first.
This is better IMHO, since you want to give promotions with a minimum threshold
ONLY if the user really pays that amount. It wouldn't be the case if the total
is checked before the discount is applied.
2018-02-23 18:36:19 +01:00
Romain Derie 6d25671bb3 [FIX] website_sale_coupon: new class for product results
For the tests on coupon on enterprise, there is a need of a new class to wait
search results to be loaded, or it would click on the /shop product instead of
waiting, resulting in a conccurent update error.

This closes #22263
2018-02-23 18:35:20 +01:00
Christophe Simonis 9a1d71ce95 [MERGE] forward port branch saas-14 up to d8e45489cd 2018-02-23 18:25:03 +01:00