Skip to content

Commit 50d7120

Browse files
committed
[IMP] estate: implement property maintenance management workflow-Group-task
Implemented a dedicated property maintenance model to manage and track maintenance issues linked with properties. Added computed fields for priority and estimated costs based on issue types, along with validation to ensure actual costs are entered before completing maintenance tasks. Introduced a state-based workflow with actions for issue creation, progress tracking, and completion. Added list and form views with statusbar navigation, technician assignment, and maintenance cost details for efficient property service management. Ref-Group task
1 parent cf6b343 commit 50d7120

9 files changed

Lines changed: 196 additions & 1 deletion

estate/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"views/estate_property_offer_views.xml",
1313
"views/estate_property_type_views.xml",
1414
"views/estate_property_tag_views.xml",
15+
"views/estate_property_maintenance_views.xml",
1516
"views/estate_menus.xml",
1617
"views/res_users_views.xml",
1718
],

estate/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
from . import estate_property_type
33
from . import estate_property_tag
44
from . import estate_property_offer
5+
from . import estate_property_maintenance
56
from . import res_users

estate/models/estate_property.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class EstateProperty(models.Model):
7373
"property_id",
7474
string="Offer",
7575
)
76+
issue_ids = fields.One2many(
77+
"estate.property.maintenance",
78+
"property_id"
79+
)
7680

7781
_check_expected_price = models.Constraint(
7882
"CHECK(expected_price>0)", "Expected price must be strictly positive"
@@ -81,7 +85,7 @@ class EstateProperty(models.Model):
8185
_check_selling_price = models.Constraint(
8286
"CHECK(selling_price>0)", "Selling price must be positive"
8387
)
84-
88+
8589
@api.depends("living_area", "garden_area")
8690
def _compute_total(self):
8791
for record in self:
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from odoo import api, fields, models, _
2+
from odoo.exceptions import ValidationError
3+
4+
5+
class EstatePropertyMaintenance(models.Model):
6+
_name = "estate.property.maintenance"
7+
_description = "Property maintenance"
8+
9+
property_id = fields.Many2one(
10+
'estate.property',
11+
string="Property",
12+
required=True
13+
)
14+
15+
issue_type = fields.Selection(
16+
[
17+
('waterleakage', 'Water leakage'),
18+
('electrical', 'Electrical'),
19+
('plumber', 'Plumbing'),
20+
('structure', 'Structural')
21+
]
22+
)
23+
description = fields.Text()
24+
priority = fields.Selection(
25+
[
26+
('low', 'Low'),
27+
('medium', 'Medium'),
28+
('high', 'High')
29+
],
30+
string="Priority",
31+
compute="_compute_priority",
32+
store=True
33+
)
34+
state = fields.Selection(
35+
[
36+
('new', 'New'),
37+
('assign', 'Assign'),
38+
('wip', "WIP"),
39+
('complete', 'Complete'),
40+
],
41+
default='new'
42+
)
43+
date = fields.Date(default=fields.Date.today())
44+
estimated_cost = fields.Integer(compute="_compute_estimated_cost")
45+
actual_cost = fields.Integer()
46+
technician = fields.Many2one(
47+
'res.users',
48+
string="Assign To",
49+
)
50+
total_actual_cost = fields.Integer(
51+
compute="_compute_total_actual_cost",
52+
)
53+
54+
@api.depends("issue_type")
55+
def _compute_estimated_cost(self):
56+
for record in self:
57+
if record.issue_type == 'waterleakage':
58+
record.estimated_cost = 10000
59+
elif record.issue_type == 'electrical':
60+
record.estimated_cost = 20000
61+
elif record.issue_type == 'structure':
62+
record.estimated_cost = 50000
63+
elif record.issue_type == 'plumber':
64+
record.estimated_cost = 30000
65+
else:
66+
record.estimated_cost = 0
67+
68+
@api.depends("issue_type")
69+
def _compute_priority(self):
70+
for record in self:
71+
if record.issue_type == 'structure':
72+
record.priority = 'high'
73+
elif record.issue_type == 'electrical':
74+
record.priority = 'medium'
75+
else:
76+
record.priority = 'low'
77+
78+
@api.constrains('state', 'actual_cost')
79+
def _check_actual_cost(self):
80+
for record in self:
81+
if record.state == 'complete' and (not record.actual_cost or record.actual_cost <= 0):
82+
raise ValidationError(_(
83+
"Actual Cost must be fill before marking the maintenance as Done."
84+
))
85+
86+
@api.depends('property_id', 'actual_cost')
87+
def _compute_total_actual_cost(self):
88+
for record in self:
89+
if record.property_id:
90+
maintenance = self.search([
91+
('property_id', '=', record.property_id.id)
92+
])
93+
record.total_actual_cost = sum(
94+
maintenance.mapped('actual_cost'))
95+
else:
96+
record.total_actual_cost = 0
97+
98+
def action_create_issue(self):
99+
for records in self:
100+
records.state = 'assign'
101+
records.technician = self.env.user
102+
return True
103+
104+
def action_inprogress_issue(self):
105+
for records in self:
106+
records.state = 'wip'
107+
return True
108+
109+
def action_done_issue(self):
110+
for records in self:
111+
records.state = 'complete'
112+
return True

estate/models/estate_property_offer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def create(self, vals_list):
8181
def action_confirm(self):
8282
for offer in self.property_id.offer_ids:
8383
if self != offer and offer.status == 'accepted':
84+
offer
8485
raise UserError(_("An offer is already accepted."))
8586
self.status = "accepted"
8687
self.property_id.state = "offer_accepted"

estate/security/ir.model.access.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ access_estate_property,access_estate_property,model_estate_property,base.group_u
33
access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1
44
access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1
55
access_estate_property_offer,access_estate_property_offer,model_estate_property_offer,base.group_user,1,1,1,1
6+
access_estate_property_maintenance,access_estate_property_maintenance,model_estate_property_maintenance,base.group_user,1,1,1,1

estate/views/estate_menus.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@
3636
parent="estate_property_type_menu"
3737
action="estate_property_tag_action"
3838
/>
39+
<menuitem
40+
id="estate_property_maintenance_menu"
41+
name="Property Maintenance"
42+
parent="estate_property_type_menu"
43+
action="estate_property_maintenance_action"
44+
/>
3945
</odoo>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<odoo>
2+
<record id="estate_property_maintenance_view_list" model="ir.ui.view">
3+
<field name="name">estate.property.maintenance.view.list</field>
4+
<field name="model">estate.property.maintenance</field>
5+
<field name="arch" type="xml">
6+
<list>
7+
<field name="property_id" />
8+
<field name="issue_type" />
9+
<field name="description" />
10+
<field name="priority" />
11+
<field name="state" />
12+
<field name="date" />
13+
<field name="estimated_cost" />
14+
<field name="actual_cost" />
15+
</list>
16+
</field>
17+
</record>
18+
19+
<record id="estate_property_maintenance_view_form" model="ir.ui.view">
20+
<field name="name">estate.property.maintenance.view.form</field>
21+
<field name="model">estate.property.maintenance</field>
22+
<field name="arch" type="xml">
23+
<form>
24+
<header>
25+
<button name="action_create_issue" type="object" string="Create Issue" class="btn-primary" invisible="state in ('assign','wip','complete')"/>
26+
<button name="action_inprogress_issue" type="object" string="In Progress" class="btn-primary" invisible="state != 'assign' "/>
27+
<button name="action_done_issue" type="object" string="Done" class="btn-primary" invisible="state != 'wip' " />
28+
<field name="state" widget="statusbar" />
29+
</header>
30+
<sheet>
31+
<group>
32+
<field name="property_id" />
33+
<field name="issue_type" />
34+
<field name="description" />
35+
<field name="priority" />
36+
<field name="date" />
37+
<field name="estimated_cost" />
38+
<field name="actual_cost" />
39+
</group>
40+
<notebook>
41+
<page string="Assign">
42+
<group>
43+
<field name="technician" />
44+
</group>
45+
</page>
46+
</notebook>
47+
</sheet>
48+
</form>
49+
</field>
50+
</record>
51+
52+
<record id="estate_property_maintenance_action" model="ir.actions.act_window">
53+
<field name="name">Property Maintenance</field>
54+
<field name="res_model">estate.property.maintenance</field>
55+
<field name="view_mode">list,form</field>
56+
</record>
57+
</odoo>

estate/views/estate_property_views.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@
112112
<field name="salesperson_id" />
113113
</group>
114114
</page>
115+
<page string="Maintenance status">
116+
<field name="issue_ids">
117+
<list>
118+
<field name="issue_type" />
119+
<field name="description" />
120+
<field name="priority" />
121+
<field name="date" />
122+
<field name="actual_cost" />
123+
<field name="total_actual_cost" readonly="1"/>
124+
</list>
125+
</field>
126+
</page>
115127
</notebook>
116128
</sheet>
117129
</form>

0 commit comments

Comments
 (0)