Skip to content

Commit b32016b

Browse files
committed
[IMP] estate: Create New module estate_account to create Property invoice
Will add a new module that depends on the estate and account module It overrides the sold action to create an invoice for the property sold
1 parent 7d95cad commit b32016b

File tree

6 files changed

+108
-52
lines changed

6 files changed

+108
-52
lines changed

estate/models/estate_property.py

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33

44

55
class EstateProperty(models.Model):
6-
_name = 'estate_property'
7-
_description = 'Estate Property details'
8-
_order = 'id desc'
6+
_name = "estate_property"
7+
_description = "Estate Property details"
8+
_order = "id desc"
99

1010
name = fields.Char(required=True)
1111
description = fields.Text()
1212
postcode = fields.Char()
1313
date_availability = fields.Date(
14-
default=lambda self: fields.Date.add(fields.Date.today(), months=3),
15-
copy=False
14+
default=lambda self: fields.Date.add(fields.Date.today(), months=3), copy=False
1615
)
1716
expected_price = fields.Float(required=True)
1817
selling_price = fields.Float(readonly=True, copy=False)
@@ -23,88 +22,97 @@ class EstateProperty(models.Model):
2322
garden = fields.Boolean()
2423
garden_area = fields.Integer()
2524
garden_orientation = fields.Selection(
26-
string='Garden Orientation',
25+
string="Garden Orientation",
2726
selection=[
28-
('north', 'North'),
29-
('south', 'South'),
30-
('east', 'East'),
31-
('west', 'West')
32-
]
27+
("north", "North"),
28+
("south", "South"),
29+
("east", "East"),
30+
("west", "West"),
31+
],
3332
)
3433
state = fields.Selection(
35-
string='Status',
34+
string="Status",
3635
selection=[
37-
('new', 'New'),
38-
('offer_received', 'Offer Received'),
39-
('offer_accepted', 'Offer Accepted'),
40-
('sold', 'Sold'),
41-
('cancelled', 'Cancelled')
36+
("new", "New"),
37+
("offer_received", "Offer Received"),
38+
("offer_accepted", "Offer Accepted"),
39+
("sold", "Sold"),
40+
("cancelled", "Cancelled"),
4241
],
43-
default='new',
42+
default="new",
4443
required=True,
45-
copy=False
44+
copy=False,
4645
)
4746
active = fields.Boolean(default=True)
48-
property_type_id = fields.Many2one('estate.property.type', string='Type')
49-
buyer = fields.Many2one('res.partner', copy=False)
50-
salesperson = fields.Many2one('res.users', string='Salesman', default=lambda self: self.env.user)
51-
tag_ids = fields.Many2many('estate.property.tag', string='Tag')
52-
offer_ids = fields.One2many('estate.property.offer', 'property_id')
53-
total_area = fields.Integer(compute='_compute_total_area')
54-
best_price = fields.Float(compute='_compute_best_price')
47+
property_type_id = fields.Many2one("estate.property.type", string="Type")
48+
buyer = fields.Many2one("res.partner", copy=False)
49+
salesperson = fields.Many2one(
50+
"res.users", string="Salesman", default=lambda self: self.env.user
51+
)
52+
tag_ids = fields.Many2many("estate.property.tag", string="Tag")
53+
offer_ids = fields.One2many("estate.property.offer", "property_id")
54+
total_area = fields.Integer(compute="_compute_total_area")
55+
best_price = fields.Float(compute="_compute_best_price")
5556

5657
_check_expected_price = models.Constraint(
57-
'CHECK(expected_price > 0)',
58-
'The Expected price cannot be 0 or less then 0'
58+
"CHECK(expected_price > 0)", "The Expected price cannot be 0 or less then 0"
5959
)
6060

6161
_check_selling_price = models.Constraint(
62-
'CHECK(selling_price >= 0)',
63-
'The Selling price cannot be less then 0'
62+
"CHECK(selling_price >= 0)", "The Selling price cannot be less then 0"
6463
)
6564

66-
@api.constrains('selling_price', 'buyer', 'expected_price')
65+
@api.constrains("selling_price", "buyer", "expected_price")
6766
def _check_selling_price_90p(self):
6867
for record in self:
6968
if record.selling_price == 0:
7069
return False
71-
if float_compare((record.selling_price / record.expected_price) * 100, 90, precision_digits=2) < 0:
72-
raise exceptions.ValidationError(_('Selling Price should be 90% or more of expected price.'))
70+
if (
71+
float_compare(
72+
(record.selling_price / record.expected_price) * 100,
73+
90,
74+
precision_digits=2,
75+
)
76+
< 0
77+
):
78+
raise exceptions.ValidationError(
79+
_("Selling Price should be 90% or more of expected price.")
80+
)
7381

74-
@api.depends('living_area', 'garden_area')
82+
@api.depends("living_area", "garden_area")
7583
def _compute_total_area(self):
7684
for record in self:
7785
record.total_area = record.living_area + record.garden_area
7886

79-
@api.depends('offer_ids.price')
87+
@api.depends("offer_ids.price")
8088
def _compute_best_price(self):
8189
for record in self:
82-
record.best_price = max(record.offer_ids.mapped('price') or [0])
90+
record.best_price = max(record.offer_ids.mapped("price") or [0])
8391

84-
@api.onchange('garden')
92+
@api.onchange("garden")
8593
def _onchange_garden(self):
8694
if self.garden:
87-
self.garden_orientation = 'north'
95+
self.garden_orientation = "north"
8896
self.garden_area = 10
8997
else:
9098
self.garden_orientation = None
9199
self.garden_area = 0
92100

93101
def action_cancel_property(self):
94-
if self.filtered(lambda x: x.state == 'sold'):
95-
raise exceptions.UserError(_('A sold property cannot be cancelled'))
102+
if self.filtered(lambda x: x.state == "sold"):
103+
raise exceptions.UserError(_("A sold property cannot be cancelled"))
96104

97-
self.state = 'cancelled'
98-
return True
105+
self.state = "cancelled"
99106

100107
def action_property_sold(self):
101-
if self.filtered(lambda x: x.state == 'cancelled'):
102-
raise exceptions.UserError(_('A cancelled property cannot be sold'))
108+
if self.filtered(lambda x: x.state == "cancelled"):
109+
raise exceptions.UserError(_("A cancelled property cannot be sold"))
103110

104-
self.state = 'sold'
105-
return True
111+
self.state = "sold"
106112

107113
@api.ondelete(at_uninstall=False)
108114
def _unlink_if_new_or_sold(self):
109-
if self.filtered(lambda x: x.state not in ('new', 'cancelled')):
110-
raise exceptions.UserError(_('Cannot delete property which is not yer sold or cancelled'))
115+
if self.filtered(lambda x: x.state not in ("new", "cancelled")):
116+
raise exceptions.UserError(
117+
_("Cannot delete property which is new or cancelled")
118+
)

estate/views/estate_property_views.xml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@
1515
<h1>
1616
<field name="name" nolabel="True" />
1717
</h1>
18-
<field name="tag_ids" widget="many2many_tags" class="mb-5"
19-
options="{'color_field': 'color'}" />
18+
<group>
19+
<group>
20+
<field name="tag_ids" widget="many2many_tags"
21+
options="{'color_field': 'color'}" string="Tags" />
22+
</group>
23+
</group>
2024
<group>
2125
<group>
2226
<field name="property_type_id" string="Property Type"
@@ -106,6 +110,6 @@
106110
<field name="name">Properties</field>
107111
<field name="res_model">estate_property</field>
108112
<field name="context">{'search_default_available': True}</field>
109-
<field name="view_mode">list,form</field>
113+
<field name="view_mode">list,form,kanban</field>
110114
</record>
111-
</odoo>
115+
</odoo>

estate_account/__init__.py

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

estate_account/__manifest__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "Estate Accounting",
3+
"version": "1.0",
4+
"depends": ["estate", "account"],
5+
"author": "Shivam Saksham(shsak)",
6+
"category": "Sales",
7+
"description": """
8+
A Real Estate Invoicing Module
9+
""",
10+
"license": "LGPL-3",
11+
"data": [],
12+
}

estate_account/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import estate_property
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from odoo import models, Command
2+
3+
4+
class EstateProperty(models.Model):
5+
_inherit = "estate_property"
6+
7+
def action_property_sold(self):
8+
self.env["account.move"].create(
9+
{
10+
"move_type": "out_invoice",
11+
"partner_id": self.buyer.id,
12+
"invoice_line_ids": [
13+
Command.create(
14+
{
15+
"name": self.name,
16+
"quantity": 1,
17+
"price_unit": self.selling_price * 0.6,
18+
}
19+
),
20+
Command.create(
21+
{
22+
"name": "Administrative Fees",
23+
"quantity": 1,
24+
"price_unit": 100,
25+
}
26+
),
27+
],
28+
}
29+
)
30+
return super().action_property_sold()

0 commit comments

Comments
 (0)