odoo-addon-sale-blanket-order 16.0.1.0.0.6__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.
- odoo/addons/sale_blanket_order/README.rst +83 -60
- odoo/addons/sale_blanket_order/__manifest__.py +2 -2
- odoo/addons/sale_blanket_order/i18n/sale_blanket_order.pot +16 -26
- odoo/addons/sale_blanket_order/models/blanket_orders.py +71 -50
- odoo/addons/sale_blanket_order/models/sale_config_settings.py +0 -1
- odoo/addons/sale_blanket_order/models/sale_orders.py +2 -2
- odoo/addons/sale_blanket_order/readme/CONTRIBUTORS.md +17 -0
- odoo/addons/sale_blanket_order/readme/{CREDITS.rst → CREDITS.md} +2 -1
- odoo/addons/sale_blanket_order/readme/DESCRIPTION.md +5 -0
- odoo/addons/sale_blanket_order/readme/USAGE.md +58 -0
- odoo/addons/sale_blanket_order/static/description/index.html +53 -52
- odoo/addons/sale_blanket_order/tests/test_blanket_orders.py +6 -6
- odoo/addons/sale_blanket_order/tests/test_sale_order.py +1 -3
- odoo/addons/sale_blanket_order/views/sale_blanket_order_views.xml +24 -34
- odoo/addons/sale_blanket_order/views/sale_config_settings.xml +11 -19
- odoo/addons/sale_blanket_order/views/sale_order_views.xml +1 -1
- odoo/addons/sale_blanket_order/wizard/create_sale_orders.py +3 -2
- odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info/METADATA +186 -0
- {odoo_addon_sale_blanket_order-16.0.1.0.0.6.dist-info → odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info}/RECORD +21 -21
- {odoo_addon_sale_blanket_order-16.0.1.0.0.6.dist-info → odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info}/WHEEL +1 -1
- odoo_addon_sale_blanket_order-17.0.1.0.0.2.dist-info/top_level.txt +1 -0
- odoo/addons/sale_blanket_order/readme/CONTRIBUTORS.rst +0 -8
- odoo/addons/sale_blanket_order/readme/DESCRIPTION.rst +0 -4
- odoo/addons/sale_blanket_order/readme/USAGE.rst +0 -53
- odoo_addon_sale_blanket_order-16.0.1.0.0.6.dist-info/METADATA +0 -167
- odoo_addon_sale_blanket_order-16.0.1.0.0.6.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:
|
|
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/
|
|
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-
|
|
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=
|
|
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
|
|
32
|
-
products at a specific price. From a confirmed blanket
|
|
33
|
-
create new sale orders at such price, until the
|
|
34
|
-
due to reaching the validity date or
|
|
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
|
|
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
|
|
48
|
+
To create a new Sale Blanket Order go to the sale menu in the Sales
|
|
49
|
+
section:
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
:alt: Blanket Orders menu
|
|
51
|
+
|image1|
|
|
50
52
|
|
|
51
|
-
Hitting the button create will open the form view in which we can
|
|
52
|
-
information:
|
|
53
|
+
Hitting the button create will open the form view in which we can
|
|
54
|
+
introduce the following information:
|
|
53
55
|
|
|
54
|
-
|
|
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
|
-
|
|
65
|
-
:alt: Blanket Orders form
|
|
58
|
+
- Salesperson
|
|
66
59
|
|
|
67
|
-
|
|
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
|
-
|
|
72
|
-
:alt: Actions that can be done from Blanket Order
|
|
62
|
+
- Validity date
|
|
73
63
|
|
|
74
|
-
|
|
75
|
-
product in the BO lines for which the Sale Order will be created.
|
|
64
|
+
- Order lines:
|
|
76
65
|
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
- Product
|
|
67
|
+
- Accorded price
|
|
68
|
+
- Original, Ordered, Invoiced, Received and Remaining quantities
|
|
79
69
|
|
|
80
|
-
|
|
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
|
-
|
|
85
|
-
:alt: Blanket Order lines and actions
|
|
72
|
+
|image2|
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
93
|
-
|
|
100
|
+
- Closer Validity date
|
|
101
|
+
- Remaining quantity > Quantity introduced in the Sale Order line
|
|
102
|
+
|
|
103
|
+
|image6|
|
|
94
104
|
|
|
95
|
-
..
|
|
96
|
-
|
|
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:%
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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/
|
|
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": "
|
|
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"
|
|
11
|
+
"depends": ["uom", "sale_management"],
|
|
12
12
|
"data": [
|
|
13
13
|
"security/security.xml",
|
|
14
14
|
"security/ir.model.access.csv",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#
|
|
5
5
|
msgid ""
|
|
6
6
|
msgstr ""
|
|
7
|
-
"Project-Id-Version: Odoo Server
|
|
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.
|
|
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.
|
|
137
|
-
msgid "Analytic
|
|
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
|
|
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
|
|
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
|
-
|
|
488
|
-
|
|
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
|
-
|
|
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
|
-
|
|
495
|
-
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
|
561
|
+
def _get_display_price(self):
|
|
567
562
|
# Copied and adapted from the sale module
|
|
568
563
|
self.ensure_one()
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
self.
|
|
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
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
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,
|
|
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(
|
|
611
|
+
self.price_unit = self._get_display_price()
|
|
609
612
|
if self.product_id.code:
|
|
610
|
-
name = "[{}] {
|
|
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(
|
|
740
|
+
return super().write(values)
|
|
@@ -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
|
|
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
|
|
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
|
|
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.
|