11from dateutil .relativedelta import relativedelta
2- from odoo import fields , models ,api ,exceptions
2+ from odoo import fields , models , api , exceptions
3+ from odoo .tools .float_utils import float_compare , float_is_zero
4+ from odoo .exceptions import ValidationError , UserError
35
46
57class EstateProperty (models .Model ):
68 _name = "estate.property"
79 _description = "Property"
8- state = fields .Selection (selection = [("New" ,"New" ), ("Offer_Received" ,"Offer Received" ) ,("Offer_Accepted" ,"Offer Accepted" ), ("Sold" ,"Sold" ), ("Cancelled" ,"Cancelled" )])
9- active = fields .Boolean ('Active' ,default = True )
10- name = fields .Char (required = True ,default = "Unkown" )
10+ _order = "id desc"
11+
12+ _positif_expected_price = models .Constraint ("CHECK (expected_price > 0)" , "A price can't be negatif" )
13+ _positif_selling_price = models .Constraint ("CHECK (selling_price > 0)" , "A price can't be negatif" )
14+
15+ state = fields .Selection (selection = [
16+ ("new" , "New" ),
17+ ("offer_received" , "Offer Received" ),
18+ ("offer_accepted" , "Offer Accepted" ),
19+ ("sold" , "Sold" ),
20+ ("cancelled" , "Cancelled" )
21+ ], default = 'new' )
22+
23+ active = fields .Boolean ('Active' , default = True )
24+ name = fields .Char (required = True , default = "Unkown" )
1125 description = fields .Text ()
1226 postcode = fields .Char ()
13- date_availability = fields .Date ("Available From" ,copy = False ,default = fields .Datetime .today () + relativedelta (months = 3 ))
14- last_seen = fields .Date ("Last Seen" , default = fields .Datetime .now )
27+ date_availability = fields .Date ("Available From" , copy = False , default = lambda self : fields .Datetime .today () + relativedelta (months = 3 ))
28+ last_seen = fields .Date ("Last Seen" , default = lambda self : fields .Datetime .now () )
1529 expected_price = fields .Float (required = True )
16- selling_price = fields .Float (readonly = True ,copy = False )
17- best_price = fields .Float (string = "Best Price" ,compute = "_get_best_price " )
30+ selling_price = fields .Float (readonly = True , copy = False )
31+ best_price = fields .Float (string = "Best Price" , compute = "_compute_best_price " )
1832 bedrooms = fields .Integer (default = 2 )
1933 living_area = fields .Integer ()
2034 facades = fields .Integer ()
2135 garage = fields .Boolean ()
2236 garden = fields .Boolean ()
2337 garden_area = fields .Integer ()
24- garden_orientation = fields .Selection (selection = [('North' ,'North' ),('South' ,'South' ),('East' ,'East' ),('West' ,'West' )])
25- total_area = fields .Float (compute = "_get_total_area" ,string = "Total Area" );
26- property_type_id = fields .Many2one ("estate.property.type" ,string = "Type" )
27- buyer_id = fields .Many2one ("res.partner" ,string = "Buyer" )
28- seller_id = fields .Many2one ("res.users" ,default = lambda self : self .env .user ,string = "Seller" )
29- tag_ids = fields .Many2many ("estate.property.tag" ,string = "Tags" )
30- offer_ids = fields .One2many ("estate.property.offer" ,"property_id" ,string = "Offers" )
38+ garden_orientation = fields .Selection (selection = [
39+ ('north' , 'North' ),
40+ ('south' , 'South' ),
41+ ('east' , 'East' ),
42+ ('west' , 'West' )])
43+
44+ total_area = fields .Float (compute = "_compute_total_area" , string = "Total Area" )
45+ property_type_id = fields .Many2one ("estate.property.type" , string = "Type" )
46+ buyer_id = fields .Many2one ("res.partner" , string = "Buyer" )
47+ seller_id = fields .Many2one ("res.users" , default = lambda self : self .env .user , string = "Seller" )
48+ tag_ids = fields .Many2many ("estate.property.tag" , string = "Tags" )
49+ offer_ids = fields .One2many ("estate.property.offer" , "property_id" , string = "Offers" )
3150
3251 def sell_property (self ):
3352 for record in self :
34- if (record .state == "Cancelled " ):
35- raise exceptions . UserError ("Can't sell cancelled property." )
36- record .state = "Sold "
53+ if (record .state == "cancelled " ):
54+ raise UserError ("Can't sell cancelled property." )
55+ record .state = "sold "
3756 return True
38-
57+
3958 def cancel_property (self ):
4059 for record in self :
41- if (record .state == "Sold " ):
42- raise exceptions . UserError ("Can't cancel sold property." )
43- record .state = "Cancelled "
60+ if (record .state == "sold " ):
61+ raise UserError ("Can't cancel sold property." )
62+ record .state = "cancelled "
4463 return True
4564
46- @api .depends ('living_area' ,'garden_area' )
47- def _get_total_area (self ):
65+ @api .depends ('living_area' , 'garden_area' )
66+ def _compute_total_area (self ):
4867 for record in self :
49- record .total_area = record .garden_area + record .living_area ;
50-
68+ record .total_area = record .garden_area + record .living_area
5169
5270 @api .depends ('offer_ids' )
53- def _get_best_price (self ):
71+ def _compute_best_price (self ):
5472 for record in self :
55- max :int = 0
56-
57- if (len (record .offer_ids )== 0 ):
73+ if (not record .offer_ids ):
5874 record .best_price = 0
5975 continue
60-
61- for offer in record .offer_ids :
62- if (offer .price >= max ):
63- max = offer .price
64- record .best_price = max
76+
77+ record .best_price = max (record .offer_ids .mapped ('price' ))
6578
6679 @api .onchange ("garden" )
67- def _garden_pre_fill (self ):
80+ def _on_change_garden (self ):
6881 self .garden_area = 10 if self .garden else 0
69- self .garden_orientation = 'North' if self .garden else ''
82+ self .garden_orientation = 'North' if self .garden else ''
83+
84+ @api .constrains ('selling_price' , 'expected_price' )
85+ def _constrain_prices (self ):
86+ for record in self :
87+ if float_is_zero (record .selling_price , 2 ):
88+ continue
89+ if (float_compare (record .selling_price , record .expected_price * 0.8 , 2 ) == - 1 ):
90+ raise ValidationError (f"Selling price is too low { record .selling_price } " )
0 commit comments