diff --git a/odoo/addons/dsrpt_repair_config/__manifest__.py b/odoo/addons/dsrpt_repair_config/__manifest__.py
index 9502f24..80ed437 100644
--- a/odoo/addons/dsrpt_repair_config/__manifest__.py
+++ b/odoo/addons/dsrpt_repair_config/__manifest__.py
@@ -15,6 +15,10 @@
"views/repair_fsm_zone_view_form.xml",
"views/repair_fsm_zone_view_kanban.xml",
"views/repair_fsm_zone_action_main.xml",
+ "views/repair_work_type_view_list.xml",
+ "views/repair_work_type_view_form.xml",
+ "views/repair_work_type_view_kanban.xml",
+ "views/repair_work_type_action_main.xml",
"views/menu.xml",
],
"assets": {
diff --git a/odoo/addons/dsrpt_repair_config/models/__init__.py b/odoo/addons/dsrpt_repair_config/models/__init__.py
index 588c333..f8ab3e7 100644
--- a/odoo/addons/dsrpt_repair_config/models/__init__.py
+++ b/odoo/addons/dsrpt_repair_config/models/__init__.py
@@ -1 +1,2 @@
from . import fsm_zone
+from . import work_type
diff --git a/odoo/addons/dsrpt_repair_config/models/work_type.py b/odoo/addons/dsrpt_repair_config/models/work_type.py
new file mode 100644
index 0000000..f01f635
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_config/models/work_type.py
@@ -0,0 +1,12 @@
+from odoo import fields, models
+
+
+class RepairWorkType(models.Model):
+ _name = "repair.work.type"
+ _description = "Repair Work Type"
+ _order = "name"
+ _inherit = ["mail.thread", "mail.activity.mixin"]
+
+ name = fields.Char(required=True, tracking=True)
+ duration_min = fields.Integer(default=120, required=True, tracking=True)
+ active = fields.Boolean(default=True, tracking=True)
diff --git a/odoo/addons/dsrpt_repair_config/security/ir.model.access.csv b/odoo/addons/dsrpt_repair_config/security/ir.model.access.csv
index 56cc552..6a46944 100644
--- a/odoo/addons/dsrpt_repair_config/security/ir.model.access.csv
+++ b/odoo/addons/dsrpt_repair_config/security/ir.model.access.csv
@@ -1,3 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_repair_fsm_zone_user,repair.fsm.zone user,model_repair_fsm_zone,dsrpt_repair_config.group_dsrpt_repair_config_user,1,1,1,0
access_repair_fsm_zone_manager,repair.fsm.zone manager,model_repair_fsm_zone,dsrpt_repair_config.group_dsrpt_repair_config_manager,1,1,1,1
+access_repair_work_type_user,repair.work.type user,model_repair_work_type,dsrpt_repair_config.group_dsrpt_repair_config_user,1,1,1,0
+access_repair_work_type_manager,repair.work.type manager,model_repair_work_type,dsrpt_repair_config.group_dsrpt_repair_config_manager,1,1,1,1
diff --git a/odoo/addons/dsrpt_repair_config/views/menu.xml b/odoo/addons/dsrpt_repair_config/views/menu.xml
index 53c054f..a01516b 100644
--- a/odoo/addons/dsrpt_repair_config/views/menu.xml
+++ b/odoo/addons/dsrpt_repair_config/views/menu.xml
@@ -13,4 +13,11 @@
10
+
+
diff --git a/odoo/addons/dsrpt_repair_config/views/repair_work_type_action_main.xml b/odoo/addons/dsrpt_repair_config/views/repair_work_type_action_main.xml
new file mode 100644
index 0000000..1901e4b
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_config/views/repair_work_type_action_main.xml
@@ -0,0 +1,8 @@
+
+
+
+ Work Types
+ repair.work.type
+ list,kanban,form
+
+
diff --git a/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_form.xml b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_form.xml
new file mode 100644
index 0000000..87ae727
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_form.xml
@@ -0,0 +1,19 @@
+
+
+
+ repair.work.type.form
+ repair.work.type
+
+
+
+
+
diff --git a/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_kanban.xml b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_kanban.xml
new file mode 100644
index 0000000..d6c4f0e
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_kanban.xml
@@ -0,0 +1,25 @@
+
+
+
+ repair.work.type.kanban
+ repair.work.type
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_list.xml b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_list.xml
new file mode 100644
index 0000000..818f6e3
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_config/views/repair_work_type_view_list.xml
@@ -0,0 +1,14 @@
+
+
+
+ repair.work.type.list
+ repair.work.type
+
+
+
+
+
+
+
+
+
diff --git a/odoo/addons/dsrpt_repair_technicians/models/technician.py b/odoo/addons/dsrpt_repair_technicians/models/technician.py
index df8304a..adace1c 100644
--- a/odoo/addons/dsrpt_repair_technicians/models/technician.py
+++ b/odoo/addons/dsrpt_repair_technicians/models/technician.py
@@ -11,6 +11,8 @@ class RepairTechnician(models.Model):
name = fields.Char(required=True, tracking=True)
user_id = fields.Many2one("res.users", string="User", tracking=True)
zone_ids = fields.Many2many("repair.fsm.zone", string="FSM Zones", tracking=True)
+ work_type_ids = fields.Many2many("repair.work.type", string="Work Types", tracking=True)
+ available_until = fields.Date(string="Available Until", tracking=True)
state = fields.Selection(
selection=[
("draft", "Draft"),
diff --git a/odoo/addons/dsrpt_repair_technicians/security/ir.model.access.csv b/odoo/addons/dsrpt_repair_technicians/security/ir.model.access.csv
index aa7fed1..850cabb 100644
--- a/odoo/addons/dsrpt_repair_technicians/security/ir.model.access.csv
+++ b/odoo/addons/dsrpt_repair_technicians/security/ir.model.access.csv
@@ -5,3 +5,5 @@ access_repair_technician_schedule_user,repair.technician.schedule user,model_rep
access_repair_technician_schedule_manager,repair.technician.schedule manager,model_repair_technician_schedule,dsrpt_repair_technicians.group_dsrpt_repair_technicians_manager,1,1,1,1
access_repair_technician_exception_user,repair.technician.exception user,model_repair_technician_exception,dsrpt_repair_technicians.group_dsrpt_repair_technicians_user,1,1,1,0
access_repair_technician_exception_manager,repair.technician.exception manager,model_repair_technician_exception,dsrpt_repair_technicians.group_dsrpt_repair_technicians_manager,1,1,1,1
+access_repair_work_type_for_technician_user,repair.work.type for technician user,model_repair_work_type,dsrpt_repair_technicians.group_dsrpt_repair_technicians_user,1,0,0,0
+access_repair_work_type_for_technician_manager,repair.work.type for technician manager,model_repair_work_type,dsrpt_repair_technicians.group_dsrpt_repair_technicians_manager,1,0,0,0
diff --git a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_form.xml b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_form.xml
index 21fb04e..a5462a7 100644
--- a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_form.xml
+++ b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_form.xml
@@ -16,6 +16,8 @@
+
+
diff --git a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_kanban.xml b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_kanban.xml
index 00933d9..bb24383 100644
--- a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_kanban.xml
+++ b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_kanban.xml
@@ -8,6 +8,7 @@
+
@@ -21,6 +22,9 @@
+
+
+
diff --git a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_list.xml b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_list.xml
index 169de95..ab62c1d 100644
--- a/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_list.xml
+++ b/odoo/addons/dsrpt_repair_technicians/views/repair_technician_view_list.xml
@@ -8,6 +8,8 @@
+
+
diff --git a/odoo/addons/dsrpt_repair_work_orders/__manifest__.py b/odoo/addons/dsrpt_repair_work_orders/__manifest__.py
index 519aabb..6f7912c 100644
--- a/odoo/addons/dsrpt_repair_work_orders/__manifest__.py
+++ b/odoo/addons/dsrpt_repair_work_orders/__manifest__.py
@@ -16,6 +16,7 @@
"data": [
"security/groups.xml",
"security/ir.model.access.csv",
+ "data/slot_horizon_settings.xml",
"data/sequence.xml",
"views/repair_work_order_view_list.xml",
"views/repair_work_order_view_form.xml",
diff --git a/odoo/addons/dsrpt_repair_work_orders/data/slot_horizon_settings.xml b/odoo/addons/dsrpt_repair_work_orders/data/slot_horizon_settings.xml
new file mode 100644
index 0000000..2dbbc59
--- /dev/null
+++ b/odoo/addons/dsrpt_repair_work_orders/data/slot_horizon_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+ dsrpt_repair_work_orders.slot_horizon_days
+ 15
+
+
diff --git a/odoo/addons/dsrpt_repair_work_orders/models/work_order.py b/odoo/addons/dsrpt_repair_work_orders/models/work_order.py
index 95b1a1d..3b1080d 100644
--- a/odoo/addons/dsrpt_repair_work_orders/models/work_order.py
+++ b/odoo/addons/dsrpt_repair_work_orders/models/work_order.py
@@ -1,4 +1,8 @@
-from odoo import api, fields, models
+from datetime import datetime, time, timedelta
+
+import pytz
+
+from odoo import Command, api, fields, models
from odoo.exceptions import ValidationError
@@ -24,11 +28,20 @@ class RepairWorkOrder(models.Model):
readonly=True,
tracking=True,
)
+ work_type_id = fields.Many2one("repair.work.type", string="Work Type", tracking=True)
description = fields.Text(tracking=True)
requested_datetime = fields.Datetime(default=fields.Datetime.now, tracking=True)
- scheduled_datetime = fields.Datetime(tracking=True)
+ scheduled_datetime = fields.Datetime(string="Scheduled Start", tracking=True)
+ scheduled_end = fields.Datetime(string="Scheduled End", tracking=True)
technician_id = fields.Many2one("repair.technician", tracking=True)
assigned_user_id = fields.Many2one("res.users", related="technician_id.user_id", store=True)
+ slot_day = fields.Date(default=fields.Date.context_today, tracking=True)
+ available_slot_ids = fields.One2many(
+ "repair.work.order.slot",
+ "work_order_id",
+ string="Available Slots",
+ copy=False,
+ )
state = fields.Selection(
selection=[
("draft", "Draft"),
@@ -52,7 +65,24 @@ class RepairWorkOrder(models.Model):
for vals in vals_list:
if vals.get("name", "New") == "New":
vals["name"] = self.env["ir.sequence"].next_by_code("repair.work.order") or "New"
- return super().create(vals_list)
+ records = super().create(vals_list)
+ records._refresh_available_slots_saved()
+ return records
+
+ def write(self, vals):
+ result = super().write(vals)
+ trigger_fields = {
+ "work_type_id",
+ "slot_day",
+ "contact_address_id",
+ "zone_id",
+ "scheduled_datetime",
+ "scheduled_end",
+ "technician_id",
+ }
+ if trigger_fields.intersection(vals):
+ self._refresh_available_slots_saved()
+ return result
def _group_expand_states(self, states, domain, order):
return [key for key, _label in self._fields["state"].selection]
@@ -66,8 +96,7 @@ class RepairWorkOrder(models.Model):
def _find_zone_for_point(self, latitude, longitude):
if latitude is False or longitude is False or latitude is None or longitude is None:
return self.env["repair.fsm.zone"]
- zone_domain = [("state", "=", "active")] if "state" in self.env["repair.fsm.zone"]._fields else []
- zones = self.env["repair.fsm.zone"].search(zone_domain)
+ zones = self.env["repair.fsm.zone"].search([("state", "=", "active")])
for zone in zones:
if zone.contains_point(latitude, longitude):
return zone
@@ -88,6 +117,189 @@ class RepairWorkOrder(models.Model):
if rec.contact_address_id and rec.contact_address_id.contact_id != rec.contact_id:
rec.contact_address_id = False
+ @api.onchange("work_type_id", "slot_day", "contact_address_id", "zone_id")
+ def _onchange_recompute_available_slots(self):
+ for rec in self:
+ slot_values = rec._build_available_slot_values()
+ rec.available_slot_ids = [Command.clear(), *[Command.create(vals) for vals in slot_values]]
+
+ @staticmethod
+ def _merge_intervals(intervals):
+ if not intervals:
+ return []
+ sorted_intervals = sorted(intervals, key=lambda item: item[0])
+ merged = [sorted_intervals[0]]
+ for start_dt, end_dt in sorted_intervals[1:]:
+ last_start, last_end = merged[-1]
+ if start_dt <= last_end:
+ merged[-1] = (last_start, max(last_end, end_dt))
+ else:
+ merged.append((start_dt, end_dt))
+ return merged
+
+ @staticmethod
+ def _subtract_intervals(source, cutouts):
+ if not source:
+ return []
+ if not cutouts:
+ return source
+ result = []
+ for src_start, src_end in source:
+ segments = [(src_start, src_end)]
+ for cut_start, cut_end in cutouts:
+ next_segments = []
+ for seg_start, seg_end in segments:
+ if cut_end <= seg_start or cut_start >= seg_end:
+ next_segments.append((seg_start, seg_end))
+ continue
+ if cut_start > seg_start:
+ next_segments.append((seg_start, min(cut_start, seg_end)))
+ if cut_end < seg_end:
+ next_segments.append((max(cut_end, seg_start), seg_end))
+ segments = next_segments
+ if not segments:
+ break
+ result.extend(segments)
+ return RepairWorkOrder._merge_intervals(result)
+
+ def _get_slot_horizon_days(self):
+ raw_value = self.env["ir.config_parameter"].sudo().get_param("dsrpt_repair_work_orders.slot_horizon_days", "15")
+ try:
+ parsed = int(raw_value)
+ except (TypeError, ValueError):
+ parsed = 15
+ return max(parsed, 1)
+
+ def _is_day_in_horizon(self, day_value):
+ if not day_value:
+ return False
+ today = fields.Date.context_today(self)
+ horizon_end = today + timedelta(days=self._get_slot_horizon_days())
+ return today <= day_value <= horizon_end
+
+ def _day_bounds_utc(self, day_value):
+ user_tz_name = self.env.user.tz or "UTC"
+ user_tz = pytz.timezone(user_tz_name)
+ local_start = user_tz.localize(datetime.combine(day_value, time.min))
+ local_end = local_start + timedelta(days=1)
+ utc_start = local_start.astimezone(pytz.UTC).replace(tzinfo=None)
+ utc_end = local_end.astimezone(pytz.UTC).replace(tzinfo=None)
+ return utc_start, utc_end, user_tz
+
+ @staticmethod
+ def _hour_to_utc(day_value, float_hour, user_tz):
+ minutes = int(round(float(float_hour or 0.0) * 60))
+ local_dt = user_tz.localize(datetime.combine(day_value, time.min) + timedelta(minutes=minutes))
+ return local_dt.astimezone(pytz.UTC).replace(tzinfo=None)
+
+ def _technician_day_availability(self, technician, day_value, day_start_utc, day_end_utc, user_tz):
+ weekday = str(day_value.weekday())
+ base_intervals = []
+ for schedule in technician.schedule_ids.filtered(lambda rec: rec.day_of_week == weekday):
+ start_dt = self._hour_to_utc(day_value, schedule.hour_from, user_tz)
+ end_dt = self._hour_to_utc(day_value, schedule.hour_to, user_tz)
+ if end_dt > start_dt:
+ base_intervals.append((start_dt, end_dt))
+ available = self._merge_intervals(base_intervals)
+ if not available:
+ return []
+
+ exc_domain = [
+ ("technician_id", "=", technician.id),
+ ("start_datetime", "<", day_end_utc),
+ ("end_datetime", ">", day_start_utc),
+ ]
+ exceptions = self.env["repair.technician.exception"].search(exc_domain)
+ negative = []
+ positive = []
+ for exc in exceptions:
+ interval = (max(exc.start_datetime, day_start_utc), min(exc.end_datetime, day_end_utc))
+ if interval[1] <= interval[0]:
+ continue
+ if exc.exception_type == "negative":
+ negative.append(interval)
+ else:
+ positive.append(interval)
+ available = self._subtract_intervals(available, self._merge_intervals(negative))
+ available = self._merge_intervals([*available, *positive])
+
+ busy_domain = [
+ ("technician_id", "=", technician.id),
+ ("scheduled_datetime", "!=", False),
+ ("scheduled_datetime", "<", day_end_utc),
+ ("state", "not in", ["cancelled"]),
+ ]
+ if self.id:
+ busy_domain.append(("id", "!=", self.id))
+ busy_orders = self.env["repair.work.order"].search(busy_domain)
+ busy = []
+ for order in busy_orders:
+ start_dt = order.scheduled_datetime
+ duration_min = order.work_type_id.duration_min or self.work_type_id.duration_min or 120
+ end_dt = order.scheduled_end or (start_dt + timedelta(minutes=duration_min))
+ if end_dt <= day_start_utc or start_dt >= day_end_utc:
+ continue
+ busy.append((max(start_dt, day_start_utc), min(end_dt, day_end_utc)))
+ return self._subtract_intervals(available, self._merge_intervals(busy))
+
+ def _candidate_technicians(self, day_value):
+ domain = [("state", "=", "active")]
+ if self.zone_id:
+ domain.append(("zone_ids", "in", self.zone_id.id))
+ if self.work_type_id:
+ domain.append(("work_type_ids", "in", self.work_type_id.id))
+ if day_value:
+ domain.extend(["|", ("available_until", "=", False), ("available_until", ">=", day_value)])
+ return self.env["repair.technician"].search(domain)
+
+ def _build_available_slot_values(self):
+ self.ensure_one()
+ if not self.work_type_id or not self.zone_id or not self.slot_day:
+ return []
+ if not self._is_day_in_horizon(self.slot_day):
+ return []
+
+ duration = timedelta(minutes=max(self.work_type_id.duration_min or 0, 15))
+ step = timedelta(minutes=30)
+ day_start_utc, day_end_utc, user_tz = self._day_bounds_utc(self.slot_day)
+ technicians = self._candidate_technicians(self.slot_day)
+ candidates = []
+ for technician in technicians:
+ free_intervals = self._technician_day_availability(technician, self.slot_day, day_start_utc, day_end_utc, user_tz)
+ for interval_start, interval_end in free_intervals:
+ cursor = interval_start
+ while cursor + duration <= interval_end:
+ candidates.append(
+ {
+ "technician_id": technician.id,
+ "start_datetime": cursor,
+ "end_datetime": cursor + duration,
+ "duration_min": int(duration.total_seconds() // 60),
+ }
+ )
+ cursor += step
+
+ candidates.sort(key=lambda item: (item["start_datetime"], item["technician_id"]))
+ return candidates[:3]
+
+ def _refresh_available_slots_saved(self):
+ for rec in self:
+ if not rec.id:
+ continue
+ values = rec._build_available_slot_values()
+ rec.available_slot_ids.unlink()
+ if values:
+ self.env["repair.work.order.slot"].create(
+ [
+ {
+ "work_order_id": rec.id,
+ "sequence": index,
+ **slot_vals,
+ }
+ for index, slot_vals in enumerate(values, start=1)
+ ]
+ )
+
def action_confirm(self):
self.write({"state": "confirmed"})
@@ -110,6 +322,42 @@ class RepairWorkOrder(models.Model):
self.write({"state": "draft"})
+class RepairWorkOrderSlot(models.Model):
+ _name = "repair.work.order.slot"
+ _description = "Repair Work Order Available Slot"
+ _order = "sequence, start_datetime, id"
+
+ work_order_id = fields.Many2one("repair.work.order", required=True, ondelete="cascade")
+ sequence = fields.Integer(default=10)
+ technician_id = fields.Many2one("repair.technician", required=True)
+ start_datetime = fields.Datetime(required=True)
+ end_datetime = fields.Datetime(required=True)
+ duration_min = fields.Integer(required=True)
+
+ @api.constrains("start_datetime", "end_datetime")
+ def _check_datetime_order(self):
+ for rec in self:
+ if rec.end_datetime <= rec.start_datetime:
+ raise ValidationError("Slot end must be after slot start.")
+
+ def action_book(self):
+ self.ensure_one()
+ order = self.work_order_id
+ next_state = order.state
+ if order.state in ("draft", "confirmed"):
+ next_state = "assigned"
+ order.write(
+ {
+ "technician_id": self.technician_id.id,
+ "scheduled_datetime": self.start_datetime,
+ "scheduled_end": self.end_datetime,
+ "state": next_state,
+ }
+ )
+ order._refresh_available_slots_saved()
+ return {"type": "ir.actions.client", "tag": "reload"}
+
+
class RepairWorkOrderTime(models.Model):
_name = "repair.work.order.time"
_description = "Repair Work Order Time"
diff --git a/odoo/addons/dsrpt_repair_work_orders/security/ir.model.access.csv b/odoo/addons/dsrpt_repair_work_orders/security/ir.model.access.csv
index cb4163f..427f771 100644
--- a/odoo/addons/dsrpt_repair_work_orders/security/ir.model.access.csv
+++ b/odoo/addons/dsrpt_repair_work_orders/security/ir.model.access.csv
@@ -5,3 +5,7 @@ access_repair_work_order_time_user,repair.work.order.time user,model_repair_work
access_repair_work_order_time_manager,repair.work.order.time manager,model_repair_work_order_time,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_manager,1,1,1,1
access_repair_work_order_material_user,repair.work.order.material user,model_repair_work_order_material,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_user,1,1,1,0
access_repair_work_order_material_manager,repair.work.order.material manager,model_repair_work_order_material,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_manager,1,1,1,1
+access_repair_work_order_slot_user,repair.work.order.slot user,model_repair_work_order_slot,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_user,1,1,1,1
+access_repair_work_order_slot_manager,repair.work.order.slot manager,model_repair_work_order_slot,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_manager,1,1,1,1
+access_repair_work_type_for_work_orders_user,repair.work.type for work orders user,model_repair_work_type,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_user,1,0,0,0
+access_repair_work_type_for_work_orders_manager,repair.work.type for work orders manager,model_repair_work_type,dsrpt_repair_work_orders.group_dsrpt_repair_work_orders_manager,1,0,0,0
diff --git a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_form.xml b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_form.xml
index 788a359..c38dec5 100644
--- a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_form.xml
+++ b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_form.xml
@@ -15,49 +15,65 @@
-
+
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_kanban.xml b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_kanban.xml
index 14ece34..874313e 100644
--- a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_kanban.xml
+++ b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_kanban.xml
@@ -8,7 +8,9 @@
+
+
@@ -23,9 +25,15 @@
+
+
+
+
+
+
diff --git a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_list.xml b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_list.xml
index aac2c14..32c8acd 100644
--- a/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_list.xml
+++ b/odoo/addons/dsrpt_repair_work_orders/views/repair_work_order_view_list.xml
@@ -8,8 +8,10 @@
+
+