Repository: OCA/sale-prebook
Pull request #3: [16.0] [IMP] sale_stock_prebook: Specific picking type for booking
Author: login: lmignon
Labels: name: enhancement
description: New feature or request
name: merged 🎉
Created: 2025-03-14T13:17:35Z | Merged: 2025-03-27T11:16:25Z

* [x] includes #6 

moved from https://github.com/OCA/sale-workflow/pull/3481


Diff:
diff --git a/sale_stock_prebook/__manifest__.py b/sale_stock_prebook/__manifest__.py
index ac99acf..b5a76c2 100644
--- a/sale_stock_prebook/__manifest__.py
+++ b/sale_stock_prebook/__manifest__.py
@@ -9,6 +9,7 @@
     "data": [
         "views/sale_views.xml",
         "views/stock_route_views.xml",
+        "views/stock_rule_views.xml",
     ],
     "depends": [
         "sale_stock",
diff --git a/sale_stock_prebook/models/stock_rule.py b/sale_stock_prebook/models/stock_rule.py
index 07cfd5d..81e3231 100644
--- a/sale_stock_prebook/models/stock_rule.py
+++ b/sale_stock_prebook/models/stock_rule.py
@@ -1,11 +1,46 @@
 # Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
 # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
-from odoo import models
+from odoo import fields, models
 
 
 class StockRule(models.Model):
     _inherit = "stock.rule"
 
+    prebook_picking_type_id = fields.Many2one(
+        "stock.picking.type",
+        "Operation Type for Prebooking",
+        required=False,
+        check_company=True,
+        domain="[('code', '=?', picking_type_code_domain)]",
+        help="This operation type will be used for prebooking stock for sale orders. "
+        "It's therefore only relevant for rules that are used for sale order lines.",
+    )
+
+    def _get_stock_move_values(
+        self,
+        product_id,
+        product_qty,
+        product_uom,
+        location_dest_id,
+        name,
+        origin,
+        company_id,
+        values,
+    ):
+        res = super()._get_stock_move_values(
+            product_id,
+            product_qty,
+            product_uom,
+            location_dest_id,
+            name,
+            origin,
+            company_id,
+            values,
+        )
+        if values.get("used_for_sale_reservation") and self.prebook_picking_type_id:
+            res["picking_type_id"] = self.prebook_picking_type_id.id
+        return res
+
     def _get_custom_move_fields(self):
         res = super()._get_custom_move_fields()
         res.append("used_for_sale_reservation")
diff --git a/sale_stock_prebook/tests/common.py b/sale_stock_prebook/tests/common.py
index 82367e3..5c8ca35 100644
--- a/sale_stock_prebook/tests/common.py
+++ b/sale_stock_prebook/tests/common.py
@@ -20,6 +20,11 @@ def setUpClass(cls):
                 }
             )
         )
+        cls.warehouse = cls.env.ref("stock.warehouse0")
+        cls.deliver_route = cls.warehouse.delivery_route_id
+        cls.prebook_picking_type = cls.env.ref("stock.picking_type_out").copy(
+            {"name": "Prebook"}
+        )
         # prebook product
         product_form = Form(cls.env["product.product"])
         product_form.name = "Test Product 1"
diff --git a/sale_stock_prebook/tests/test_sale_stock_prebook.py b/sale_stock_prebook/tests/test_sale_stock_prebook.py
index d2f31de..8ef2c7b 100644
--- a/sale_stock_prebook/tests/test_sale_stock_prebook.py
+++ b/sale_stock_prebook/tests/test_sale_stock_prebook.py
@@ -52,3 +52,12 @@ def test_50_process_move(self):
         self.sale.reserve_stock()
         with self.assertRaisesRegex(ValidationError, "You cannot set a quantity done"):
             self.sale.picking_ids.move_ids.quantity_done = 3
+
+    def test_60_prebook_dedicatd_picking_type(self):
+        self.deliver_route.rule_ids.write(
+            {"prebook_picking_type_id": self.prebook_picking_type.id}
+        )
+        self.sale.reserve_stock()
+        self.assertEqual(
+            self.sale.picking_ids.picking_type_id, self.prebook_picking_type
+        )
diff --git a/sale_stock_prebook/views/stock_rule_views.xml b/sale_stock_prebook/views/stock_rule_views.xml
new file mode 100644
index 0000000..cdaa083
--- /dev/null
+++ b/sale_stock_prebook/views/stock_rule_views.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<odoo>
+    <record id="view_stock_rule_form" model="ir.ui.view">
+        <field name="name">stock.rule.form</field>
+        <field name="inherit_id" ref="stock.view_stock_rule_form" />
+        <field name="model">stock.rule</field>
+        <field name="arch" type="xml">
+            <field name="picking_type_id" position="after">
+                <field
+                    name="prebook_picking_type_id"
+                    string="Prebook Picking Type"
+                    options="{'no_create': True}"
+                />
+            </field>
+        </field>
+    </record>
+
+</odoo>


Reviews:
user: login: rousseldenis
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-18T07:42:38Z
user: login: rousseldenis
body: Minor comment
state: APPROVED
author_association: NONE
submitted_at: 2025-03-18T07:43:04Z
user: login: lmignon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T08:27:04Z

Review comments:
diff_hunk: @@ -1,11 +1,46 @@
 # Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
 # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
-from odoo import models
+from odoo import fields, models
 
 
 class StockRule(models.Model):
     _inherit = "stock.rule"
 
+    prebook_picking_type_id = fields.Many2one(
path: sale_stock_prebook/models/stock_rule.py
user: login: rousseldenis
body: Couldn't this name be specific to sale ? `sale_prebook_picking_type_id` 
created_at: 2025-03-18T07:42:38Z
author_association: NONE
diff_hunk: @@ -1,11 +1,46 @@
 # Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
 # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
-from odoo import models
+from odoo import fields, models
 
 
 class StockRule(models.Model):
     _inherit = "stock.rule"
 
+    prebook_picking_type_id = fields.Many2one(
path: sale_stock_prebook/models/stock_rule.py
user: login: lmignon
body: IMO no since this mechanism can be used by hand outside the sale process
created_at: 2025-03-18T08:27:04Z
author_association: CONTRIBUTOR

PR comments:
user: login: lmignon
created_at: 2025-03-27T11:10:52Z
body: /ocabot merge nobump
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:10:58Z
body: What a great day to merge this nice PR. Let's do it!
Prepared branch [16.0-ocabot-merge-pr-3-by-lmignon-bump-nobump](https://github.com/OCA/sale-prebook/commits/16.0-ocabot-merge-pr-3-by-lmignon-bump-nobump), awaiting test results.
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:11:27Z
body: @lmignon your merge command was aborted due to failed check(s), which you can inspect on [this commit of 16.0-ocabot-merge-pr-3-by-lmignon-bump-nobump](https://github.com/OCA/sale-prebook/commits/456a5bec9fc9fc7567812d7a5adad3bb99962956).

After fixing the problem, you can re-issue a merge command. Please refrain from merging manually as it will most probably make the target branch red.
author_association: CONTRIBUTOR
user: login: lmignon
created_at: 2025-03-27T11:11:33Z
body: /ocabot merge minor
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:11:38Z
body: On my way to merge this fine PR!
Prepared branch [16.0-ocabot-merge-pr-3-by-lmignon-bump-minor](https://github.com/OCA/sale-prebook/commits/16.0-ocabot-merge-pr-3-by-lmignon-bump-minor), awaiting test results.
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:12:03Z
body: @lmignon your merge command was aborted due to failed check(s), which you can inspect on [this commit of 16.0-ocabot-merge-pr-3-by-lmignon-bump-minor](https://github.com/OCA/sale-prebook/commits/c4e50fa858a337b75d4b19210dcaf6b403c2ec4b).

After fixing the problem, you can re-issue a merge command. Please refrain from merging manually as it will most probably make the target branch red.
author_association: CONTRIBUTOR
user: login: lmignon
created_at: 2025-03-27T11:12:16Z
body: /ocabot merge major
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:12:22Z
body: This PR looks fantastic, let's merge it!
Prepared branch [16.0-ocabot-merge-pr-3-by-lmignon-bump-major](https://github.com/OCA/sale-prebook/commits/16.0-ocabot-merge-pr-3-by-lmignon-bump-major), awaiting test results.
author_association: CONTRIBUTOR
user: login: lmignon
created_at: 2025-03-27T11:12:49Z
body: > /ocabot merge major

new column -> new major version
author_association: CONTRIBUTOR
user: login: OCA-git-bot
created_at: 2025-03-27T11:16:26Z
body: Congratulations, your PR was merged at 4285925b3f373d8318b7ff3bf0cc97159d270902. Thanks a lot for contributing to OCA. ❤️
author_association: CONTRIBUTOR