- Aug 01, 2019
-
-
Meghna Jaswani authored
- Update the CoA for 2020 - Add the most recent monthly tax report instead of the old one with the new tax model - Base language English (multilang translation in fr and de) hsh and rgo co-authored opw-1917932 closes odoo/odoo#35371 Signed-off-by:
Josse Colpaert <jco@openerp.com>
-
Robot Odoo authored
1/ Improve res.partner search for customers/suppliers ========================================= Purpose ------- This commit allows to call `name_search` with context key `res_partner_search_mode` that can take currently two values: "customer" or "supplier". When ordering search results, order partners by the number of SO they have when the value is "customer" and by the number of PO if the value is "supplier". Top suppliers/customers are displayed above in a PO/SO partner dropdown. We have thought about different implementations before selecting this one: - Keep the 2 boolean flags and automatically set them if a SO or PO is created for a customer/supplier (helps a bit but doesn't work well for the first SO/PO). As the onboarding is also a priority, we didn't implement it. - Instead of filtering on the bool flags, sort the name_search() result according to the number of orders they already have (e.g. if you search for "Foo" on a PO, a supplier "SuperFoo" with 32 purchase orders will appear before supplier "HorribleFoo" that has no PO). Problem is to do this in an efficient manner for large databases - possibly we could store a "relevance index" based on the number of recent orders. Storing those values is an issue too, as it doesn't work well for multi company database. Indeed, storing values that depend on the context is certainly not a good idea. - Same as previous alternative but with no stored columns, rather a JOIN in name_search. This is the solution that have been kept. The only concern was about the perfomances. We tested it on our production base, on a sales order, as we have way much more customers than suppliers. After a deep analysis on the querry and the bitmap generated by PostgreSQL, we can conclude that the count(*) works rather efficiently and that the request is not significantly heavier than without the context key. Performance Analysis -------------------- The following results have been obtained on our production database. ### Before this commit ### The original query is the following one: ``` EXPLAIN ANALYSE SELECT res_partner.id FROM "res_partner" WHERE ("res_partner"."customer" = True) AND ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap ORDER BY res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; ``` Here is the EXPLAIN ANALYSE returned by PostgreSQL: ``` Limit (cost=1625.50..1625.52 rows=8 width=21) (actual time=13.397..13.404 rows=8 loops=1) -> Sort (cost=1625.50..1626.32 rows=326 width=21) (actual time=13.395..13.396 rows=8 loops=1) Sort Key: (((display_name)::text ~~* '%eezee-i%'::text)) DESC, display_name Sort Method: top-N heapsort Memory: 26kB -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.98 rows=326 width=21) (actual time=13.025..13.350 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (customer AND active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=12.983..12.983 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=5.022..5.022 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.128..4.128 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=2.240..2.240 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.585..1.585 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) Planning time: 0.766 ms Execution time: 13.489 ms ``` ### After this commit ### Without the context key, the query looks like this: ``` SELECT res_partner.id FROM "res_partner" WHERE ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap GROUP BY res_partner.id ORDER BY COUNT(*) DESC, res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; ``` And it quite clear when looking at the EXPLAIN ANALYSE that the request is quite the same, except the aggregation that is made with a quicksort method. ``` Limit (cost=1645.00..1645.02 rows=8 width=29) (actual time=13.200..13.206 rows=8 loops=1) -> Sort (cost=1645.00..1645.82 rows=328 width=29) (actual time=13.197..13.198 rows=8 loops=1) Sort Key: (count(*)) DESC, (((display_name)::text ~~* '%eezee-i%'::text)) DESC, display_name Sort Method: top-N heapsort Memory: 26kB -> GroupAggregate (cost=1631.88..1638.44 rows=328 width=29) (actual time=13.090..13.160 rows=56 loops=1) Group Key: id -> Sort (cost=1631.88..1632.70 rows=328 width=20) (actual time=13.080..13.084 rows=56 loops=1) Sort Key: id Sort Method: quicksort Memory: 29kB -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.17 rows=328 width=20) (actual time=12.793..13.055 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=12.755..12.755 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.823..4.823 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=3.941..3.941 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=2.186..2.186 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.798..1.798 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) Planning time: 0.761 ms Execution time: 13.317 ms ``` With the context key, the query looks like this: ``` EXPLAIN ANALYSE SELECT res_partner.id FROM "res_partner" LEFT JOIN sale_order ON res_partner.id = sale_order.partner_id WHERE ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap GROUP BY res_partner.id ORDER BY COUNT(*) DESC, res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; ``` The only difference is that a nested loop is made for the left join, as postgreSQL has correctly identified the dicriminating table. The correct result is obtained within a similar duration. ``` Limit (cost=2700.68..2700.70 rows=8 width=29) (actual time=12.561..12.568 rows=8 loops=1) -> Sort (cost=2700.68..2701.50 rows=328 width=29) (actual time=12.559..12.560 rows=8 loops=1) Sort Key: (count(*)) DESC, (((res_partner.display_name)::text ~~* '%eezee-i%'::text)) DESC, res_partner.display_name Sort Method: top-N heapsort Memory: 26kB -> GroupAggregate (cost=2687.56..2694.12 rows=328 width=29) (actual time=12.449..12.527 rows=56 loops=1) Group Key: res_partner.id -> Sort (cost=2687.56..2688.38 rows=328 width=20) (actual time=12.408..12.425 rows=305 loops=1) Sort Key: res_partner.id Sort Method: quicksort Memory: 42kB -> Nested Loop Left Join (cost=1283.21..2673.86 rows=328 width=20) (actual time=11.629..12.340 rows=305 loops=1) -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.17 rows=328 width=20) (actual time=11.596..11.862 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=11.560..11.560 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.724..4.724 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=3.825..3.825 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=1.752..1.752 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.254..1.254 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) -> Index Only Scan using sale_order_partner_id_index on sale_order (cost=0.42..2.74 rows=48 width=4) (actual time=0.006..0.007 rows=5 loops=56) Index Cond: (partner_id = res_partner.id) Heap Fetches: 12 Planning time: 1.056 ms Execution time: 13.791 ms ``` 2/ Remove customer and supplier fields from res.partner =========================================== Purpose ------- Fields `customer` and `supplier` on `res.partner` are mostly used in domains of many2x fields. Those domains can confuse end users because they don't see the partner they are looking for; and it's not obvious why. Some identified problems: 1. It can lead to duplicated partners: the user does not find the partner, so he creates a new one. 2. The user imports supplier contacts in the Contacts app, so they don't get the `supplier` flag. Then the user wants to make a purchase order, and cannot find the new suppliers in the list 3. A user removes the customer flag on a prospect, because they don't think it's a customer yet - except now they can't make a quote for that customer... Specification ------------- Remove the two mentioned fields. Since fields `customer` and `supplier` have been removed, all partners are now shown in many2one dropdowns. But in some cases, not all partners are relevant or some are more likely to be relevant than others. e.g. when creating a PO, top suppliers have a higher priority than other partners. So, adapt the places where those fields were used with the new mechanism to display the searched the partners, according to the number purchase/sales orders they made. TaskID: 2031147 closes odoo/odoo#34524 Signed-off-by:
Yannick Tivisse (yti) <yti@odoo.com> Co-authored-by:
Yannick Tivisse <yti@odoo.com>
-
Lucas Lefèvre authored
Purpose ======= Fields `customer` and `supplier` on `res.partner` are mostly used in domains of many2x fields. Those domains can confuse end users because they don't see the partner they are looking for; and it's not obvious why. Some identified problems: 1. It can lead to duplicated partners: the user does not find the partner, so he creates a new one. 2. The user imports supplier contacts in the Contacts app, so they don't get the `supplier` flag. Then the user wants to make a purchase order, and cannot find the new suppliers in the list 3. A user removes the customer flag on a prospect, because they don't think it's a customer yet - except now they can't make a quote for that customer... Specification ============= Remove the two mentioned fields. Since fields `customer` and `supplier` have been removed, all partners are now shown in many2one dropdowns. But in some cases, not all partners are relevant or some are more likely to be relevant than others. e.g. when creating a PO, top suppliers have a higher priority than other partners. So, adapt the places where those fields were used with the new mechanism to display the searched the partners, according to the number purchase/sales orders they made. TaskID: 2031147 Co-authored-by:
Yannick Tivisse <yti@odoo.com>
-
Lucas Lefèvre authored
This commit allows to call `name_search` with context key `res_partner_search_mode` that can take currently two values: "customer" or "supplier". When ordering search results, order partners by the number of SO they have when the value is "customer" and by the number of PO if the value is "supplier". Top suppliers/customers are displayed above in a PO/SO partner dropdown. We have thought about different implementations before selecting this one: - Keep the 2 boolean flags and automatically set them if a SO or PO is created for a customer/supplier (helps a bit but doesn't work well for the first SO/PO). As the onboarding is also a priority, we didn't implement it. - Instead of filtering on the bool flags, sort the name_search() result according to the number of orders they already have (e.g. if you search for "Foo" on a PO, a supplier "SuperFoo" with 32 purchase orders will appear before supplier "HorribleFoo" that has no PO). Problem is to do this in an efficient manner for large databases - possibly we could store a "relevance index" based on the number of recent orders. Storing those values is an issue too, as it doesn't work well for multi company database. Indeed, storing values that depend on the context is certainly not a good idea. - Same as previous alternative but with no stored columns, rather a JOIN in name_search. This is the solution that have been kept. The only concern was about the perfomances. We tested it on our production base, on a sales order, as we have way much more customers than suppliers. After a deep analysis on the querry and the bitmap generated by PostgreSQL, we can conclude that the count(*) works rather efficiently and that the request is not significantly heavier than without the context key. Performance Analysis ==================== The following results have been obtained on our production database. Before this commit ------------------ The original query is the following one: ``` EXPLAIN ANALYSE SELECT res_partner.id FROM "res_partner" WHERE ("res_partner"."customer" = True) AND ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap ORDER BY res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; ``` Here is the EXPLAIN ANALYSE returned by PostgreSQL: ``` Limit (cost=1625.50..1625.52 rows=8 width=21) (actual time=13.397..13.404 rows=8 loops=1) -> Sort (cost=1625.50..1626.32 rows=326 width=21) (actual time=13.395..13.396 rows=8 loops=1) Sort Key: (((display_name)::text ~~* '%eezee-i%'::text)) DESC, display_name Sort Method: top-N heapsort Memory: 26kB -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.98 rows=326 width=21) (actual time=13.025..13.350 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (customer AND active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=12.983..12.983 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=5.022..5.022 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.128..4.128 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=2.240..2.240 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.585..1.585 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) Planning time: 0.766 ms Execution time: 13.489 ms ``` After this commit ----------------- Without the context key, the query looks like this: ``` SELECT res_partner.id FROM "res_partner" WHERE ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap GROUP BY res_partner.id ORDER BY COUNT(*) DESC, res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; And it quite clear when looking at the EXPLAIN ANALYSE that the request is quite the same, except the aggregation that is made with a quicksort method. Limit (cost=1645.00..1645.02 rows=8 width=29) (actual time=13.200..13.206 rows=8 loops=1) -> Sort (cost=1645.00..1645.82 rows=328 width=29) (actual time=13.197..13.198 rows=8 loops=1) Sort Key: (count(*)) DESC, (((display_name)::text ~~* '%eezee-i%'::text)) DESC, display_name Sort Method: top-N heapsort Memory: 26kB -> GroupAggregate (cost=1631.88..1638.44 rows=328 width=29) (actual time=13.090..13.160 rows=56 loops=1) Group Key: id -> Sort (cost=1631.88..1632.70 rows=328 width=20) (actual time=13.080..13.084 rows=56 loops=1) Sort Key: id Sort Method: quicksort Memory: 29kB -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.17 rows=328 width=20) (actual time=12.793..13.055 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=12.755..12.755 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.823..4.823 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=3.941..3.941 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=2.186..2.186 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.798..1.798 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) Planning time: 0.761 ms Execution time: 13.317 ms ``` With the context key, the query looks like this: ``` EXPLAIN ANALYSE SELECT res_partner.id FROM "res_partner" LEFT JOIN sale_order ON res_partner.id = sale_order.partner_id WHERE ("res_partner"."active" = True) AND ((("res_partner"."type" != 'private') OR "res_partner"."type" IS NULL) OR "res_partner"."type" IS NULL ) AND (res_partner.email ilike '%eezee-i%' OR res_partner.display_name ilike '%eezee-i%' OR res_partner.ref ilike '%eezee-i%' OR res_partner.vat ilike '%eezeei%') -- don't panic, trust postgres bitmap GROUP BY res_partner.id ORDER BY COUNT(*) DESC, res_partner.display_name ilike '%eezee-i%' desc, res_partner.display_name limit 8; ``` The only difference is that a nested loop is made for the left join, as postgreSQL has correctly identified the dicriminating table. The correct result is obtained within a similar duration. ``` Limit (cost=2700.68..2700.70 rows=8 width=29) (actual time=12.561..12.568 rows=8 loops=1) -> Sort (cost=2700.68..2701.50 rows=328 width=29) (actual time=12.559..12.560 rows=8 loops=1) Sort Key: (count(*)) DESC, (((res_partner.display_name)::text ~~* '%eezee-i%'::text)) DESC, res_partner.display_name Sort Method: top-N heapsort Memory: 26kB -> GroupAggregate (cost=2687.56..2694.12 rows=328 width=29) (actual time=12.449..12.527 rows=56 loops=1) Group Key: res_partner.id -> Sort (cost=2687.56..2688.38 rows=328 width=20) (actual time=12.408..12.425 rows=305 loops=1) Sort Key: res_partner.id Sort Method: quicksort Memory: 42kB -> Nested Loop Left Join (cost=1283.21..2673.86 rows=328 width=20) (actual time=11.629..12.340 rows=305 loops=1) -> Bitmap Heap Scan on res_partner (cost=1282.79..1618.17 rows=328 width=20) (actual time=11.596..11.862 rows=56 loops=1) Recheck Cond: (((email)::text ~~* '%eezee-i%'::text) OR ((display_name)::text ~~* '%eezee-i%'::text) OR ((ref)::text ~~* '%eezee-i%'::text) OR ((vat)::text ~~* '%eezeei%'::text)) Rows Removed by Index Recheck: 1 Filter: (active AND (((type)::text <> 'private'::text) OR (type IS NULL) OR (type IS NULL))) Rows Removed by Filter: 1 Heap Blocks: exact=58 -> BitmapOr (cost=1282.79..1282.79 rows=328 width=0) (actual time=11.560..11.560 rows=0 loops=1) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=4.724..4.724 rows=54 loops=1) Index Cond: ((email)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..322.22 rows=162 width=0) (actual time=3.825..3.825 rows=56 loops=1) Index Cond: ((display_name)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..321.00 rows=1 width=0) (actual time=1.752..1.752 rows=0 loops=1) Index Cond: ((ref)::text ~~* '%eezee-i%'::text) -> Bitmap Index Scan on res_partner_name_tgm_idx_gin (cost=0.00..317.03 rows=4 width=0) (actual time=1.254..1.254 rows=0 loops=1) Index Cond: ((vat)::text ~~* '%eezeei%'::text) -> Index Only Scan using sale_order_partner_id_index on sale_order (cost=0.42..2.74 rows=48 width=4) (actual time=0.006..0.007 rows=5 loops=56) Index Cond: (partner_id = res_partner.id) Heap Fetches: 12 Planning time: 1.056 ms Execution time: 13.791 ms ``` TaskID: 2031147 Co-authored-by:
Yannick Tivisse <yti@odoo.com>
-
Robot Odoo authored
Instead, make sure the field src is always up to date Change a bit the behaviour of `_write` to always try to update potential translations when in monolanguage (was only done in multi-language if different than en_US) and always create translations when writing on a translatable field when in multi-language (was skipped in en_US) Add tests Task-id: 2031752 Pad: https://pad.odoo.com/p/r.dbf835d0aae979d858f73446dcbfb1df closes odoo/odoo#34598 Signed-off-by:
Martin Trigaux (mat) <mat@odoo.com>
-
Martin Trigaux authored
If a db is in single lang (en_US or not) but still has translations, the translation should be updated in addition to updating the referenced record Add tests to formalise the expected behaviour: If one language only (en_US or not), when writing on a translatable field: - record field should updated - value of potential existing en_US translation should be updated - src of potential existing translations should be updated - no new translation should be created If en_US and fr_FR, when writing on a translatable field in en_US: - record field should updated - value of potential existing en_US translation should be updated - src of potential existing translations should be updated - new en_US translation should be created if was not present If en_US and fr_FR, when writing on a translatable field in fr_FR: - record field should not be updated - value of potential existing fr_FR translation should be updated - src of potential existing translations should not be updated - new fr_FR translation should be created if was not present Adapt test_new_api test get_installed is ormcached, just putting active = True is not enough
-
Martin Trigaux authored
Instead, make sure the field src is always up to date Add tests Changes in _write: - Replace _set_ids (to be deprecated) call by _upsert_translations as it works in batch - Call _upsert_translations for any language, including en_US In case an English translation already existed for a record, only the master value (on the reference record) was updated but the user kept seeing the translation value (was revealed 73a7534b). - Read src_trans without language Similar as above, if an English translation already existed, the translation was used for the result of the read and not the new value that has just been inserted into the database - Add _set_source method When updating a master record of a translated field, the src field must be updated, including in different languages. Before it was ok that the src field was out of date as the source was computed Changes in copy_translation: - set src as the new value without lang update the comment to reflect reality since 489494e7 src will contain the English version if no changes were made and it will contain the modified value if copy was overriden Changes in upsert_translations: - Do not force a module, comment, state Only src, res_id, name, value and lang must be given. Optional values will no longer be set to null if not given
-
- Jul 29, 2019
-
-
Naglis Jonaitis authored
Since this is a website template, the `context` does not make much sense. Additionally, there is no search filter named `web_features`. Lastly, the action opened via this link already has a default search filter enabled [1]. [1]: https://github.com/odoo/odoo/blob/81f024b545c8ddeeed040fcde42db3f5f7e2a468/addons/website/views/website_views.xml#L17 closes odoo/odoo#35275 Signed-off-by:
Jérémy Kersten (jke) <jke@openerp.com>
-
- Jul 31, 2019
-
-
Simon Lejeune authored
This class referenced demo data but even if they weren't installed, the tests were passing. Remove the definition and usages. closes odoo/odoo#35343 Signed-off-by:
Simon Lejeune (sle) <sle@openerp.com>
-
wan authored
Reproduce: 1. I create a product with fifo and real_time valuation (make sure the invoicing policy is 'delivered' and make it available in pos). 2. set the cost of the product to be 5.0 and sale price to be 10.0. 3. I update its inventory and set 5 items. -> total valuation of 25. 4. I change the cost of the product to 1.0. 5. I update again the quantity to 10, making the valuation of the product to 30.0. 6. I configure point of sale to allow invoicing. 7. Open a pos session then sell 7 items of the product (invoice the order). 8. Since the product is fifo, this means that the cost of goods sold is 5 * 5.0 + 2 * 1.0 = 27.0. 9. The correct expense account line should have balance of 27.0. 10. The correct output account line should have balance of -27.0 However, instead of 27.0 as stock valuation amount, the value in the pos.order invoice is currently 7 * 2.0 = 14 -- and this is wrong. It is not taking into account the value of the previous stock Solution: Missing refactoring from https://github.com/odoo/odoo/commit/14812f41710282f9923078f6764323086500ae85 closes odoo/odoo#35335 Signed-off-by:
Simon Lejeune (sle) <sle@openerp.com>
-
- Jul 30, 2019
-
-
Xavier-Do authored
Since #34996, in some case, the error detail was not logged keeping only the final summary "x errors, x failures" when running TestSuite. Making fail test test_cache_invalidation for instance won't show a detailed message when breaking test_01_project_tour will. This issue occurs when using subtest, like with assertQueryCount, @users decorator, test_all_l10n, and test_youtube_urls. Since Testresult addSubTest append directly to error and failures instead of calling addError and addFailure, we need to ovewrite addSubtest too. closes odoo/odoo#35270 Signed-off-by:
Denis Ledoux <beledouxdenis@users.noreply.github.com>
-
- Jul 31, 2019
-
-
Nathan de Pryck authored
The "company_id" fields for the iap account has been changed by the "company_ids" fields to allow the use of an iap account with multiple company. closes odoo/odoo#35093 Signed-off-by:
Rémi Rahir (rar) <rar@odoo.com>
-
svs-odoo authored
Before this commit, you can delete only canceled MO. Now, if you want to delete a non-canceled MO, it will try to cancel it then to unlink it. Task #1969034 closes odoo/odoo#34026 Signed-off-by:
Arnold Moyaux <amoyaux@users.noreply.github.com>
-
Arnold Moyaux authored
Usecase: - Set table top as manufacture and MTO - Create a MO for table(MTO) - Confirm the MO - Cancel the MO The activity with the exception is not logged on the child MO It happens because the _get_upstream_documents_and_responsible for move linked to a MO is based on the created_production_id field. However it is only set on the move that created the move_finished_ids for the new MO. In the case of a MO that directly create a child MO the chain is: MO -> move_raw_ids -> move_finished_ids -> MO2 The log_activity on cancel is based on the move_raw_ids and their move_orig_ids in the previous case it's the move_finished_ids for MO2. However the move_finished_ids for MO2 is directly link to the child MO and the created_production_id is set on the move_raw_ids for MO parent. Compare to PO, we could directly base the parent document on production_id since the move_finished_ids are directly created.
-
svs-odoo authored
Manufacturing Order can now be cancelled even if some move lines or Work Orders are done (in this case, a wizard ask confirmation to the user). Task #1969034 Co-authored-by:
Arnold Moyaux <arm@odoo.com>
-
pha-odoo authored
Using path such as '/dev/ttyUSB0' to connect to a serial port makes it impossible to use the bluetooth. We now use the locations in '/dev/serial/by-path' to connect to serial port, which does not affect bluetooth connections closes odoo/odoo#35302 Signed-off-by:
Quentin Lejeune (qle) <qle@odoo.com>
-
Pierre Rousseau authored
Before this commit, the tooltip message for the credits lacks clarity when making a request for companies and contacts. The sentence 'making a total of X credits for this request' was only the total of the credits for the contacts, without the credits for the companies. Now, the tooltip is clearer, the total takes into account the credits for the companies and the contacts. Task-ID 2036946 closes odoo/odoo#35049 Signed-off-by:
Rémi Rahir (rar) <rar@odoo.com>
-
- Jul 29, 2019
-
-
Hardik Prajapati authored
the KID number is base on invoice and payment the KID number control digit is calculated from the MOD10 (luan) the last digit in the KID number is a control digit. task-1969040 closes #33779 Signed-off-by:
Josse Colpaert <jco@openerp.com>
-
- Jul 31, 2019
-
-
Patrick Hoste authored
Adds two stats button on res.partner form view : - The first one will show all the courses that the partner is following. - The second one will show all the certifications the partner has passed. When the partner is a company : - All the courses followed by all the partners are shown without duplicate. - All the certifications passed by all the partners are shown. PR : #34908 Task ID : 2034097 Signed-off-by:
Thibault Delavallee (tde) <tde@openerp.com>
-
qmo-odoo authored
This commit changes the method _get_default_team_id so that it removes the xmlid reference to the default team. Instead, we will now use the team sequence (with default team's sequence being set as 1) and falling back to the next team with the highest sequence if the default team got deleted. Therefore, teams will now be ordered by sequence instead of name, allowing the users to reorder their teams as they see fit This commit also removes useless sudo when searching teams Task: #1962182 PR: #32372 wip Signed-off-by:
Thibault Delavallee (tde) <tde@openerp.com>
-
- Jul 30, 2019
-
-
qmo-odoo authored
This commit improves the ux in CRM by changing a few things: - Restore the use_leads and use_quotations fields along with their features as they were in 12.0. - Hide the email alias if use_upportunities and use_leads are unchecked. - Show a link to the general settings instead of the alias_domain if no alias_domain has been configured. - fixes the "unassigned lead(s)" link so that it redirects the user to the actually unassigned leads Task: #1962182 PR: #32372
-
- Jul 31, 2019
-
-
qmo-odoo authored
This commit adds the number of comments on the comments tab and also improves the design of the pdf sharing options Task: 1978736 PR: #34232 Signed-off-by:
Thibault Delavallee (tde) <tde@openerp.com>
-
qmo-odoo authored
This commit improves the user experience in the slide.slide form view by reorganizing fields, renaming fields and hiding unnecessary fields. This commit also introduces two new fields: - comment_count: computed field that gets the number of comments on the slide - channel_allow_comment: Related field to the channel_id.allow_coment. This field is used to hide/show unnecessary fields TaskID: 1978736 PR: #34232
-
Robot Odoo authored
* gamification, website_forum, stock Fix for: https://github.com/odoo/odoo/pull/32132 Some problems with the mentioned PR had to be fixed and after some discussions, it was decided to revert back to the original crashmanager warnings for the backend. See sub-commits for details. closes odoo/odoo#35209 Signed-off-by:
Quentin Smetz (qsm) <qsm@odoo.com>
-
Arnold Moyaux authored
The purpose of quiet parameter is to return a barcode image without left and right margins. It could be usefull on report where the barcode size should be minize or align to another element. closes odoo/odoo#29209 Signed-off-by:
Simon Lejeune (sle) <sle@openerp.com>
-
Prakash Prajapati authored
task-1889404 Closes #29209
-
Prakash Prajapati authored
task-1889404 Closes #29209
-
Prakash Prajapati authored
Improve batch picking demo data. The first page shows the summary of all the pickings. next page onwards we can see the picking information in the report. task-1889404 Closes #29209
-
Prakash Prajapati authored
Add the total weight of the picking on the delivery slip (next to the date field) (only if different than 0) Add a column "HS code" on the product line if there is at least one product with an HS code task-1889404 Closes #29209
-
- Jul 30, 2019
-
-
fja-odoo authored
Fix for: https://github.com/odoo/odoo/pull/32132 We had changed the display of the warnings in the back-end to be like the front-end (notification toast). This change needs to be reverted. Now the warnings in the front-end are toast notifications and in the back-end they are Warning modals. Part of: https://github.com/odoo/odoo/pull/35209
-
fja-odoo authored
Fix for: https://github.com/odoo/odoo/pull/32132 A reference to gamification was still made in the crash_manager. Part of: https://github.com/odoo/odoo/pull/35209
-
fja-odoo authored
* = website_forum, stock Fix for: https://github.com/odoo/odoo/pull/32132 crash_manager.js was using the services while bypassing ServiceProviderMixin That means all services are duplicated, each having their own state. To fix this issue, CrashManager now extends AbstractService. Also crash_manager is now registered in serviceRegistry instead of being instanciated on the fly. The crash_manager now being a Service raise one issue with the tests: The services are not run for the tests but some tests needs the crash_manager 'unhandledrejection' listener. For that matter the services are reenable in qunit. Also the crash_manager's 'unhandledrejection' listener has to have precedence over the qunit listener as it will handle rejections wich have no reason or are not Errors. Part of: https://github.com/odoo/odoo/pull/35209
-
Yenthe666 authored
Those two decorators are removed/deprecated since recent commits but some references remained in the documentation. api.multi is deprecated since https://github.com/odoo/odoo/commit/cc62447a44c2cf4e2edaf8a1f6d94520e799ddd9 api.one was removed with https://github.com/odoo/odoo/commit/407f1f6cdb87a59bbad9f853078d7345cdf9f60c closes odoo/odoo#35261 Signed-off-by:
Martin Trigaux (mat) <mat@odoo.com>
-
Naglis Jonaitis authored
There is no such aria property `aria-title`. closes odoo/odoo#35274 Signed-off-by:
Martin Trigaux (mat) <mat@odoo.com>
-
qsm-odoo authored
Since https://github.com/odoo/odoo/commit/2ad49ec93e39ae5d59ccc17884408870e1c86c5e , all dialogs were able to be closed by clicking on the backdrop which was not a desired behavior. Indeed, the 'backdrop' option of the BS component was misused. closes odoo/odoo#35300 Signed-off-by:
Quentin Smetz (qsm) <qsm@odoo.com>
-
Vincent Schippefilt authored
This reverts commit 3ea179e03c938222d88e32cbb5accacdfcef78c6. SBU requested to revert this task https://www.odoo.com/web#id=2036832&model=project.task&view_type=form&menu_id=4720 closes odoo/odoo#35298 Signed-off-by:
VincentSchippefilt <VincentSchippefilt@users.noreply.github.com>
-
qmo-odoo authored
This commit improves a few methods related to the user profiles: - Change _prepare_all_users_values so that it works with a batch of users - Change the _get_user_certificates and rename it to _get_users_certificates so that it works with a batch of users to avoid doing a search in a list comprehension. This method will also be used to get the number of certificates per users TaskID: 1952064 PR: #32229 Signed-off-by:
Thibault Delavallee (tde) <tde@openerp.com>
-
qmo-odoo authored
This commit fixes an issue where only three slides would be displayed instead of four in a category of the course page. This was due to the promoted slide being ignored in its own category. After this commit, the promoted slide will appear in the promoted slot AND in its category TaskID: 1952064 PR: #32229
-
Patrick Hoste authored
By default the main Leads menu doesn't have a submenu anymore But when the website_crm_score module is installed, it appears as a submenu like before PR : #34595 Task ID : 2031626 Signed-off-by:
Thibault Delavallee (tde) <tde@openerp.com>
-
Yenthe666 authored
closes odoo/odoo#35227 Signed-off-by:
Martin Trigaux (mat) <mat@odoo.com>
-