Skip to content
Snippets Groups Projects
  1. Jul 30, 2019
  2. Aug 02, 2019
  3. Aug 01, 2019
  4. Jul 31, 2019
    • Naglis Jonaitis's avatar
      [IMP] *: fix typos in field definitions · 7417d8fc
      Naglis Jonaitis authored
      
      * account, crm, hr, im_livechat, l10n_ch, l10n_it_edi, mail,
      mass_mailing, project, stock, base
      
      - `String` -> `string`;
      - `defaut` -> `default`;
      - `defaults` -> `default`;
      - `reandonly` -> `readonly`;
      - removed redundant `placeholder` attribute for `Char` field;
      - removed redundant `size` attribute for `Float` and `Integer` fields;
      - changed to use `Selection` instead of `Char` for a field having a
      defined `selection`.
      
      closes odoo/odoo#35356
      
      Signed-off-by: default avatarMartin Trigaux (mat) <mat@odoo.com>
      7417d8fc
  5. Aug 02, 2019
    • Gert Pellin's avatar
      [IMP] product, sale, sale_management: move discount group on product · ef99ea2d
      Gert Pellin authored
      
      The group 'group_discount_per_so_line' is used on reports in
      point_of_sale but is created in 'sale' module and point_of_sale doesn't
      depends on sale. So we've move this group on product to be able to
      properly use it in point_of_sale.
      
      TASK-ID: 2008468
      
      closes odoo/odoo#35041
      
      Signed-off-by: default avatarpimodoo <pimodoo@users.noreply.github.com>
      ef99ea2d
    • Pierre Masereel's avatar
      [FIX] point_of_sale: set back orders stat button · eba2d26e
      Pierre Masereel authored
      The stat button on the pos session that shows the different POS orders
      linked to the session has been deleted by mistake in rev: 91532b7b
      
      So we've set it back.
      eba2d26e
    • Gert Pellin's avatar
      [IMP] point_of_sale: improve views of pos objects · ccce0768
      Gert Pellin authored
      We made here some small changes on the views of different object of POS
      module, and set the field journal_ids required in the views, because
      launching a POS without payment method won't magically assign one
      anymore.
      
      TASK-ID: 2008468
      ccce0768
    • Pierre Masereel's avatar
      [IMP] point_of_sale: pos journal for each company · acbca119
      Pierre Masereel authored
      When the accounting localisation is installed after the POS config, the
      values on the default POS config which is in data are not completed
      because the POS config has been created before any journal exists.
      
      So now, when a chart template is installed, we are completing the POS
      config values, and creating the Sale POS journal. We also call the
      creation of POS journal when the point_of_sale module is installed after
      the template is installed on the database to be sure that we have a
      default value for POS journal.
      
      TASK-ID: 2008468
      acbca119
    • Gert Pellin's avatar
      [IMP] point_of_sale: correcly set default values on pos config · a6b598e6
      Gert Pellin authored
      When a pos config is created, default values set on it are not allways
      correct, for the sale journal we are referencing a data, which mean
      rthat it only worls in the first company. For the invoice journal, we
      are referencing the wrong journal in the onchannge, etc
      
      TASK-ID: 2008468
      a6b598e6
  6. Aug 01, 2019
    • Pierre Masereel's avatar
      [FIX] account: unlink data when installing chart of account · 56331c1a
      Pierre Masereel authored
      When a chart of account is installed, it first remove all existing
      existing data. If you don't have account_accountant module installed,
      but you have create a bank or cash journal (through the POS for
      example). Some accounts have been created and the installation of chart
      template is trying to remove some models, but as the account_accountant
      you don't have access write on model 'account.reconcile.model'.
      56331c1a
    • Martin Trigaux's avatar
      [FIX] *: bad usage of _ method · f8ff7deb
      Martin Trigaux authored
      
      No need for selection fields
      If in global variable, the _lt should be used instead
      
      closes odoo/odoo#31211
      
      Signed-off-by: default avatarMartin Trigaux (mat) <mat@odoo.com>
      f8ff7deb
    • Martin Trigaux's avatar
      [ADD] tools: lazy translation method · f4319580
      Martin Trigaux authored
      Introduces the method _lt
      
      The translation method is now evaluated lazily.
      It allows to declare global variables with translatable content
      
      e.g. this code will now work:
      
      LABEL = _lt("User")
      
      def _compute_label(self):
          context = {'lang': self.partner_id.lang}
          self.user_label = LABEL
      f4319580
    • Simon Lejeune's avatar
      [REF] stock_account: _compute_average_price unit price rounding · 0fc9a97d
      Simon Lejeune authored
      
      Since the introduction of the stock valuation layer, unit_cost is
      rounded in the company currency (actually it is NOT because of an ORM
      bug that will be fixed later). With the test introduced at [0], fixing
      that ORM bug shows we have a rounding issue (27.02 instead of 27) due to
      the company currency rounding on the unit_cost. Since the logic of the
      anglo saxon will probably always give some rounding issue (we always
      return a price unit that will be multiply by the invoiced quantity)
      recomputing a not rounded price unit by using the not rounded value with
      the not rounded quantity seems a good enough compromise.
      
      [0] 13a535a0
      
      closes odoo/odoo#35384
      
      Signed-off-by: default avatarSimon Lejeune (sle) <sle@openerp.com>
      0fc9a97d
    • Simon Lejeune's avatar
      [ADD] purchase: test planned date · 9197c0ad
      Simon Lejeune authored
      
      task-2032417
      
      closes odoo/odoo#35148
      
      Signed-off-by: default avatarSimon Lejeune (sle) <sle@openerp.com>
      9197c0ad
    • Ankita Raval's avatar
      [IMP] purchase: set schedule_date of po lines as per date_planned of PO · a2a39ef4
      Ankita Raval authored
      In this commit -
      1. Previously, date_planned of PO was computed and set while the creation of PO.
         In this commit, removed the compute logic and now field will be empty until
         user fills it.
      2. ‘Set date to all order lines’ button is removed.
      3. Now if user have filled the date_planned of PO, it will be copied to all po
         lines.
      4. Schedule date of PO line will be readonly if date_planned have any value
         else will be editable.
      5. Update the test cases of computation of date_planned.
      
      Task-2032417
      a2a39ef4
    • Jitendra Prajapati's avatar
      [IMP] mrp: added support embedded google slide on work center · 8bf1486d
      Jitendra Prajapati authored
      
      This commit adds new `embed_viewer` widget which will be used display URLs
      via embedded iframes.  You can add any valid URL to display page via iframe,
      although widget automatically converts raw google slide URL into embedded URL.
      
      Task ID: 1909010
      
      closes odoo/odoo#29404
      
      Signed-off-by: default avatarSimon Lejeune (sle) <sle@openerp.com>
      
      
      Co-authored-by: default avatarpga-odoo <pga@odoo.com>
      8bf1486d
    • Prakash Prajapati's avatar
      [IMP] various: Clean stat buttons across all modules. · 1a330565
      Prakash Prajapati authored
      Purpose
      =======
      
      Make them consistent.
      Make sure context is correctly set.
      Prevent creation when necessary.
      
      Specification
      =============
      
      See https://www.odoo.com/web#id=2024467&action=333&active_id=1251&model=project.task&view_type=form&menu_id=4720
      
      
      for the detailed list of all the requested improvements.
      
      TaskID: 2024467
      
      closes odoo/odoo#34561
      
      Signed-off-by: default avatarYannick Tivisse (yti) <yti@odoo.com>
      1a330565
    • Yenthe666's avatar
      [IMP] base: improve logging view and add hooks · 0c808a08
      Yenthe666 authored
      
      closes odoo/odoo#32392
      
      Signed-off-by: default avatarMartin Trigaux (mat) <mat@odoo.com>
      0c808a08
    • mreficent's avatar
      [IMP] doc: remove calls to @api.guess and @api.noguess · 64773140
      mreficent authored
      
      Those two decorators are removed/deprecated since recent commits but
      some references remained in the documentation.
      
      api.guess and api.noguess is deprecated and removed since c552fb7a
      
      closes odoo/odoo#35332
      
      Signed-off-by: default avatarMartin Trigaux (mat) <mat@odoo.com>
      64773140
    • Meghna Jaswani's avatar
      [IMP] l10n_lu: update of CoA 2020 PCN standard and tax report · ee1f0ef1
      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: default avatarJosse Colpaert <jco@openerp.com>
      ee1f0ef1
    • Robot Odoo's avatar
      [MERGE] base: Remove customer/supplier fields on res.partner · 8626257b
      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: default avatarYannick Tivisse (yti) <yti@odoo.com>
      
      Co-authored-by: default avatarYannick Tivisse <yti@odoo.com>
      8626257b
    • Lucas Lefèvre's avatar
      [IMP] base: Remove customer and supplier fields from res.partner · 3e97cff7
      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: default avatarYannick Tivisse <yti@odoo.com>
      3e97cff7
    • Lucas Lefèvre's avatar
      [IMP] base: Allow to better search partners if they are customers/suppliers · 8766f388
      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: default avatarYannick Tivisse <yti@odoo.com>
      8766f388
    • Robot Odoo's avatar
      [MERGE] base: remove field source of ir.translation · ed7b53bb
      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: default avatarMartin Trigaux (mat) <mat@odoo.com>
      ed7b53bb
    • Martin Trigaux's avatar
      [FIX] base: single lang behaviour · 18d9c2ca
      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
      18d9c2ca
    • Martin Trigaux's avatar
      [REF] base: remove field source of ir.translation · 66ef641f
      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
      66ef641f
  7. Jul 29, 2019
  8. Jul 31, 2019
    • Simon Lejeune's avatar
      [REF] stock: tests common · 5c8342f9
      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: default avatarSimon Lejeune (sle) <sle@openerp.com>
      5c8342f9
    • wan's avatar
      [FIX] point_of_sale: anglosaxon prices werent correctly calcuated · 13a535a0
      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: default avatarSimon Lejeune (sle) <sle@openerp.com>
      13a535a0
  9. Jul 30, 2019
    • Xavier-Do's avatar
      [FIX] core: log error on addSubTest · 22930162
      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: default avatarDenis Ledoux <beledouxdenis@users.noreply.github.com>
      22930162
  10. Jul 31, 2019
    • Nathan de Pryck's avatar
      [IMP] iap: multi-company for iap account · 4f33ae16
      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: default avatarRémi Rahir (rar) <rar@odoo.com>
      4f33ae16
    • svs-odoo's avatar
      [IMP] mrp: can delete active MO · b499c330
      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: default avatarArnold Moyaux <amoyaux@users.noreply.github.com>
      b499c330
    • Arnold Moyaux's avatar
      [FIX] mrp: log activity on parent MO · 3d4c0f92
      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.
      3d4c0f92
    • svs-odoo's avatar
      [IMP] mrp: can cancel MO in more cases · c76fcd87
      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: default avatarArnold Moyaux <arm@odoo.com>
      c76fcd87
    • pha-odoo's avatar
      [FIX] iot: bluetooth work with serial · 28c2e642
      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: default avatarQuentin Lejeune (qle) <qle@odoo.com>
      28c2e642
    • Pierre Rousseau's avatar
      [IMP] crm_iap_lead: improve credits tooltip · 0e6e80ca
      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: default avatarRémi Rahir (rar) <rar@odoo.com>
      0e6e80ca
  11. Jul 29, 2019
  12. Jul 31, 2019
    • Patrick Hoste's avatar
      [IMP] eLearning: adds course and certification stat button on partner · 81c7afb8
      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: default avatarThibault Delavallee (tde) <tde@openerp.com>
      81c7afb8
    • qmo-odoo's avatar
      [REF] sales_team: Clean _get_default_team · d3291207
      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: default avatarThibault Delavallee (tde) <tde@openerp.com>
      d3291207
Loading