diff --git a/fieldservice_equipment_stock/__manifest__.py b/fieldservice_equipment_stock/__manifest__.py
index 6de0db40e0..c9911683d0 100644
--- a/fieldservice_equipment_stock/__manifest__.py
+++ b/fieldservice_equipment_stock/__manifest__.py
@@ -15,7 +15,10 @@
],
"data": [
"security/ir.model.access.csv",
+ "data/fsm_order_type.xml",
"views/fsm_equipment.xml",
+ "views/fsm_order_view.xml",
+ "views/fsm_order_type_view.xml",
"views/product_template.xml",
"views/stock_picking_type.xml",
"views/stock_lot.xml",
diff --git a/fieldservice_equipment_stock/data/fsm_order_type.xml b/fieldservice_equipment_stock/data/fsm_order_type.xml
new file mode 100644
index 0000000000..39d0acb902
--- /dev/null
+++ b/fieldservice_equipment_stock/data/fsm_order_type.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Return
+ return
+
+
+
diff --git a/fieldservice_equipment_stock/models/__init__.py b/fieldservice_equipment_stock/models/__init__.py
index cbea216dc5..3328284837 100644
--- a/fieldservice_equipment_stock/models/__init__.py
+++ b/fieldservice_equipment_stock/models/__init__.py
@@ -2,6 +2,8 @@
stock_move,
stock_picking_type,
fsm_equipment,
+ fsm_order,
+ fsm_order_type,
product_template,
stock_lot,
)
diff --git a/fieldservice_equipment_stock/models/fsm_equipment.py b/fieldservice_equipment_stock/models/fsm_equipment.py
index 9c50770efa..bbb91fa6d1 100644
--- a/fieldservice_equipment_stock/models/fsm_equipment.py
+++ b/fieldservice_equipment_stock/models/fsm_equipment.py
@@ -44,3 +44,17 @@ def write(self, vals):
if "lot_id" in vals:
equipment.lot_id.fsm_equipment_id = equipment.id
return res
+
+ def create_equip_order_return(self):
+ self.ensure_one()
+ order_type = self.env.ref("fieldservice_equipment_stock.fsm_order_type_return")
+ return {
+ "name": "Return Equipment",
+ "type": "ir.actions.act_window",
+ "res_model": "fsm.order",
+ "view_mode": "form",
+ "context": {
+ "default_equipment_id": self.id,
+ "default_type": order_type and order_type.id or False,
+ },
+ }
diff --git a/fieldservice_equipment_stock/models/fsm_order.py b/fieldservice_equipment_stock/models/fsm_order.py
new file mode 100644
index 0000000000..e82519761a
--- /dev/null
+++ b/fieldservice_equipment_stock/models/fsm_order.py
@@ -0,0 +1,78 @@
+# Copyright 2024 Camptocamp
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import _, api, models
+from odoo.exceptions import ValidationError
+
+
+class FSMOrder(models.Model):
+ _inherit = "fsm.order"
+
+ def _prepare_return_procurement_group_values(self):
+ return {
+ "name": self.display_name,
+ "fsm_order_id": self.id,
+ "move_type": "direct",
+ }
+
+ def _prepare_return_stock_picking_values(self):
+ source_location_id = self._get_equipment_current_location()
+ return {
+ "picking_type_id": self.type.picking_type_id.id,
+ "origin": self.display_name,
+ "location_dest_id": self.type.picking_type_id.default_location_dest_id.id,
+ "location_id": source_location_id and source_location_id.id,
+ "fsm_order_id": self.id,
+ "group_id": self.procurement_group_id.id,
+ }
+
+ def _prepare_return_stock_move_values(self):
+ source_location_id = self._get_equipment_current_location()
+ return {
+ "name": self.display_name,
+ "product_id": self.equipment_id.product_id.id,
+ "product_uom_qty": 1,
+ "product_uom": self.equipment_id.product_id.uom_id.id,
+ "location_id": source_location_id.id,
+ "location_dest_id": self.type.picking_type_id.default_location_dest_id.id,
+ "group_id": self.procurement_group_id.id,
+ "fsm_order_id": self.id,
+ "lot_ids": [(4, self.equipment_id.lot_id.id)]
+ if self.equipment_id.lot_id
+ else False,
+ }
+
+ def _get_equipment_current_location(self):
+ self.ensure_one()
+ return self.equipment_id and self.equipment_id.location_id.inventory_location_id
+
+ @api.model
+ def create(self, vals):
+ # if FSM order with type return is created then
+ # create a picking order
+ order = super().create(vals)
+ if order.type.internal_type == "return":
+ if order.equipment_id and order.type.picking_type_id:
+ group = self.env["procurement.group"].search(
+ [("fsm_order_id", "=", order.id)]
+ )
+ if not group:
+ values = order._prepare_return_procurement_group_values()
+ group = self.env["procurement.group"].create(values)
+ order.procurement_group_id = group and group.id
+ return_picking_values = order._prepare_return_stock_picking_values()
+ new_picking = self.env["stock.picking"].create(return_picking_values)
+ return_move_values = order._prepare_return_stock_move_values()
+ return_move_values["picking_id"] = new_picking.id
+ self.env["stock.move"].create(return_move_values)
+ new_picking.action_confirm()
+
+ elif not order.type.picking_type_id:
+ raise ValidationError(
+ _(
+ "Cannot create Return Order because "
+ "order type does not have a current "
+ "Picking Type."
+ )
+ )
+ return order
diff --git a/fieldservice_equipment_stock/models/fsm_order_type.py b/fieldservice_equipment_stock/models/fsm_order_type.py
new file mode 100644
index 0000000000..f23eacd5ba
--- /dev/null
+++ b/fieldservice_equipment_stock/models/fsm_order_type.py
@@ -0,0 +1,16 @@
+# Copyright 2024 Camptocamp
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class FsmOrderType(models.Model):
+ _inherit = "fsm.order.type"
+
+ internal_type = fields.Selection(
+ selection_add=[("return", "Return")],
+ )
+ picking_type_id = fields.Many2one(
+ "stock.picking.type",
+ domain=[("code", "=", "incoming")],
+ )
diff --git a/fieldservice_equipment_stock/static/description/index.html b/fieldservice_equipment_stock/static/description/index.html
index 05d72795eb..198050d110 100644
--- a/fieldservice_equipment_stock/static/description/index.html
+++ b/fieldservice_equipment_stock/static/description/index.html
@@ -8,11 +8,10 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
+:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
-Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -275,7 +274,7 @@
margin-left: 2em ;
margin-right: 2em }
-pre.code .ln { color: gray; } /* line numbers */
+pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +300,7 @@
span.pre {
white-space: pre }
-span.problematic, pre.problematic {
+span.problematic {
color: red }
span.section-subtitle {
@@ -461,9 +460,7 @@
This module is maintained by the OCA.
-
-
-
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
diff --git a/fieldservice_equipment_stock/views/fsm_equipment.xml b/fieldservice_equipment_stock/views/fsm_equipment.xml
index a92a59a0d9..cde1758113 100644
--- a/fieldservice_equipment_stock/views/fsm_equipment.xml
+++ b/fieldservice_equipment_stock/views/fsm_equipment.xml
@@ -5,6 +5,15 @@
fsm.equipment
+
+
+
diff --git a/fieldservice_equipment_stock/views/fsm_order_type_view.xml b/fieldservice_equipment_stock/views/fsm_order_type_view.xml
new file mode 100644
index 0000000000..dea98a8d11
--- /dev/null
+++ b/fieldservice_equipment_stock/views/fsm_order_type_view.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ fsm.order.type
+
+
+
+
+
+
+
+
+
diff --git a/fieldservice_equipment_stock/views/fsm_order_view.xml b/fieldservice_equipment_stock/views/fsm_order_view.xml
new file mode 100644
index 0000000000..9fb54e8561
--- /dev/null
+++ b/fieldservice_equipment_stock/views/fsm_order_view.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ fsm.order
+
+
+
+ internal_type not in ['repair', 'maintenance', 'return']
+ internal_type in ['return']
+
+
+
+
+