Skip to content

Commit 6afa556

Browse files
committed
[IMP] awesome_owl: Implemented new components and improve UI/JS structure
Estate: - Updated models (property, offer, type) with improved logic and fields - Fixed offer views and replaced deprecated attrs with modifiers for Odoo 17+ - Updated main property views for better usability - Added cron XML for scheduled date processing - Improved manifest metadata Estate Accounting: - Added account_move extension for property invoicing - Updated estate_property accounting bridge - Added new view estate_move.xml - Updated access rights - Cleaned model imports Awesome Dashboard: - Updated dashboard JS logic - Added new SCSS styling - Improved dashboard XML structure Awesome Owl: - Updated manifest and controllers - Added new components: card, counter, todo_list (JS + XML) - Updated main.js and playground code - Added utils.js helper module
1 parent 89126d5 commit 6afa556

32 files changed

+422
-148
lines changed

Estate/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
'license': 'AGPL-3',
99
'data': [
1010
'security/ir.model.access.csv',
11+
'data/date_cron.xml',
1112
'views/estate_property_type_views.xml',
1213
'views/estate_property_offer_views.xml',
1314
'views/estate_property_tags_views.xml',

Estate/data/date_cron.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<odoo>
2+
<record id="ir_cron_move_sold" model="ir.cron">
3+
<field name="name">Sold if validity exceeds</field>
4+
<field name="model_id" ref="model_estate_property_offer"/>
5+
<field name="state">code</field>
6+
<field name="code">model._cron_move_sold</field>
7+
<field name="interval_number">1</field>
8+
<field name="interval_type">days</field>
9+
</record>
10+
</odoo>

Estate/models/estate_property.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from odoo import models, fields, api
44
from odoo.exceptions import ValidationError
5+
from odoo.tools.float_utils import float_compare, float_is_zero
56

67

78
class EstateProperty(models.Model):
@@ -13,7 +14,7 @@ class EstateProperty(models.Model):
1314
postcode = fields.Char()
1415
create_date = fields.Datetime()
1516
expected_price = fields.Float(required=True)
16-
selling_price = fields.Float()
17+
selling_price = fields.Float(readonly=True)
1718
bedrooms = fields.Integer()
1819
living_area = fields.Integer()
1920
facades = fields.Integer()
@@ -82,15 +83,21 @@ def _inverse_date_deadline(self):
8283
delta = (record.date_deadline - create_date).days if record.date_deadline else 0
8384
record.validity_days = delta
8485

86+
@api.constrains('selling_price', 'expected_price')
87+
def _check_selling_price(self):
88+
for record in self:
89+
if not float_is_zero(record.selling_price, precision_digits=2):
90+
if float_compare(record.selling_price, 0.9 * record.expected_price, precision_digits=2) < 0:
91+
raise ValidationError("The selling price cannot be lower than 90% of the expected price.")
92+
8593
@api.onchange("garden")
8694
def _onchange_garden(self):
87-
for record in self:
88-
if record.garden:
89-
record.garden_area = 10
90-
record.garden_orientation = "north"
91-
else:
92-
record.garden_area = 0
93-
record.garden_orientation = False
95+
if self.garden:
96+
self.garden_area = 10
97+
self.garden_orientation = "north"
98+
else:
99+
self.garden_area = 0
100+
self.garden_orientation = False
94101

95102
@api.model
96103
def create(self, vals):
@@ -119,12 +126,6 @@ def action_back_to_new(self):
119126
for record in self:
120127
record.state = "new"
121128

122-
@api.constrains("selling_price", "expected_price")
123-
def _check_selling_price_ratio(self):
124-
for record in self:
125-
if record.selling_price < 0.9 * record.expected_price:
126-
raise ValidationError("Selling price must be at least 90% of the expected price")
127-
128129
def _unlink(self):
129130
for record in self:
130131
if record.state in ["new"]:
Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,78 @@
1+
from datetime import timedelta
12
from odoo import models, fields, api
2-
from odoo.exceptions import ValidationError
3+
from odoo.exceptions import UserError
34

45

56
class EstatePropertyOffer(models.Model):
67
_name = "estate.property.offer"
78
_description = "Real Estate Property Offer"
89
_order = "price desc"
910

10-
price = fields.Float(required=True)
11+
price = fields.Float(string="Price", required=True)
1112
status = fields.Selection(
12-
[
13-
('accepted', 'Accepted'),
14-
('refused', 'Refused'),
15-
],
13+
[('accepted', 'Accepted'), ('refused', 'Refused')],
14+
string="Status",
15+
copy=False
1616
)
17-
property_id = fields.Many2one("estate.property", string="Property", required=True)
1817
partner_id = fields.Many2one("res.partner", string="Buyer", required=True)
18+
property_id = fields.Many2one("estate.property", string="Property", required=True)
19+
validity = fields.Integer(default=7, string="Validity (Days)")
20+
date_deadline = fields.Date(compute="_compute_date_deadline", inverse="_inverse_date_deadline", string="Deadline")
21+
22+
_check_price = models.Constraint(
23+
'CHECK(price > 0)',
24+
'The offer price must be strictly positive'
25+
)
26+
27+
@api.depends("create_date", "validity")
28+
def _compute_date_deadline(self):
29+
for record in self:
30+
base_date = record.create_date.date() if record.create_date else fields.Date.today()
31+
record.date_deadline = base_date + timedelta(days=record.validity)
32+
33+
def _inverse_date_deadline(self):
34+
for record in self:
35+
base_date = record.create_date.date() if record.create_date else fields.Date.today()
36+
if record.date_deadline:
37+
record.validity = (record.date_deadline - base_date).days
1938

2039
def action_accept_offer(self):
2140
for record in self:
41+
if record.status == 'accepted':
42+
continue
43+
2244
record.status = 'accepted'
45+
record.property_id.write({
46+
'selling_price': record.price,
47+
'buyer_id': record.partner_id.id,
48+
'state': 'offer_accepted'
49+
})
50+
51+
record.property_id.offer_ids.filtered(lambda o: o.id != record.id).write({
52+
'status': 'refused'
53+
})
54+
return True
2355

2456
def action_refuse_offer(self):
2557
for record in self:
2658
record.status = 'refused'
59+
return True
2760

28-
@api.constrains("price")
29-
def _check_price_ratio(self):
30-
for record in self:
31-
if record.price <= 0.0:
32-
raise ValidationError("Price must be greater than 0")
61+
@api.model
62+
def create(self, vals):
63+
if len(vals) > 0:
64+
property = self.env['estate.property'].browse(vals[0]['property_id'])
65+
for record in vals:
66+
if property.state == 'new':
67+
property.state = 'offer_received'
68+
if record['price'] < property.best_price:
69+
raise UserError("Offer must be higher or equal than %d" % property.best_price)
70+
return super().create(vals)
71+
72+
@api.model
73+
def _cron_move_sold(self):
74+
expired_offers = self.search([
75+
('status', '=', False),
76+
('date_deadline', '<', fields.Date.today())
77+
])
78+
expired_offers.write({'status': 'refused'})

Estate/models/estate_property_type.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from odoo import models, fields, api
2-
from odoo.exceptions import ValidationError
32

43

54
class EstatePropertyType(models.Model):
65
_name = "estate.property.type"
76
_description = "Real Estate Property Type"
8-
_order = "name desc"
7+
_order = "sequence , name"
98

109
name = fields.Char(required=True)
1110
property_ids = fields.One2many("estate.property", "property_type_id", string="Properties")
Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,56 @@
11
<odoo>
2-
3-
<record id="estate_property_offer_tree_view" model="ir.ui.view">
2+
<record id="estate_property_offer_view_list" model="ir.ui.view">
43
<field name="name">estate.property.offer.list</field>
54
<field name="model">estate.property.offer</field>
65
<field name="arch" type="xml">
7-
<list>
8-
<field name="price" />
9-
<field name="partner_id" />
10-
<button name="action_accept_offer" string="accept" type="object" invisible="status in ['accepted', 'refused']" />
11-
<button name="action_refuse_offer" string="refuse" type="object" invisible="status in ['accepted', 'refused']" />
12-
<field name="status" />
6+
<list string="Property Offers" editable="bottom"
7+
decoration-success="status == 'accepted'"
8+
decoration-danger="status == 'refused'">
9+
<field name="price"/>
10+
<field name="partner_id"/>
11+
<field name="status" column_invisible="True"/>
12+
<button name="action_accept_offer"
13+
string="Accept"
14+
type="object"
15+
icon="fa-check"
16+
title="Accept"
17+
invisible="status"/>
18+
19+
<button name="action_refuse_offer"
20+
string="Refuse"
21+
type="object"
22+
icon="fa-times"
23+
title="Refuse"
24+
invisible="status"/>
1325
</list>
1426
</field>
1527
</record>
1628

17-
<record id="estate_property_offer_form_view" model="ir.ui.view">
29+
<record id="estate_property_offer_view_form" model="ir.ui.view">
1830
<field name="name">estate.property.offer.form</field>
1931
<field name="model">estate.property.offer</field>
2032
<field name="arch" type="xml">
21-
<form>
33+
<form string="Offer Details">
2234
<sheet>
2335
<group>
24-
<field name="price"/>
25-
<field name="partner_id"/>
26-
<field name="status"/>
27-
<button name="action_accept_offer" string="accept" type="object" invisible="status in ['accepted', 'refused']" />
28-
<button name="action_refuse_offer" string="refuse" type="object" invisible="status in ['accepted', 'refused']" />
36+
<group>
37+
<field name="price"/>
38+
<field name="partner_id"/>
39+
</group>
40+
<group>
41+
<field name="status"/>
42+
<field name="property_id" readonly="1"/>
43+
</group>
2944
</group>
3045
</sheet>
3146
</form>
3247
</field>
3348
</record>
49+
50+
<record id="action_estate_property_offer" model="ir.actions.act_window">
51+
<field name="name">Property Offers</field>
52+
<field name="res_model">estate.property.offer</field>
53+
<field name="view_mode">list,form</field>
54+
<field name="domain">[('property_id', '=', active_id)]</field>
55+
</record>
3456
</odoo>

Estate/views/estate_property_type_views.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<field name="model">estate.property.type</field>
1010
<field name="arch" type="xml">
1111
<list>
12+
<field name="sequence" widget="handle"/>
1213
<field name="name"/>
1314
</list>
1415
</field>

0 commit comments

Comments
 (0)