Skip to content

Commit 670422d

Browse files
author
joyep
committed
[ADD] estate: Chapter 11 - add the sprinkles
Enhance property management - update launch configuration, modify ordering, and improve views
1 parent 859d32c commit 670422d

File tree

8 files changed

+138
-45
lines changed

8 files changed

+138
-45
lines changed

estate/.vscode/launch.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55
"name": "debug current file",
66
"type": "debugpy",
77
"request": "launch",
8-
"program": "${file}",
8+
"program": "${workspaceFolder}/odoo/odoo-bin",
9+
"args": [
10+
"--addons-path=addons,../enterprise/,../tutorials/",
11+
"-d",
12+
"rd-demo",
13+
"-u",
14+
"estate",
15+
"--dev",
16+
"all",
17+
"--http-interface=127.0.0.1"
18+
],
919
"console": "integratedTerminal",
1020
"justMyCode": true
1121
}

estate/models/estate_property.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class EstateProperty(models.Model):
1010
# ----------------------------------------
1111
_name = "estate.property"
1212
_description = "Estate Property"
13-
_order = "sequence"
13+
_order = "id desc"
1414

1515
# ----------------------------------------
1616
# Field declarations

estate/models/estate_property_offer.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55

66

77
class EstatePropertyOffer(models.Model):
8+
# ----------------------------------------
9+
# Private attributes
10+
# ----------------------------------------
811
_name = "estate.property.offer"
912
_description = "Estate Property Offer"
13+
_order = "price desc"
1014

15+
# ----------------------------------------
16+
# Field declarations
17+
# ----------------------------------------
1118
price = fields.Float("Price")
1219
status = fields.Selection(
1320
selection=[
@@ -21,10 +28,21 @@ class EstatePropertyOffer(models.Model):
2128
property_id = fields.Many2one("estate.property", string="Property", required=True)
2229
validity = fields.Integer("Validity (days)", default=7)
2330
date_deadline = fields.Date("Deadline", compute="_compute_date_deadline", inverse="_inverse_date_deadline")
31+
property_type_id = fields.Many2one(
32+
"estate.property.type",
33+
related="property_id.property_type_id",
34+
string="Property Type",
35+
store=True,
36+
)
2437

38+
# ----------------------------------------
2539
# SQL constraints
40+
# ----------------------------------------
2641
_offer_price_positive = models.Constraint("CHECK(price > 0)")
2742

43+
# ----------------------------------------
44+
# Compute and inverse methods
45+
# ----------------------------------------
2846
@api.depends("create_date", "validity")
2947
def _compute_date_deadline(self):
3048
for offer in self:
@@ -40,6 +58,20 @@ def _inverse_date_deadline(self):
4058
elif offer.date_deadline: # Fallback if create_date is not set
4159
offer.validity = (offer.date_deadline - fields.Date.today()).days
4260

61+
# ----------------------------------------
62+
# CRUD methods
63+
# ----------------------------------------
64+
@api.model_create_multi
65+
def create(self, vals_list):
66+
# Create the offers
67+
offers = super().create(vals_list)
68+
# Update property status to 'offer_received' for all related properties
69+
offers.mapped("property_id").write({"status": "offer_received"})
70+
return offers
71+
72+
# ----------------------------------------
73+
# Action methods
74+
# ----------------------------------------
4375
def action_accept_offer(self):
4476
for offer in self:
4577
# Check if there's already an accepted offer

estate/models/estate_property_tag.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@
22

33

44
class EstatePropertyTag(models.Model):
5+
# ----------------------------------------
6+
# Private attributes
7+
# ----------------------------------------
58
_name = "estate.property.tag"
69
_description = "Estate Property Tag"
10+
_order = "name"
711

12+
# ----------------------------------------
13+
# Field declarations
14+
# ----------------------------------------
815
name = fields.Char("Name", required=True)
16+
color = fields.Integer("Color Index", default=0)
917

18+
# ----------------------------------------
19+
# SQL constraints
20+
# ----------------------------------------
1021
_tag_name_unique = models.Constraint("UNIQUE(name)")

estate/models/estate_property_type.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,30 @@
22

33

44
class EstatePropertyType(models.Model):
5+
# ----------------------------------------
6+
# Private attributes
7+
# ----------------------------------------
58
_name = "estate.property.type"
69
_description = "Estate Property Type"
10+
_order = "sequence, name"
711

12+
# ----------------------------------------
13+
# Field declarations
14+
# ----------------------------------------
815
name = fields.Char("Name", required=True)
16+
sequence = fields.Integer("Sequence", default=1, help="Used to order property types")
17+
property_ids = fields.One2many("estate.property", "property_type_id", string="Properties")
18+
offer_ids = fields.One2many("estate.property.offer", "property_type_id", string="Offers")
19+
offer_count = fields.Integer("Offer Count", compute="_compute_offer_count")
920

21+
# ----------------------------------------
22+
# SQL constraints
23+
# ----------------------------------------
1024
_property_type_name_unique = models.Constraint("UNIQUE(name)")
25+
26+
# ----------------------------------------
27+
# Compute methods
28+
# ----------------------------------------
29+
def _compute_offer_count(self):
30+
for property_type in self:
31+
property_type.offer_count = len(property_type.offer_ids)

estate/views/estate_property_tag_views.xml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,16 @@
33
<record id="estate_property_tag_action" model="ir.actions.act_window">
44
<field name="name">Property Tags</field>
55
<field name="res_model">estate.property.tag</field>
6-
<field name="view_mode">list,form</field>
6+
<field name="view_mode">list</field>
77
</record>
8-
<record id="estate_property_tag_view_tree" model="ir.ui.view">
8+
<record id="estate_property_tag_view_list" model="ir.ui.view">
99
<field name="name">estate.property.tag.list</field>
1010
<field name="model">estate.property.tag</field>
1111
<field name="arch" type="xml">
12-
<list string="Property Tags">
12+
<list string="Property Tags" editable="bottom">
1313
<field name="name" string="Name"/>
14+
<field name="color" string="Color" widget="color_picker"/>
1415
</list>
1516
</field>
1617
</record>
17-
<record id="estate_property_tag_view_form" model="ir.ui.view">
18-
<field name="name">estate.property.tag.form</field>
19-
<field name="model">estate.property.tag</field>
20-
<field name="arch" type="xml">
21-
<form string="Property Tag">
22-
<sheet>
23-
<group>
24-
<field name="name" string="Name"/>
25-
</group>
26-
</sheet>
27-
</form>
28-
</field>
29-
</record>
3018
</odoo>

estate/views/estate_property_type_views.xml

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
<?xml version="1.0"?>
22
<odoo>
3+
<!-- PROPERTY TYPE OFFERS ACTION -->
4+
<record id="action_property_type_offers" model="ir.actions.act_window">
5+
<field name="res_model">estate.property.offer</field>
6+
<field name="name">Offers</field>
7+
<field name="view_mode">list</field>
8+
<field name="domain">[('property_type_id', '=', active_id)]</field>
9+
<field name="context">{'default_property_type_id': active_id}</field>
10+
</record>
11+
12+
<record id="property_type_offers_view_list" model="ir.ui.view">
13+
<field name="name">estate.property.offer.property.type.list</field>
14+
<field name="model">estate.property.offer</field>
15+
<field name="arch" type="xml">
16+
<list string="Property Type Offers">
17+
<field name="price"/>
18+
<field name="status"/>
19+
</list>
20+
</field>
21+
</record>
22+
23+
<!-- PROPERTY TYPE VIEWS -->
324
<record id="estate_property_type_action" model="ir.actions.act_window">
425
<field name="name">Property Types</field>
526
<field name="res_model">estate.property.type</field>
627
<field name="view_mode">list,form,search</field>
728
</record>
8-
<record id="estate_property_type_view_tree" model="ir.ui.view">
29+
<record id="estate_property_type_view_list" model="ir.ui.view">
930
<field name="name">estate.property.type.list</field>
1031
<field name="model">estate.property.type</field>
1132
<field name="arch" type="xml">
1233
<list string="Property Types">
34+
<field name="sequence" widget="handle"/>
1335
<field name="name" string="Name"/>
1436
</list>
1537
</field>
@@ -20,9 +42,25 @@
2042
<field name="arch" type="xml">
2143
<form string="Property Type">
2244
<sheet>
45+
<div class="oe_button_box" name="button_box">
46+
<button type="action" name="estate.action_property_type_offers" class="oe_stat_button" icon="fa-money">
47+
<field name="offer_count" widget="statinfo" string="Offers"/>
48+
</button>
49+
</div>
2350
<group>
2451
<field name="name" string="Name"/>
2552
</group>
53+
<notebook>
54+
<page string="Properties">
55+
<field name="property_ids">
56+
<list>
57+
<field name="name"/>
58+
<field name="expected_price"/>
59+
<field name="status"/>
60+
</list>
61+
</field>
62+
</page>
63+
</notebook>
2664
</sheet>
2765
</form>
2866
</field>

estate/views/estate_property_views.xml

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
<field name="name">Properties</field>
55
<field name="res_model">estate.property</field>
66
<field name="view_mode">list,form,search</field>
7+
<field name="search_view_id" ref="estate_property_view_search"/>
8+
<field name="context">{'search_default_available': True}</field>
79
</record>
810

9-
<record id="estate_property_view_tree" model="ir.ui.view">
11+
<record id="estate_property_view_list" model="ir.ui.view">
1012
<field name="name">estate.property.list</field>
1113
<field name="model">estate.property</field>
1214
<field name="arch" type="xml">
13-
<list string="Properties">
15+
<list string="Properties" decoration-success="status in ['offer_received','offer_accepted']" decoration-bf="status == 'offer_accepted'" decoration-muted="status == 'sold'">
16+
<field name="sequence" widget="handle"/>
1417
<field name="name" string="Title"/>
1518
<field name="property_type_id" string="Property Type"/>
1619
<field name="tag_ids" string="Tags" widget="many2many_tags"/>
@@ -19,7 +22,7 @@
1922
<field name="living_area" string="Living Area (sqm)"/>
2023
<field name="expected_price" string="Expected Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
2124
<field name="selling_price" string="Selling Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
22-
<field name="date_availability" string="Available From"/>
25+
<field name="date_availability" string="Available From" optional="hide"/>
2326
</list>
2427
</field>
2528
</record>
@@ -31,19 +34,19 @@
3134
<form string="Property">
3235
<sheet>
3336
<header>
34-
<button name="action_set_sold" type="object" string="Sold" class="btn-primary"/>
35-
<button name="action_set_canceled" type="object" string="Cancel" class="btn-secondary"/>
37+
<button name="action_set_sold" type="object" string="Sold" class="btn-primary" invisible="status in ['sold', 'canceled']"/>
38+
<button name="action_set_canceled" type="object" string="Cancel" class="btn-secondary" invisible="status in ['sold', 'canceled']"/>
39+
<field name="status" widget="statusbar" statusbar_visible="new,offer_received,offer_accepted,sold"/>
3640
</header>
3741
<div class="oe_title">
3842
<h1>
3943
<field name="name"/>
4044
</h1>
41-
<field name="tag_ids" widget="many2many_tags" string="Tags"/>
45+
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color',}" string="Tags"/>
4246
</div>
4347
<group>
4448
<group>
45-
<field name="status" string="Status"/>
46-
<field name="property_type_id" string="Property Type"/>
49+
<field name="property_type_id" string="Property Type" options="{'no_create': True, 'no_open': True}"/>
4750
<field name="postcode" string="Postcode"/>
4851
<field name="date_availability" string="Available From"/>
4952
</group>
@@ -63,31 +66,21 @@
6366
<field name="facades" string="Facades"/>
6467
<field name="garage" string="Garage"/>
6568
<field name="garden" string="Garden"/>
66-
<field name="garden_area" string="Garden Area (sqm)"/>
67-
<field name="garden_orientation" string="Garden Orientation"/>
69+
<field name="garden_area" string="Garden Area (sqm)" visible="garden"/>
70+
<field name="garden_orientation" string="Garden Orientation" visible="garden"/>
6871
<field name="total_area" string="Total Area (sqm)"/>
6972
</group>
7073
</page>
7174
<page string="Offers">
72-
<field name="offer_ids">
73-
<list string="Offers">
75+
<field name="offer_ids" readonly="status in ['offer_accepted', 'sold', 'canceled']">
76+
<list string="Offers" editable="top" decoration-success="status == 'accepted'" decoration-danger="status == 'refused'">
7477
<field name="price" string="Price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
7578
<field name="partner_id" string="Partner"/>
7679
<field name="validity" string="Validity (days)"/>
7780
<field name="date_deadline" string="Deadline"/>
78-
<button name="action_accept_offer" type="object" icon="fa-check"/>
79-
<button name="action_refuse_offer" type="object" icon="fa-times"/>
80-
<field name="status" string="Status"/>
81+
<button name="action_accept_offer" type="object" icon="fa-check" invisible="status"/>
82+
<button name="action_refuse_offer" type="object" icon="fa-times" title="Refuse Offer" invisible="status"/>
8183
</list>
82-
<form string="Offer">
83-
<group>
84-
<field name="price" string="Price"/>
85-
<field name="partner_id" string="Partner"/>
86-
<field name="validity" string="Validity (days)"/>
87-
<field name="date_deadline" string="Deadline"/>
88-
<field name="status" string="Status"/>
89-
</group>
90-
</form>
9184
</field>
9285
</page>
9386
<page string="Other Info">
@@ -113,10 +106,10 @@
113106
<field name="property_type_id" string="Property Type"/>
114107
<field name="tag_ids" string="Tags"/>
115108
<field name="bedrooms" string="Bedrooms"/>
116-
<field name="living_area" string="Living Area (sqm)"/>
109+
<field name="living_area" string="Living Area (sqm)" filter_domain="[('living_area', '>=', self)]"/>
117110
<field name="facades" string="Facades"/>
118111

119-
<filter string="Available" name="available" domain="[('status', 'in', ['new', 'offer_received'])]"/>
112+
<filter name="available" string="Available" domain="[('status', 'in', ['new', 'offer_received'])]"/>
120113

121114
<group>
122115
<filter string="Postcode" name="postcode" context="{'group_by': 'postcode'}"/>

0 commit comments

Comments
 (0)