Skip to content

Commit d7e6602

Browse files
committed
[IMP] estate: Added Inheritance to module and created estate account module
Applied model and view inheritance patterns to extend core functionality Enabled interactions between modules for enhanced business workflows Updated business logic to support new integration features
1 parent c67201f commit d7e6602

15 files changed

+176
-69
lines changed

awesome_gallery/models/ir_action.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ class ActWindowView(models.Model):
77

88
view_mode = fields.Selection(selection_add=[
99
('gallery', "Awesome Gallery")
10-
], ondelete={'gallery': 'cascade'})
10+
], ondelete = {'gallery':'cascade'})

estate/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from . import models
1+
from . import models

estate/__manifest__.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
{
2-
'name':"Real Estate",
3-
'summary':"This is real estate module",
4-
'category':"Tutorials",
5-
'description':"This is real estate module",
6-
'author':"Dhruvrajsinh Zala (zadh)",
2+
'name': "Real Estate",
3+
'summary': "This is real estate module",
4+
'category': "Tutorials",
5+
'description': "This is real estate module",
6+
'author': "Dhruvrajsinh Zala (zadh)",
77
'installable': True,
88
'application': True,
9-
'data':['security/ir.model.access.csv', 'views/estate_property_offers.xml',
9+
'data': ['security/ir.model.access.csv',
1010
'views/estate_property_views.xml',
11-
'views/estate_menus.xml',
12-
'views/estate_property_type_views.xml','views/estate_property_tags.xml']
13-
}
11+
'views/estate_property_offers.xml',
12+
'views/estate_property_type_views.xml',
13+
'views/estate_property_tags.xml',
14+
'views/res_users_views.xml',
15+
'views/estate_menus.xml'],
16+
'license': 'AGPL-3'
17+
}

estate/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from . import esatate_property_type
33
from . import estate_property_tags
44
from . import estate_property_offer
5+
from . import inherited_res_users
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
from odoo import models,fields,api
2-
1+
from odoo import models, fields, api
32

43
class EstatePropertyTyeps(models.Model):
5-
_name="estate.property.types"
6-
_description="Types of Estate Property"
7-
_order="sequence,name"
84

9-
_unique_type_name = models.Constraint('UNIQUE(name)','Property type name must be unique.')
5+
_name = "estate.property.types"
6+
_description = "Types of Estate Property"
7+
_order = "sequence,name"
8+
9+
_sql_constraints = [('_unique_type_name', 'UNIQUE(name)', 'Property type name must be unique.')]
1010

11-
name=fields.Char(required=True)
12-
property_ids=fields.One2many('estate.property','property_type_id',string="Properties")
11+
name = fields.Char(required=True)
12+
property_ids = fields.One2many('estate.property', 'property_type_id', string="Properties")
1313
sequence = fields.Integer(default=1)
1414

1515
offer_ids = fields.One2many(
@@ -18,7 +18,6 @@ class EstatePropertyTyeps(models.Model):
1818
string="Offers"
1919
)
2020

21-
2221
offer_count = fields.Integer(
2322
string="Offer Count",
2423
compute='_compute_offer_count',
@@ -28,4 +27,4 @@ class EstatePropertyTyeps(models.Model):
2827
@api.depends('offer_ids')
2928
def _compute_offer_count(self):
3029
for record in self:
31-
record.offer_count = len(record.offer_ids)
30+
record.offer_count = len(record.offer_ids)

estate/models/estate_property.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
from dateutil.relativedelta import relativedelta
2-
from odoo import models,fields,api,_
3-
from odoo.tools.float_utils import float_compare,float_is_zero
4-
from odoo.exceptions import UserError,ValidationError
2+
from odoo import models, fields, api, _
3+
from odoo.tools.float_utils import float_compare, float_is_zero
4+
from odoo.exceptions import UserError, ValidationError
55

66
class EstateProperty(models.Model):
7+
8+
79
_name = 'estate.property'
810
_description = 'Real Estate Property'
911
_order = 'id desc'
1012

13+
_sql_constraints = [('_check_expected_price', 'CHECK(expected_price > 0)', 'The expected price must be positive.'), ('_check_selling_price', 'CHECK(selling_price >= 0)', 'The selling price must be positive.')]
1114

12-
_check_expected_price = models.Constraint('CHECK(expected_price > 0)','The expected price must be positive.')
13-
_check_selling_price = models.Constraint('CHECK(selling_price >= 0)','The selling price must be positive.')
14-
15-
name = fields.Char(required=True,string="Title")
15+
name = fields.Char(required=True, string="Title")
1616
description = fields.Text()
1717
postcode = fields.Char()
1818
date_availability = fields.Date(
19-
default=lambda self: fields.Date.today() + relativedelta(months=3),
20-
copy=False,string="Available From")
19+
default = lambda self: fields.Date.today() + relativedelta(months=3),
20+
copy = False,string="Available From")
2121
expected_price = fields.Float(required=True)
2222
selling_price = fields.Float(readonly=True,copy=False)
2323
bedrooms = fields.Integer(default=2)
2424
living_area = fields.Integer(string="Living Area (sqm)")
25-
total_area = fields.Float(compute='_compute_total_area',store=True)
25+
total_area = fields.Float(compute='_compute_total_area', store=True)
2626
facades = fields.Integer()
27-
garage = fields.Boolean()
27+
garage = fields.Boolean()
2828
garden = fields.Boolean()
2929
garden_area = fields.Integer(string="Garden Area (sqm)")
3030
active = fields.Boolean(default=True)
3131
garden_orientation = fields.Selection([
32-
('north','North'),
33-
('south','South'),
34-
('east','East'),
35-
('west','West')
32+
('north', 'North'),
33+
('south', 'South'),
34+
('east', 'East'),
35+
('west', 'West')
3636
],string="Garden Orientation")
3737
state = fields.Selection(
3838
[
@@ -44,7 +44,7 @@ class EstateProperty(models.Model):
4444
],
4545
required=True,
4646
copy=False,
47-
default='new')
47+
default = 'new')
4848
property_type_id = fields.Many2one(
4949
"estate.property.types", string="Property Type"
5050
)
@@ -54,12 +54,18 @@ class EstateProperty(models.Model):
5454
salesperson_id = fields.Many2one(
5555
"res.users", string="Salesperson", default=lambda self: self.env.user
5656
)
57-
tag_ids = fields.Many2many('estate.property.tags',string="Tags")
57+
tag_ids = fields.Many2many('estate.property.tags', string="Tags")
5858

59-
offer_ids = fields.One2many('estate.property.offer','property_id',string="Offers")
59+
offer_ids = fields.One2many('estate.property.offer','property_id', string="Offers")
6060

6161
best_price = fields.Float(compute='_get_best_offer_price',store=True)
6262

63+
@api.ondelete(at_uninstall=False)
64+
def _unlink_except_state_new_or_cancelled(self):
65+
for record in self:
66+
if record.state not in ['new','cancelled']:
67+
raise UserError(_("You can only delete properties in 'New' or 'Cancelled' state."))
68+
6369
@api.depends("living_area","garden_area")
6470
def _compute_total_area(self):
6571
for record in self:
@@ -83,15 +89,15 @@ def _onchange_garden(self):
8389

8490
def action_set_state_sold(self):
8591
for record in self:
86-
if(record.state == 'cancelled'):
92+
if record.state == 'cancelled':
8793
raise UserError(_("Cancelled property cannot be sold."))
8894
else:
8995
record.state = 'sold'
9096
return True
9197

9298
def action_set_state_cancel(self):
9399
for record in self:
94-
if(record.state == 'sold'):
100+
if record.state == 'sold':
95101
raise UserError(_("Sold property cannot be cancelled."))
96102
else:
97103
record.state = 'cancelled'
@@ -105,6 +111,4 @@ def _check_selling_price(self):
105111
record.selling_price,
106112
record.expected_price * 0.9,
107113
precision_digits=2) < 0 :
108-
raise ValidationError(_("The selling price cannot be lower than 90% of the expected price"))
109-
110-
114+
raise ValidationError(_("The selling price cannot be lower than 90% of the expected price"))

estate/models/estate_property_offer.py

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,56 @@
1-
from odoo import fields,models,api,_
1+
from odoo import fields, models, api, _
22
from odoo.exceptions import UserError
3-
from datetime import timedelta,datetime
3+
from datetime import timedelta, datetime
44

55
class EstatePropertyOffer(models.Model):
6-
_name="estate.property.offer"
7-
_description="Offers of Estate Property"
8-
_order = 'price desc'
96

10-
_check_offer_price = models.Constraint('CHECK(price > 0)','The Offer price must be positive.')
7+
_name = "estate.property.offer"
8+
_description = "Offers of Estate Property"
9+
_order = 'price desc'
10+
_sql_constraints = [('_check_offer_price', 'CHECK(price > 0)', 'The Offer price must be positive.')]
1111

1212
price = fields.Float()
13-
status = fields.Selection([('accepted','Accepted'),('refused','Refused')],copy=False)
14-
partner_id = fields.Many2one('res.partner',string="Partner",required=True)
15-
property_id = fields.Many2one('estate.property',string="Property",required=True)
13+
status = fields.Selection([('accepted', 'Accepted'), ('refused', 'Refused')], copy=False)
14+
partner_id = fields.Many2one('res.partner', string="Partner", required=True)
15+
property_id = fields.Many2one('estate.property', string="Property", required=True)
1616
property_type_id = fields.Many2one(
1717
'estate.property.types',
18-
related="property_id.property_type_id",
19-
string="Property Type",
20-
required=True)
21-
18+
related = "property_id.property_type_id",
19+
string = "Property Type",
20+
required = True)
2221
validity = fields.Integer(default=7)
23-
date_deadline = fields.Date(compute="_compute_deadline",inverse="_inverse_deadline",store=True)
22+
date_deadline = fields.Date(compute="_compute_deadline", inverse="_inverse_deadline", store=True)
23+
24+
@api.model_create_multi
25+
def create(self,vals):
26+
27+
for val in vals:
28+
property_id = val['property_id']
29+
offer_price = val['price']
30+
is_state_new = self.env['estate.property'].browse(property_id).state == 'new'
31+
32+
result = self.read_group(
33+
domain=[('property_id','=',property_id)],
34+
fields=['price:max'],
35+
groupby=[]
36+
)
37+
38+
max_price = result[0]['price'] if result else 0
39+
40+
if max_price >= offer_price:
41+
raise UserError(_("You cannot create an offer with a lower or equal amount than an existing offer for this property."))
42+
43+
if is_state_new:
44+
self.env['estate.property'].browse(property_id).state = 'offer_received'
45+
46+
return super(EstatePropertyOffer,self).create(vals)
47+
2448
@api.depends('validity')
2549
def _compute_deadline(self):
2650
for record in self:
2751
create_date = record.create_date or datetime.now()
2852
record.date_deadline = create_date + timedelta(days=record.validity)
53+
2954
def _inverse_deadline(self):
3055
for record in self:
3156
create_date = record.create_date or datetime.now()
@@ -36,19 +61,19 @@ def _inverse_deadline(self):
3661
def action_accept_offer(self):
3762
for record in self:
3863
existing = self.search([
39-
('property_id','=',record.property_id.id),
40-
('status','=','accepted')
64+
('property_id', '=', record.property_id.id),
65+
('status', '=', 'accepted')
4166
])
4267
if existing:
4368
raise UserError(_("Another offer has been already accepted."))
4469
record.status = "accepted"
4570
record.property_id.state = "offer_accepted"
4671
record.property_id.selling_price = record.price
4772
record.property_id.buyer_id = record.partner_id.id
73+
4874
def action_refuse_offer(self):
4975
for record in self:
50-
if(record.status == 'accepted'):
76+
if record.status == 'accepted':
5177
raise UserError(_("Accepted Offer cannot be Refused"))
5278
else:
5379
record.status = "refused"
54-

estate/models/estate_property_tags.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
from odoo import fields,models
1+
from odoo import fields, models
22

33
class EstatePropertyTags(models.Model):
4-
_name="estate.property.tags"
5-
_description="Estate Property Tags"
4+
5+
_name = "estate.property.tags"
6+
_description = "Estate Property Tags"
67
_order = "name"
78

8-
_unique_tag_name = models.Constraint('UNIQUE(name)','Tag name must be unique.')
9+
_sql_constraints = [('_unique_tag_name', 'UNIQUE(name)', 'Tag name must be unique.')]
910

10-
name=fields.Char(required=True)
11-
color=fields.Integer(default=3)
11+
name = fields.Char(required=True)
12+
color = fields.Integer(default=3)

estate/models/inherited_res_users.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from odoo import models, fields
2+
3+
class InheritedResUsers(models.Model):
4+
5+
_inherit = 'res.users'
6+
7+
property_ids = fields.One2many('estate.property',
8+
'salesperson_id',
9+
string='Available Properties',
10+
domain=[('state','in',['new','offer_received'])])

estate/security/ir.model.access.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2-
estate.access_estate_property,access_estate_property,estate.model_estate_property,,1,1,1,1
2+
estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1
33
estate.access_estate_property_types,access_estate_property_types,estate.model_estate_property_types,base.group_user,1,1,1,1
44
estate.access_estate_property_tags,access_estate_property_tags,estate.model_estate_property_tags,base.group_user,1,1,1,1
55
estate.access_estate_property_offer,access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,1,1,1

0 commit comments

Comments
 (0)