Add polygon FSM zones and auto zone detection by coordinates

This commit is contained in:
Ruslan Bakiev
2026-02-13 17:00:37 +07:00
parent d9dd9eeb77
commit 3ad65b0d89
8 changed files with 158 additions and 2 deletions

View File

@@ -10,6 +10,9 @@ class RepairWorkOrder(models.Model):
name = fields.Char(default="New", copy=False, readonly=True, tracking=True)
contact_id = fields.Many2one("dsrpt.contact", required=True, tracking=True)
service_address = fields.Char(tracking=True)
service_latitude = fields.Float(digits=(10, 6), tracking=True)
service_longitude = fields.Float(digits=(10, 6), tracking=True)
zone_id = fields.Many2one("repair.fsm.zone", string="FSM Zone", tracking=True)
description = fields.Text(tracking=True)
requested_datetime = fields.Datetime(default=fields.Datetime.now, tracking=True)
@@ -39,7 +42,15 @@ 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)
for record, vals in zip(records, vals_list):
if vals.get("zone_id"):
continue
if record._has_service_point():
zone = record._find_zone_for_point(record.service_latitude, record.service_longitude)
if zone and record.zone_id != zone:
record.zone_id = zone.id
return records
def _group_expand_states(self, states, domain, order):
return [key for key, _label in self._fields["state"].selection]
@@ -50,6 +61,45 @@ class RepairWorkOrder(models.Model):
rec.total_time_hours = sum(rec.time_line_ids.mapped("hours"))
rec.total_material_cost = sum(rec.material_line_ids.mapped("subtotal"))
def _has_service_point(self):
self.ensure_one()
return self.service_latitude is not False and self.service_longitude is not False
def _find_zone_for_point(self, latitude, longitude):
zones = self.env["repair.fsm.zone"].search([("active", "=", True), ("state", "=", "active")])
for zone in zones:
if zone.contains_point(latitude, longitude):
return zone
return self.env["repair.fsm.zone"]
@api.onchange("service_latitude", "service_longitude")
def _onchange_service_coordinates(self):
for rec in self:
if rec._has_service_point():
zone = rec._find_zone_for_point(rec.service_latitude, rec.service_longitude)
if zone:
rec.zone_id = zone
def action_detect_zone(self):
for rec in self:
if not rec._has_service_point():
raise ValidationError("Service coordinates are required to detect FSM Zone.")
zone = rec._find_zone_for_point(rec.service_latitude, rec.service_longitude)
if not zone:
raise ValidationError("No active FSM Zone contains this point.")
rec.zone_id = zone.id
return True
def write(self, vals):
result = super().write(vals)
if ("service_latitude" in vals or "service_longitude" in vals) and "zone_id" not in vals:
for rec in self:
if rec._has_service_point():
zone = rec._find_zone_for_point(rec.service_latitude, rec.service_longitude)
if zone and rec.zone_id != zone:
super(RepairWorkOrder, rec).write({"zone_id": zone.id})
return result
def action_confirm(self):
self.write({"state": "confirmed"})