Skip to content

Commit 0667675

Browse files
committed
[IMP] awesome_owl: add counter and card components
Make estate module UI user-friendly Add counter and card component and display in awesome owl module
1 parent 06c2487 commit 0667675

File tree

14 files changed

+129
-45
lines changed

14 files changed

+129
-45
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Component } from "@odoo/owl";
2+
3+
export class Card extends Component {
4+
static template = "awesome_owl.Card";
5+
static props = {
6+
title: String,
7+
content: String,
8+
};
9+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.Card">
4+
<div class="card d-inline-block m-2" style="border: 3px solid #ccc; margin: 20px; padding: 20px">
5+
<div class="card-body">
6+
<h5 class="card-title" style="font-size: 20px">
7+
<t t-esc="props.title"/>
8+
</h5>
9+
<p class="card-text">
10+
<t t-esc="props.content"/>
11+
</p>
12+
</div>
13+
</div>
14+
</t>
15+
</templates>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Counter extends Component {
4+
static template = "awesome_owl.Counter";
5+
6+
static props = {
7+
onChange: {
8+
type: Function,
9+
}
10+
};
11+
12+
setup() {
13+
this.state = useState({ value: 0 });
14+
}
15+
16+
increment() {
17+
this.state.value++;
18+
if (this.props.onChange) {
19+
this.props.onChange(this.state.value);
20+
}
21+
}
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.Counter">
4+
<div style="border: 3px solid #ccc; display: inline-block; min-width: 300px; padding: 20px; margin: 20px">
5+
<p>Counter: <t t-esc="state.value"/></p>
6+
<button style="background: purple; color: white; padding: 8px; border-radius: 5px; border: 0;" class="btn btn-primary" t-on-click="increment">
7+
Increment
8+
</button>
9+
</div>
10+
</t>
11+
</templates>
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
import { Component } from "@odoo/owl";
1+
import { Component, useState } from "@odoo/owl";
2+
import { Counter } from "./counter/counter";
3+
import { Card } from "./card/card";
24

35
export class Playground extends Component {
4-
static template = "awesome_owl.playground";
6+
static template = "awesome_owl.Playground";
7+
static components = { Counter, Card };
8+
9+
setup() {
10+
this.state = useState({
11+
sum: 0,
12+
});
13+
}
14+
15+
incrementSum(newValue) {
16+
this.state.sum++;
17+
}
518
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<templates xml:space="preserve">
3-
4-
<t t-name="awesome_owl.playground">
5-
<div class="p-3">
6-
hello world
7-
</div>
3+
<t t-name="awesome_owl.Playground">
4+
<Counter onChange.bind="incrementSum"/>
5+
<Counter onChange.bind="incrementSum"/>
6+
<Counter onChange.bind="incrementSum"/>
7+
<h3 style="border: 3px solid #ccc; margin: 20px; padding: 20px">Sum of Counters: <t t-esc="state.sum"/></h3>
8+
<Card title="'This is title1'" content="'Hello from card1'"/>
9+
<Card title="'This is title2'" content="'Hello from card2'"/>
810
</t>
9-
1011
</templates>

estate/models/estate_property.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class EstateProperty(models.Model):
2525
garden_orientation = fields.Selection(
2626
string="Garden Orientation",
2727
selection=[
28-
('north', 'North'),
29-
('south', 'South'),
30-
('east', 'East'),
31-
('west', 'West')
28+
('north', 'North'),
29+
('south', 'South'),
30+
('east', 'East'),
31+
('west', 'West')
3232
]
3333
)
3434
active = fields.Boolean(default=True)
@@ -40,7 +40,8 @@ class EstateProperty(models.Model):
4040
('sold', 'Sold'),
4141
('cancelled', 'Cancelled')
4242
],
43-
default="new"
43+
default="new",
44+
readonly=True
4445
)
4546
property_type_id = fields.Many2one("estate.property.type")
4647
buyer_id = fields.Many2one("res.partner", copy=False)
@@ -50,6 +51,23 @@ class EstateProperty(models.Model):
5051
total_area = fields.Float(compute="_compute_total_area")
5152
best_offer = fields.Float(compute="_compute_best_offer")
5253

54+
_check_area = models.Constraint(
55+
'CHECK(garden_area >= 0 AND living_area>=0)',
56+
'Area must be positive'
57+
)
58+
59+
_check_price = models.Constraint(
60+
'CHECK(selling_price >= 0 AND expected_price>=0)',
61+
'Price must be positive'
62+
)
63+
64+
@api.constrains('selling_price', 'expected_price')
65+
def _check_selling_price(self):
66+
for record in self:
67+
if not float_is_zero(record.selling_price, precision_digits=2):
68+
if float_compare(record.selling_price, 0.9 * record.expected_price, precision_digits=2) < 0:
69+
raise ValidationError("The selling price cannot be lower than 90% of the expected price.")
70+
5371
@api.depends('living_area', 'garden_area')
5472
def _compute_total_area(self):
5573
for record in self:
@@ -86,20 +104,8 @@ def sold_property(self):
86104
else:
87105
record.state = 'sold'
88106

89-
_check_price = models.Constraint(
90-
'CHECK(selling_price >= 0 AND expected_price>=0)',
91-
'selling price and expected_price must be positive'
92-
)
93-
94-
@api.constrains('selling_price', 'expected_price', 'state')
95-
def _check_selling_price(self):
96-
for record in self:
97-
if not float_is_zero(record.selling_price, precision_digits=2):
98-
if float_compare(record.selling_price, 0.9 * record.expected_price, precision_digits=2) < 0:
99-
raise ValidationError("the selling price lower")
100-
101107
@api.ondelete(at_uninstall=True)
102108
def _unlink_check_state_of_property(self):
103109
for record in self:
104-
if record.state in ('offer_received', 'offer_accepted', 'sold'):
105-
raise UserError("You cannot delete a new or cancelled property !")
110+
if record.state not in ('new', 'cancelled'):
111+
raise UserError("only 'New' or 'Cancelled' property can be deleted.")

estate/models/estate_property_offer.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class EstatePropertyOffer(models.Model):
2222
validity = fields.Integer(default=7)
2323
date_deadline = fields.Date(compute="_compute_deadline", inverse="_inverse_deadline")
2424

25+
_check_offer_price = models.Constraint(
26+
'CHECK(price>=0)',
27+
'offer price must be positive',
28+
)
29+
2530
@api.depends("validity")
2631
def _compute_deadline(self):
2732
for record in self:
@@ -50,15 +55,11 @@ def action_refuse(self):
5055
else:
5156
record.status = 'refused'
5257

53-
_check_offer_price = models.Constraint(
54-
'CHECK(price>=0)',
55-
'offer price must be positive',
56-
)
57-
5858
@api.model
5959
def create(self, vals):
60+
if len(vals)>0:
61+
property = self.env['estate.property'].browse(vals[0]['property_id'])
6062
for record in vals:
61-
property = self.env['estate.property'].browse(record['property_id'])
6263
if property.state == 'new':
6364
property.state = 'offer_received'
6465
if record['price'] < property.best_offer:

estate/models/estate_property_tag.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class EstatePropertyTag(models.Model):
1010
property_ids = fields.Many2many('estate.property')
1111
color = fields.Integer()
1212

13-
_unique_name = models.Constraint(
14-
'UNIQUE(name)',
15-
'name already exists!',
13+
_check_unique_name = models.Constraint(
14+
'UNIQUE(name)',
15+
'name already exists!',
1616
)

estate/models/estate_property_type.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ class EstatePropertyType(models.Model):
1212
offer_count = fields.Integer(compute="_compute_total_offers")
1313
offer_ids = fields.One2many("estate.property.offer", "property_type_id")
1414

15+
_check_unique_name = models.Constraint(
16+
'UNIQUE(name)',
17+
'name already exists!',
18+
)
19+
1520
@api.depends("offer_ids")
1621
def _compute_total_offers(self):
1722
for record in self:

0 commit comments

Comments
 (0)