odoo-addon-sale-blanket-order 16.0.1.0.0.5__py3-none-any.whl → 17.0.1.0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of odoo-addon-sale-blanket-order might be problematic. Click here for more details.

Files changed (27) hide show
  1. odoo/addons/sale_blanket_order/README.rst +83 -60
  2. odoo/addons/sale_blanket_order/__manifest__.py +2 -2
  3. odoo/addons/sale_blanket_order/i18n/it.po +3 -3
  4. odoo/addons/sale_blanket_order/i18n/sale_blanket_order.pot +16 -26
  5. odoo/addons/sale_blanket_order/models/blanket_orders.py +71 -50
  6. odoo/addons/sale_blanket_order/models/sale_config_settings.py +0 -1
  7. odoo/addons/sale_blanket_order/models/sale_orders.py +2 -2
  8. odoo/addons/sale_blanket_order/readme/CONTRIBUTORS.md +17 -0
  9. odoo/addons/sale_blanket_order/readme/{CREDITS.rst → CREDITS.md} +2 -1
  10. odoo/addons/sale_blanket_order/readme/DESCRIPTION.md +5 -0
  11. odoo/addons/sale_blanket_order/readme/USAGE.md +58 -0
  12. odoo/addons/sale_blanket_order/static/description/index.html +53 -52
  13. odoo/addons/sale_blanket_order/tests/test_blanket_orders.py +6 -6
  14. odoo/addons/sale_blanket_order/tests/test_sale_order.py +1 -3
  15. odoo/addons/sale_blanket_order/views/sale_blanket_order_views.xml +24 -34
  16. odoo/addons/sale_blanket_order/views/sale_config_settings.xml +11 -19
  17. odoo/addons/sale_blanket_order/views/sale_order_views.xml +1 -1
  18. odoo/addons/sale_blanket_order/wizard/create_sale_orders.py +3 -2
  19. odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info/METADATA +186 -0
  20. {odoo_addon_sale_blanket_order-16.0.1.0.0.5.dist-info → odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info}/RECORD +22 -22
  21. {odoo_addon_sale_blanket_order-16.0.1.0.0.5.dist-info → odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info}/WHEEL +1 -1
  22. odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info/top_level.txt +1 -0
  23. odoo/addons/sale_blanket_order/readme/CONTRIBUTORS.rst +0 -8
  24. odoo/addons/sale_blanket_order/readme/DESCRIPTION.rst +0 -4
  25. odoo/addons/sale_blanket_order/readme/USAGE.rst +0 -53
  26. odoo_addon_sale_blanket_order-16.0.1.0.0.5.dist-info/METADATA +0 -167
  27. odoo_addon_sale_blanket_order-16.0.1.0.0.5.dist-info/top_level.txt +0 -1
@@ -7,7 +7,7 @@ Sale Blanket Orders
7
7
  !! This file is generated by oca-gen-addon-readme !!
8
8
  !! changes will be overwritten. !!
9
9
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10
- !! source digest: sha256:ccbeac2c26d7658d8283b70cce70cd45752f1c2207f3bf45370716a8072e14fd
10
+ !! source digest: sha256:38dd0261a7111b3d7809f79e0b708c34344ef59827257ad8556071883c377c7c
11
11
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12
12
 
13
13
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -17,21 +17,22 @@ Sale Blanket Orders
17
17
  :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18
18
  :alt: License: AGPL-3
19
19
  .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
20
- :target: https://github.com/OCA/sale-workflow/tree/16.0/sale_blanket_order
20
+ :target: https://github.com/OCA/sale-workflow/tree/17.0/sale_blanket_order
21
21
  :alt: OCA/sale-workflow
22
22
  .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23
- :target: https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_blanket_order
23
+ :target: https://translation.odoo-community.org/projects/sale-workflow-17-0/sale-workflow-17-0-sale_blanket_order
24
24
  :alt: Translate me on Weblate
25
25
  .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26
- :target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=16.0
26
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=17.0
27
27
  :alt: Try me on Runboat
28
28
 
29
29
  |badge1| |badge2| |badge3| |badge4| |badge5|
30
30
 
31
- A blanket order is a pre-agreement to sell a certain number of quantities of
32
- products at a specific price. From a confirmed blanket order, the users can
33
- create new sale orders at such price, until the blanket order expires, either
34
- due to reaching the validity date or exhausting all the quantities of products.
31
+ A blanket order is a pre-agreement to sell a certain number of
32
+ quantities of products at a specific price. From a confirmed blanket
33
+ order, the users can create new sale orders at such price, until the
34
+ blanket order expires, either due to reaching the validity date or
35
+ exhausting all the quantities of products.
35
36
 
36
37
  **Table of contents**
37
38
 
@@ -41,59 +42,72 @@ due to reaching the validity date or exhausting all the quantities of products.
41
42
  Usage
42
43
  =====
43
44
 
44
- A new menu in the Sales area is created, allowing users to create new blanket orders.
45
+ A new menu in the Sales area is created, allowing users to create new
46
+ blanket orders.
45
47
 
46
- To create a new Sale Blanket Order go to the sale menu in the Sales section:
48
+ To create a new Sale Blanket Order go to the sale menu in the Sales
49
+ section:
47
50
 
48
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/BO_menu.png
49
- :alt: Blanket Orders menu
51
+ |image1|
50
52
 
51
- Hitting the button create will open the form view in which we can introduce the following
52
- information:
53
+ Hitting the button create will open the form view in which we can
54
+ introduce the following information:
53
55
 
54
- * Vendor
55
- * Salesperson
56
- * Payment Terms
57
- * Validity date
58
- * Order lines:
59
- * Product
60
- * Accorded price
61
- * Original, Ordered, Invoiced, Received and Remaining quantities
62
- * Terms and Conditions of the Blanket Order
56
+ - Vendor
63
57
 
64
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/BO_form.png
65
- :alt: Blanket Orders form
58
+ - Salesperson
66
59
 
67
- From the form, once the Blanket Order has been confirmed and its state is open, the user can
68
- create a Sale Order, check the Sale Orders associated to the Blanket Order and/or
69
- see the Blanket Order lines associated to the BO.
60
+ - Payment Terms
70
61
 
71
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/BO_actions.png
72
- :alt: Actions that can be done from Blanket Order
62
+ - Validity date
73
63
 
74
- Hitting the button Create Sale Order will open a wizard that will ask for the amount of each
75
- product in the BO lines for which the Sale Order will be created.
64
+ - Order lines:
76
65
 
77
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/PO_from_BO.png
78
- :alt: Create Sale Order from Blanket Order
66
+ - Product
67
+ - Accorded price
68
+ - Original, Ordered, Invoiced, Received and Remaining quantities
79
69
 
80
- Installing this module will add an additional menu which will show all the blanket order lines
81
- currently defined in the system. From this list the user can create customized Sale Orders
82
- selecting the lines for which the PO (or POs if the customers are different) is (are) created.
70
+ - Terms and Conditions of the Blanket Order
83
71
 
84
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/BO_lines.png
85
- :alt: Blanket Order lines and actions
72
+ |image2|
86
73
 
87
- In the Sale Order form one field is added in the PO lines, the Blanket Order line field. This
88
- field keeps track to which Blanket Order line the PO line is associated. Upon adding a new product
89
- in a newly created Sale Order a blanket order line will be suggested depending on the following
74
+ From the form, once the Blanket Order has been confirmed and its state
75
+ is open, the user can create a Sale Order, check the Sale Orders
76
+ associated to the Blanket Order and/or see the Blanket Order lines
77
+ associated to the BO.
78
+
79
+ |image3|
80
+
81
+ Hitting the button Create Sale Order will open a wizard that will ask
82
+ for the amount of each product in the BO lines for which the Sale Order
83
+ will be created.
84
+
85
+ |image4|
86
+
87
+ Installing this module will add an additional menu which will show all
88
+ the blanket order lines currently defined in the system. From this list
89
+ the user can create customized Sale Orders selecting the lines for which
90
+ the PO (or POs if the customers are different) is (are) created.
91
+
92
+ |image5|
93
+
94
+ In the Sale Order form one field is added in the PO lines, the Blanket
95
+ Order line field. This field keeps track to which Blanket Order line the
96
+ PO line is associated. Upon adding a new product in a newly created Sale
97
+ Order a blanket order line will be suggested depending on the following
90
98
  factors:
91
99
 
92
- * Closer Validity date
93
- * Remaining quantity > Quantity introduced in the Sale Order line
100
+ - Closer Validity date
101
+ - Remaining quantity > Quantity introduced in the Sale Order line
102
+
103
+ |image6|
94
104
 
95
- .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/16.0/sale_blanket_order/static/description/PO_BOLine.png
96
- :alt: New field added in Sale Order Line
105
+ .. |image1| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/BO_menu.png
106
+ .. |image2| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/BO_form.png
107
+ .. |image3| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/BO_actions.png
108
+ .. |image4| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/PO_from_BO.png
109
+ .. |image5| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/BO_lines.png
110
+ .. |image6| image:: https://raw.githubusercontent.com/OCA/sale-workflow/17.0/sale_blanket_order/static/description/PO_BOLine.png
97
111
 
98
112
  Bug Tracker
99
113
  ===========
@@ -101,7 +115,7 @@ Bug Tracker
101
115
  Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/issues>`_.
102
116
  In case of trouble, please check there if your issue has already been reported.
103
117
  If you spotted it first, help us to smash it by providing a detailed and welcomed
104
- `feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_blanket_order%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
118
+ `feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_blanket_order%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
105
119
 
106
120
  Do not contact contributors directly about support or help with technical issues.
107
121
 
@@ -109,29 +123,38 @@ Credits
109
123
  =======
110
124
 
111
125
  Authors
112
- ~~~~~~~
126
+ -------
113
127
 
114
128
  * Acsone SA/NV
115
129
 
116
130
  Contributors
117
- ~~~~~~~~~~~~
131
+ ------------
132
+
133
+ - André Pereira <github@andreparames.com> (https://www.acsone.eu/)
134
+
135
+ - Adrià Gil Sorribes <adria.gil@eficent.com> (https://www.eficent.com/)
136
+
137
+ - Jordi Ballester Alomar <jordi.ballester@eficent.com>
138
+
139
+ - Alex Comba <alex.comba@agilebg.com> (https://www.agilebg.com/)
140
+
141
+ - Codeforward (https://www.codeforward.nl/):
142
+
143
+ - Jasper Jumelet <jasper.jumelet@codeforward.nl>
144
+ - Chris Bergman <chris.bergman@codeforward.nl>
118
145
 
119
- * André Pereira <github@andreparames.com> (https://www.acsone.eu/)
120
- * Adrià Gil Sorribes <adria.gil@eficent.com> (https://www.eficent.com/)
121
- * Jordi Ballester Alomar <jordi.ballester@eficent.com>
122
- * Alex Comba <alex.comba@agilebg.com> (https://www.agilebg.com/)
123
- * Jasper Jumelet <jasper.jumelet@codeforward.nl> (https://www.codeforward.nl/)
124
- * `Trobz <https://trobz.com>`_:
146
+ - `Trobz <https://trobz.com>`__:
125
147
 
126
- * Nguyễn Minh Chiến <chien@trobz.com>
148
+ - Nguyễn Minh Chiến <chien@trobz.com>
127
149
 
128
150
  Other credits
129
- ~~~~~~~~~~~~~
151
+ -------------
130
152
 
131
- The migration of this module from 15.0 to 16.0 was financially supported by Camptocamp
153
+ The migration of this module from 15.0 to 16.0 was financially supported
154
+ by Camptocamp
132
155
 
133
156
  Maintainers
134
- ~~~~~~~~~~~
157
+ -----------
135
158
 
136
159
  This module is maintained by the OCA.
137
160
 
@@ -143,6 +166,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
143
166
  mission is to support the collaborative development of Odoo features and
144
167
  promote its widespread use.
145
168
 
146
- This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/16.0/sale_blanket_order>`_ project on GitHub.
169
+ This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/17.0/sale_blanket_order>`_ project on GitHub.
147
170
 
148
171
  You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
@@ -5,10 +5,10 @@
5
5
  "category": "Sale",
6
6
  "license": "AGPL-3",
7
7
  "author": "Acsone SA/NV, Odoo Community Association (OCA)",
8
- "version": "16.0.1.0.0",
8
+ "version": "17.0.1.0.0",
9
9
  "website": "https://github.com/OCA/sale-workflow",
10
10
  "summary": "Blanket Orders",
11
- "depends": ["uom", "sale_management", "web_action_conditionable"],
11
+ "depends": ["uom", "sale_management"],
12
12
  "data": [
13
13
  "security/security.xml",
14
14
  "security/ir.model.access.csv",
@@ -6,7 +6,7 @@ msgid ""
6
6
  msgstr ""
7
7
  "Project-Id-Version: Odoo Server 16.0\n"
8
8
  "Report-Msgid-Bugs-To: \n"
9
- "PO-Revision-Date: 2024-01-25 15:34+0000\n"
9
+ "PO-Revision-Date: 2024-03-15 16:34+0000\n"
10
10
  "Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
11
11
  "Language-Team: none\n"
12
12
  "Language: it\n"
@@ -1038,14 +1038,14 @@ msgstr "Non puoi creare un ordine di vendita da un ordine aperto scaduto!"
1038
1038
  #: code:addons/sale_blanket_order/wizard/create_sale_orders.py:0
1039
1039
  #, python-format
1040
1040
  msgid "You can't order more than the remaining quantities"
1041
- msgstr "Non puoi ordinare più della quantità rimanente"
1041
+ msgstr "Non si può ordinare più della quantità rimanente"
1042
1042
 
1043
1043
  #. module: sale_blanket_order
1044
1044
  #. odoo-python
1045
1045
  #: code:addons/sale_blanket_order/wizard/create_sale_orders.py:0
1046
1046
  #, python-format
1047
1047
  msgid "You have to select lines from the same company."
1048
- msgstr "Devi selezionare le righe della stessa azienda."
1048
+ msgstr "Bisogna selezionare le righe della stessa azienda."
1049
1049
 
1050
1050
  #. module: sale_blanket_order
1051
1051
  #. odoo-python
@@ -4,7 +4,7 @@
4
4
  #
5
5
  msgid ""
6
6
  msgstr ""
7
- "Project-Id-Version: Odoo Server 16.0\n"
7
+ "Project-Id-Version: Odoo Server 17.0\n"
8
8
  "Report-Msgid-Bugs-To: \n"
9
9
  "Last-Translator: \n"
10
10
  "Language-Team: \n"
@@ -128,13 +128,13 @@ msgid "An order can't be empty"
128
128
  msgstr ""
129
129
 
130
130
  #. module: sale_blanket_order
131
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__analytic_distribution
132
- msgid "Analytic"
131
+ #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__analytic_account_id
132
+ msgid "Analytic Account"
133
133
  msgstr ""
134
134
 
135
135
  #. module: sale_blanket_order
136
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__analytic_account_id
137
- msgid "Analytic Account"
136
+ #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__analytic_distribution
137
+ msgid "Analytic Distribution"
138
138
  msgstr ""
139
139
 
140
140
  #. module: sale_blanket_order
@@ -353,7 +353,6 @@ msgstr ""
353
353
 
354
354
  #. module: sale_blanket_order
355
355
  #: model:ir.actions.server,name:sale_blanket_order.expired_blanket_orders_cron_ir_actions_server
356
- #: model:ir.cron,cron_name:sale_blanket_order.expired_blanket_orders_cron
357
356
  msgid "Expire Blanket Orders"
358
357
  msgstr ""
359
358
 
@@ -450,14 +449,6 @@ msgstr ""
450
449
  msgid "Is Follower"
451
450
  msgstr ""
452
451
 
453
- #. module: sale_blanket_order
454
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order____last_update
455
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line____last_update
456
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_wizard____last_update
457
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_wizard_line____last_update
458
- msgid "Last Modified on"
459
- msgstr ""
460
-
461
452
  #. module: sale_blanket_order
462
453
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__write_uid
463
454
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__write_uid
@@ -480,12 +471,6 @@ msgstr ""
480
471
  msgid "Lines"
481
472
  msgstr ""
482
473
 
483
- #. module: sale_blanket_order
484
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__message_main_attachment_id
485
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__message_main_attachment_id
486
- msgid "Main Attachment"
487
- msgstr ""
488
-
489
474
  #. module: sale_blanket_order
490
475
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__message_has_error
491
476
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__message_has_error
@@ -521,12 +506,6 @@ msgstr ""
521
506
  msgid "Name"
522
507
  msgstr ""
523
508
 
524
- #. module: sale_blanket_order
525
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__activity_calendar_event_id
526
- #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__activity_calendar_event_id
527
- msgid "Next Activity Calendar Event"
528
- msgstr ""
529
-
530
509
  #. module: sale_blanket_order
531
510
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__activity_date_deadline
532
511
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__activity_date_deadline
@@ -668,6 +647,11 @@ msgstr ""
668
647
  msgid "Pricelist"
669
648
  msgstr ""
670
649
 
650
+ #. module: sale_blanket_order
651
+ #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__pricelist_item_id
652
+ msgid "Pricelist Item"
653
+ msgstr ""
654
+
671
655
  #. module: sale_blanket_order
672
656
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__product_id
673
657
  #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__product_id
@@ -693,6 +677,12 @@ msgstr ""
693
677
  msgid "Quantity to Order"
694
678
  msgstr ""
695
679
 
680
+ #. module: sale_blanket_order
681
+ #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order__rating_ids
682
+ #: model:ir.model.fields,field_description:sale_blanket_order.field_sale_blanket_order_line__rating_ids
683
+ msgid "Ratings"
684
+ msgstr ""
685
+
696
686
  #. module: sale_blanket_order
697
687
  #: model_terms:ir.ui.view,arch_db:sale_blanket_order.view_blanket_order_search
698
688
  msgid "Remaining Qty"
@@ -6,8 +6,6 @@ from odoo.exceptions import UserError
6
6
  from odoo.tools import float_is_zero
7
7
  from odoo.tools.misc import format_date
8
8
 
9
- from odoo.addons.sale.models.sale_order import READONLY_FIELD_STATES
10
-
11
9
 
12
10
  class BlanketOrder(models.Model):
13
11
  _name = "sale.blanket.order"
@@ -44,7 +42,6 @@ class BlanketOrder(models.Model):
44
42
  partner_id = fields.Many2one(
45
43
  "res.partner",
46
44
  string="Partner",
47
- states=READONLY_FIELD_STATES,
48
45
  )
49
46
  line_ids = fields.One2many(
50
47
  "sale.blanket.order.line", "order_id", string="Order lines", copy=True
@@ -63,7 +60,6 @@ class BlanketOrder(models.Model):
63
60
  "product.pricelist",
64
61
  string="Pricelist",
65
62
  required=True,
66
- states=READONLY_FIELD_STATES,
67
63
  )
68
64
  currency_id = fields.Many2one("res.currency", related="pricelist_id.currency_id")
69
65
  analytic_account_id = fields.Many2one(
@@ -71,13 +67,11 @@ class BlanketOrder(models.Model):
71
67
  string="Analytic Account",
72
68
  copy=False,
73
69
  check_company=True,
74
- states=READONLY_FIELD_STATES,
75
70
  domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
76
71
  )
77
72
  payment_term_id = fields.Many2one(
78
73
  "account.payment.term",
79
74
  string="Payment Terms",
80
- states=READONLY_FIELD_STATES,
81
75
  )
82
76
  confirmed = fields.Boolean(copy=False)
83
77
  state = fields.Selection(
@@ -91,26 +85,21 @@ class BlanketOrder(models.Model):
91
85
  store=True,
92
86
  copy=False,
93
87
  )
94
- validity_date = fields.Date(
95
- states=READONLY_FIELD_STATES,
96
- )
88
+ validity_date = fields.Date()
97
89
  client_order_ref = fields.Char(
98
90
  string="Customer Reference",
99
91
  copy=False,
100
- states=READONLY_FIELD_STATES,
101
92
  )
102
- note = fields.Text(default=_default_note, states=READONLY_FIELD_STATES)
93
+ note = fields.Text(default=_default_note)
103
94
  user_id = fields.Many2one(
104
95
  "res.users",
105
96
  string="Salesperson",
106
- states=READONLY_FIELD_STATES,
107
97
  )
108
98
  team_id = fields.Many2one(
109
99
  "crm.team",
110
100
  string="Sales Team",
111
101
  change_default=True,
112
102
  default=lambda self: self.env["crm.team"]._get_default_team_id(),
113
- states=READONLY_FIELD_STATES,
114
103
  )
115
104
  company_id = fields.Many2one(
116
105
  comodel_name="res.company",
@@ -198,7 +187,7 @@ class BlanketOrder(models.Model):
198
187
  order.state = "expired"
199
188
  elif float_is_zero(
200
189
  sum(
201
- order.line_ids.filtered(lambda l: not l.display_type).mapped(
190
+ order.line_ids.filtered(lambda line: not line.display_type).mapped(
202
191
  "remaining_uom_qty"
203
192
  )
204
193
  ),
@@ -483,23 +472,29 @@ class BlanketOrderLine(models.Model):
483
472
  default=False,
484
473
  help="Technical field for UX purpose.",
485
474
  )
475
+ pricelist_item_id = fields.Many2one(
476
+ comodel_name="product.pricelist.item", compute="_compute_pricelist_item_id"
477
+ )
486
478
 
487
- def name_get(self):
488
- result = []
479
+ @api.depends(
480
+ "order_id.name", "date_schedule", "remaining_uom_qty", "product_uom.name"
481
+ )
482
+ @api.depends_context("from_sale_order")
483
+ def _compute_display_name(self):
489
484
  if self.env.context.get("from_sale_order"):
490
485
  for record in self:
491
- res = "[%s]" % record.order_id.name
486
+ name = "[%s]" % record.order_id.name
492
487
  if record.date_schedule:
493
488
  formatted_date = format_date(record.env, record.date_schedule)
494
- res += " - {}: {}".format(_("Date Scheduled"), formatted_date)
495
- res += " ({}: {} {})".format(
489
+ name += " - {}: {}".format(_("Date Scheduled"), formatted_date)
490
+ name += " ({}: {} {})".format(
496
491
  _("remaining"),
497
492
  record.remaining_uom_qty,
498
493
  record.product_uom.name,
499
494
  )
500
- result.append((record.id, res))
501
- return result
502
- return super().name_get()
495
+ record.display_name = name
496
+ else:
497
+ return super()._compute_display_name()
503
498
 
504
499
  def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id):
505
500
  """Retrieve the price before applying the pricelist
@@ -563,35 +558,43 @@ class BlanketOrderLine(models.Model):
563
558
 
564
559
  return product[field_name] * uom_factor * cur_factor, currency_id.id
565
560
 
566
- def _get_display_price(self, product):
561
+ def _get_display_price(self):
567
562
  # Copied and adapted from the sale module
568
563
  self.ensure_one()
569
- pricelist = self.order_id.pricelist_id
570
- partner = self.order_id.partner_id
571
- if self.order_id.pricelist_id.discount_policy == "with_discount":
572
- return product.with_context(pricelist=pricelist.id).lst_price
573
- final_price, rule_id = pricelist._get_product_price_rule(
574
- self.product_id, self.original_uom_qty or 1.0, self.product_uom
564
+ self.product_id.ensure_one()
565
+
566
+ pricelist_price = self.pricelist_item_id._compute_price(
567
+ product=self.product_id,
568
+ quantity=self.original_uom_qty or 1.0,
569
+ uom=self.product_uom,
570
+ date=fields.Date.today(),
571
+ currency=self.currency_id,
575
572
  )
576
- context_partner = dict(
577
- self.env.context, partner_id=partner.id, date=fields.Date.today()
578
- )
579
- base_price, currency_id = self.with_context(
580
- **context_partner
581
- )._get_real_price_currency(
582
- self.product_id,
583
- rule_id,
584
- self.original_uom_qty,
585
- self.product_uom,
586
- pricelist.id,
587
- )
588
- if currency_id != pricelist.currency_id.id:
589
- currency = self.env["res.currency"].browse(currency_id)
590
- base_price = currency.with_context(**context_partner).compute(
591
- base_price, pricelist.currency_id
592
- )
573
+
574
+ if self.order_id.pricelist_id.discount_policy == "with_discount":
575
+ return pricelist_price
576
+
577
+ if not self.pricelist_item_id:
578
+ # No pricelist rule found => no discount from pricelist
579
+ return pricelist_price
580
+
581
+ base_price = self._get_pricelist_price_before_discount()
582
+
593
583
  # negative discounts (= surcharge) are included in the display price
594
- return max(base_price, final_price)
584
+ return max(base_price, pricelist_price)
585
+
586
+ def _get_pricelist_price_before_discount(self):
587
+ # Copied and adapted from the sale module
588
+ self.ensure_one()
589
+ self.product_id.ensure_one()
590
+
591
+ return self.pricelist_item_id._compute_price_before_discount(
592
+ product=self.product_id,
593
+ quantity=self.product_uom_qty or 1.0,
594
+ uom=self.product_uom,
595
+ date=fields.Date.today(),
596
+ currency=self.currency_id,
597
+ )
595
598
 
596
599
  @api.onchange("product_id", "original_uom_qty")
597
600
  def onchange_product(self):
@@ -605,9 +608,9 @@ class BlanketOrderLine(models.Model):
605
608
  if self.order_id.partner_id and float_is_zero(
606
609
  self.price_unit, precision_digits=precision
607
610
  ):
608
- self.price_unit = self._get_display_price(self.product_id)
611
+ self.price_unit = self._get_display_price()
609
612
  if self.product_id.code:
610
- name = "[{}] {}".format(name, self.product_id.code)
613
+ name = f"[{name}] {self.product_id.code}"
611
614
  if self.product_id.description_sale:
612
615
  name += "\n" + self.product_id.description_sale
613
616
  self.name = name
@@ -656,6 +659,24 @@ class BlanketOrderLine(models.Model):
656
659
  line.remaining_uom_qty, line.product_id.uom_id
657
660
  )
658
661
 
662
+ @api.depends("product_id", "product_uom", "original_uom_qty")
663
+ def _compute_pricelist_item_id(self):
664
+ # Copied and adapted from the sale module
665
+ for line in self:
666
+ if (
667
+ not line.product_id
668
+ or line.display_type
669
+ or not line.order_id.pricelist_id
670
+ ):
671
+ line.pricelist_item_id = False
672
+ else:
673
+ line.pricelist_item_id = line.order_id.pricelist_id._get_product_rule(
674
+ line.product_id,
675
+ quantity=line.original_uom_qty or 1.0,
676
+ uom=line.product_uom,
677
+ date=fields.Date.today(),
678
+ )
679
+
659
680
  def _validate(self):
660
681
  try:
661
682
  for line in self:
@@ -716,4 +737,4 @@ class BlanketOrderLine(models.Model):
716
737
  """
717
738
  )
718
739
  )
719
- return super(BlanketOrderLine, self).write(values)
740
+ return super().write(values)
@@ -5,7 +5,6 @@ from odoo import fields, models
5
5
 
6
6
 
7
7
  class SaleConfigSettings(models.TransientModel):
8
-
9
8
  _inherit = "res.config.settings"
10
9
 
11
10
  group_blanket_disable_adding_lines = fields.Boolean(
@@ -61,14 +61,14 @@ class SaleOrderLine(models.Model):
61
61
  assigned_bo_line = False
62
62
  date_planned = date.today()
63
63
  date_delta = timedelta(days=365)
64
- for line in bo_lines.filtered(lambda l: l.date_schedule):
64
+ for line in bo_lines.filtered(lambda bo_line: bo_line.date_schedule):
65
65
  date_schedule = line.date_schedule
66
66
  if date_schedule and abs(date_schedule - date_planned) < date_delta:
67
67
  assigned_bo_line = line
68
68
  date_delta = abs(date_schedule - date_planned)
69
69
  if assigned_bo_line:
70
70
  return assigned_bo_line
71
- non_date_bo_lines = bo_lines.filtered(lambda l: not l.date_schedule)
71
+ non_date_bo_lines = bo_lines.filtered(lambda bo_line: not bo_line.date_schedule)
72
72
  if non_date_bo_lines:
73
73
  return non_date_bo_lines[0]
74
74
 
@@ -0,0 +1,17 @@
1
+ - André Pereira \<<github@andreparames.com>\> (<https://www.acsone.eu/>)
2
+
3
+ - Adrià Gil Sorribes \<<adria.gil@eficent.com>\>
4
+ (<https://www.eficent.com/>)
5
+
6
+ - Jordi Ballester Alomar \<<jordi.ballester@eficent.com>\>
7
+
8
+ - Alex Comba \<<alex.comba@agilebg.com>\> (<https://www.agilebg.com/>)
9
+
10
+ - Codeforward (https://www.codeforward.nl/):
11
+
12
+ > - Jasper Jumelet \<<jasper.jumelet@codeforward.nl>\>
13
+ > - Chris Bergman \<<chris.bergman@codeforward.nl>\>
14
+
15
+ - [Trobz](https://trobz.com):
16
+
17
+ > - Nguyễn Minh Chiến \<<chien@trobz.com>\>
@@ -1 +1,2 @@
1
- The migration of this module from 15.0 to 16.0 was financially supported by Camptocamp
1
+ The migration of this module from 15.0 to 16.0 was financially supported
2
+ by Camptocamp
@@ -0,0 +1,5 @@
1
+ A blanket order is a pre-agreement to sell a certain number of
2
+ quantities of products at a specific price. From a confirmed blanket
3
+ order, the users can create new sale orders at such price, until the
4
+ blanket order expires, either due to reaching the validity date or
5
+ exhausting all the quantities of products.