Skip to content

Commit c6f97f3

Browse files
committed
[ADD] estate: Chapter 8 - add computed fields and views
Enhance property and offer models with computed fields and views
1 parent 257b435 commit c6f97f3

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

estate/models/estate_property.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from odoo import fields, models
1+
from odoo import api, fields, models
22
from dateutil.relativedelta import relativedelta
33

44

@@ -15,7 +15,9 @@ class EstateProperty(models.Model):
1515
description = fields.Text("Description")
1616
postcode = fields.Char("Postcode")
1717
date_availability = fields.Date(
18-
"Available From", default=lambda self: fields.Date.today() + relativedelta(months=3), copy=False
18+
"Available From",
19+
default=lambda self: fields.Date.today() + relativedelta(months=3),
20+
copy=False,
1921
)
2022
expected_price = fields.Float("Expected Price", required=True)
2123
selling_price = fields.Float("Selling Price", copy=False, readonly=True)
@@ -55,3 +57,30 @@ class EstateProperty(models.Model):
5557
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
5658
tag_ids = fields.Many2many("estate.property.tag", string="Tags")
5759
offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
60+
61+
# Computed fields
62+
@api.depends("living_area", "garden_area")
63+
def _compute_total_area(self):
64+
for record in self:
65+
record.total_area = record.living_area + record.garden_area
66+
67+
total_area = fields.Integer("Total Area (sqm)", compute="_compute_total_area", store=True)
68+
69+
@api.depends("offer_ids.price")
70+
def _compute_best_offer(self):
71+
for record in self:
72+
prices = record.offer_ids.mapped("price")
73+
record.best_offer = max(prices) if prices else 0.0
74+
75+
best_offer = fields.Float("Best Offer", compute="_compute_best_offer", store=True)
76+
77+
@api.onchange("garden")
78+
def _onchange_garden(self):
79+
if not self.garden:
80+
self.garden_area = 0
81+
self.garden_orientation = False
82+
else:
83+
if not self.garden_area:
84+
self.garden_area = 10
85+
if not self.garden_orientation:
86+
self.garden_orientation = "north"

estate/models/estate_property_offer.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from odoo import fields, models
1+
from datetime import timedelta
2+
3+
from odoo import api, fields, models
24

35

46
class EstatePropertyOffer(models.Model):
@@ -16,3 +18,20 @@ class EstatePropertyOffer(models.Model):
1618
)
1719
partner_id = fields.Many2one("res.partner", string="Partner", required=True)
1820
property_id = fields.Many2one("estate.property", string="Property", required=True)
21+
validity = fields.Integer("Validity (days)", default=7)
22+
date_deadline = fields.Date("Deadline", compute="_compute_date_deadline", inverse="_inverse_date_deadline")
23+
24+
@api.depends("create_date", "validity")
25+
def _compute_date_deadline(self):
26+
for offer in self:
27+
if offer.create_date:
28+
offer.date_deadline = offer.create_date.date() + timedelta(days=offer.validity)
29+
else: # Fallback if create_date is not set
30+
offer.date_deadline = fields.Date.today() + timedelta(days=offer.validity)
31+
32+
def _inverse_date_deadline(self):
33+
for offer in self:
34+
if offer.date_deadline and offer.create_date:
35+
offer.validity = (offer.date_deadline - offer.create_date.date()).days
36+
elif offer.date_deadline: # Fallback if create_date is not set
37+
offer.validity = (offer.date_deadline - fields.Date.today()).days

estate/views/estate_property_views.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
</group>
4545
<group>
4646
<field name="expected_price" string="Expected Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
47+
<field name="best_offer" string="Best Offer" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
4748
<field name="selling_price" string="Selling Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
4849
</group>
4950
</group>
@@ -59,15 +60,27 @@
5960
<field name="garden" string="Garden"/>
6061
<field name="garden_area" string="Garden Area (sqm)"/>
6162
<field name="garden_orientation" string="Garden Orientation"/>
63+
<field name="total_area" string="Total Area (sqm)"/>
6264
</group>
6365
</page>
6466
<page string="Offers">
6567
<field name="offer_ids">
6668
<list string="Offers">
6769
<field name="price" string="Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
6870
<field name="partner_id" string="Partner"/>
71+
<field name="validity" string="Validity (days)"/>
72+
<field name="date_deadline" string="Deadline"/>
6973
<field name="status" string="Status"/>
7074
</list>
75+
<form string="Offer">
76+
<group>
77+
<field name="price" string="Price"/>
78+
<field name="partner_id" string="Partner"/>
79+
<field name="validity" string="Validity (days)"/>
80+
<field name="date_deadline" string="Deadline"/>
81+
<field name="status" string="Status"/>
82+
</group>
83+
</form>
7184
</field>
7285
</page>
7386
<page string="Other Info">

0 commit comments

Comments
 (0)