From 4da5a7b7f154631db114800b4b58a0c6743f0ac7 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Fri, 31 Oct 2025 11:32:49 +0530 Subject: [PATCH 01/13] [ADD] estate: Added a New Module estate_property Added a new module for estate property and completed tasks 1, 2, and 3. I added a models folder and learned to push data into PostgreSQL using ORM. --- Estate/__init__.py | 1 + Estate/__manifest__.py | 8 ++++++++ Estate/models/__init__.py | 1 + Estate/models/estate_property.py | 35 ++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 Estate/__init__.py create mode 100644 Estate/__manifest__.py create mode 100644 Estate/models/__init__.py create mode 100644 Estate/models/estate_property.py diff --git a/Estate/__init__.py b/Estate/__init__.py new file mode 100644 index 00000000000..9a7e03eded3 --- /dev/null +++ b/Estate/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/Estate/__manifest__.py b/Estate/__manifest__.py new file mode 100644 index 00000000000..63ced7ca137 --- /dev/null +++ b/Estate/__manifest__.py @@ -0,0 +1,8 @@ +{ + 'name' :'estate', + 'depends':['base'], + 'application': True, + 'installable': True, + 'category': 'Tutorials', + 'license': 'AGPL-3' +} diff --git a/Estate/models/__init__.py b/Estate/models/__init__.py new file mode 100644 index 00000000000..5e1963c9d2f --- /dev/null +++ b/Estate/models/__init__.py @@ -0,0 +1 @@ +from . import estate_property diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py new file mode 100644 index 00000000000..796e4d2903f --- /dev/null +++ b/Estate/models/estate_property.py @@ -0,0 +1,35 @@ +#always check for odoo import from venv due to which errors in psql might arise +#structure module name + +#Models +# init +# module property - this consist of all files u wanna add and substract +#init +#manifest + + + +from odoo import models, fields + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "Real Estate Property" + + name = fields.Char(required=True) + description = fields.Text() + postcode = fields.Char() + date_availability = fields.Date() + expected_price = fields.Float(required=True) + selling_price = fields.Float() + bedrooms = fields.Integer() + living_area = fields.Integer() + facades = fields.Integer() + garage = fields.Boolean() + garden = fields.Boolean() + garden_area = fields.Integer() + garden_orientation = fields.Selection([ + ('north', 'North'), + ('south', 'South'), + ('east', 'East'), + ('west', 'West'), + ]) From e5c07e0db4ad550d628294cb304e93da398cc305 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Fri, 31 Oct 2025 15:15:00 +0530 Subject: [PATCH 02/13] [IMP] estate: Implemented the Security Logic Enhanced the Security Logic for improved protection. Added the access control rights for the estate_property.py file --- Estate/__init__.py | 3 ++- Estate/__manifest__.py | 7 ++++++- Estate/models/__init__.py | 1 + Estate/models/estate_property.py | 11 +---------- Estate/security/ir.model.access.csv | 2 ++ Estate/views/estate_menus.xml | 2 ++ Estate/views/estate_property_views.xml | 0 7 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 Estate/security/ir.model.access.csv create mode 100644 Estate/views/estate_menus.xml create mode 100644 Estate/views/estate_property_views.xml diff --git a/Estate/__init__.py b/Estate/__init__.py index 9a7e03eded3..899bcc97f0f 100644 --- a/Estate/__init__.py +++ b/Estate/__init__.py @@ -1 +1,2 @@ -from . import models \ No newline at end of file +from . import models + diff --git a/Estate/__manifest__.py b/Estate/__manifest__.py index 63ced7ca137..870a555325c 100644 --- a/Estate/__manifest__.py +++ b/Estate/__manifest__.py @@ -3,6 +3,11 @@ 'depends':['base'], 'application': True, 'installable': True, + 'author':'estate', 'category': 'Tutorials', - 'license': 'AGPL-3' + 'license': 'AGPL-3', + 'data': [ + 'security/ir.model.access.csv' + 'views/estate_property_views.xml' + ] } diff --git a/Estate/models/__init__.py b/Estate/models/__init__.py index 5e1963c9d2f..c5006b18cf8 100644 --- a/Estate/models/__init__.py +++ b/Estate/models/__init__.py @@ -1 +1,2 @@ from . import estate_property + diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py index 796e4d2903f..f58ac118a9d 100644 --- a/Estate/models/estate_property.py +++ b/Estate/models/estate_property.py @@ -1,16 +1,7 @@ -#always check for odoo import from venv due to which errors in psql might arise -#structure module name - -#Models -# init -# module property - this consist of all files u wanna add and substract -#init -#manifest - - from odoo import models, fields + class EstateProperty(models.Model): _name = "estate.property" _description = "Real Estate Property" diff --git a/Estate/security/ir.model.access.csv b/Estate/security/ir.model.access.csv new file mode 100644 index 00000000000..3b6948e942e --- /dev/null +++ b/Estate/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +estate.access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1 diff --git a/Estate/views/estate_menus.xml b/Estate/views/estate_menus.xml new file mode 100644 index 00000000000..94ec487e3ee --- /dev/null +++ b/Estate/views/estate_menus.xml @@ -0,0 +1,2 @@ + + Date: Wed, 5 Nov 2025 15:14:49 +0530 Subject: [PATCH 03/13] [IMP] estate: Added menu structure and property action Introduced a new menu structure for the estate module, including a root menu and submenus for properties. Also added an action for managing estate properties with a corresponding view mode. --- Estate/__manifest__.py | 13 +++++++------ Estate/views/estate_menus.xml | 12 +++++++++++- Estate/views/estate_property_views.xml | 12 ++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Estate/__manifest__.py b/Estate/__manifest__.py index 870a555325c..a38f73ebb1b 100644 --- a/Estate/__manifest__.py +++ b/Estate/__manifest__.py @@ -1,13 +1,14 @@ { - 'name' :'estate', - 'depends':['base'], + 'name': 'estate', + 'depends': ['base'], 'application': True, 'installable': True, - 'author':'estate', + 'author': 'estate', 'category': 'Tutorials', 'license': 'AGPL-3', 'data': [ - 'security/ir.model.access.csv' - 'views/estate_property_views.xml' - ] + 'security/ir.model.access.csv', + 'views/estate_property_views.xml', + 'views/estate_menus.xml', + ], } diff --git a/Estate/views/estate_menus.xml b/Estate/views/estate_menus.xml index 94ec487e3ee..9df798df43a 100644 --- a/Estate/views/estate_menus.xml +++ b/Estate/views/estate_menus.xml @@ -1,2 +1,12 @@ - + + + + + diff --git a/Estate/views/estate_property_views.xml b/Estate/views/estate_property_views.xml index e69de29bb2d..def2d0ea112 100644 --- a/Estate/views/estate_property_views.xml +++ b/Estate/views/estate_property_views.xml @@ -0,0 +1,12 @@ + + + Properties + estate.property + list,form + +

+ Create a new property +

+
+
+
From d95830456d3b469f986b56cf711f19deb8a50607 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Thu, 6 Nov 2025 11:29:06 +0530 Subject: [PATCH 04/13] [IMP] estate: menu structure and added property views --- Estate/views/estate_menus.xml | 19 +++++++-- Estate/views/estate_property_views.xml | 58 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Estate/views/estate_menus.xml b/Estate/views/estate_menus.xml index 9df798df43a..a94b6c98069 100644 --- a/Estate/views/estate_menus.xml +++ b/Estate/views/estate_menus.xml @@ -1,12 +1,23 @@ + - + + + + diff --git a/Estate/views/estate_property_views.xml b/Estate/views/estate_property_views.xml index def2d0ea112..6b38116a90c 100644 --- a/Estate/views/estate_property_views.xml +++ b/Estate/views/estate_property_views.xml @@ -1,3 +1,4 @@ + Properties @@ -9,4 +10,61 @@

+ + + estate.property.list + estate.property + + + + + + + + + + Properties (List) + estate.property + list + + + + + + + estate.property.form + estate.property + +
+ +

+ +

+ + + + + + + + + + + + + + + +
+
+
+
+ + + Property(Form) + estate.property + form + + +
From eb055cb4a28e326abc31a96a024c9d4b65a7b7e3 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Thu, 6 Nov 2025 12:31:26 +0530 Subject: [PATCH 05/13] [IMP] estate: Added state field and search view -added search view state field and list and form views [IMP] estate: Added list & form view -added filter for new or offer received stage [IMP] estate: Implemented models and views for property offers -added models and views for property offers field --- Estate/models/estate_property.py | 13 +++++++++++++ Estate/views/estate_menus.xml | 2 -- Estate/views/estate_property_views.xml | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py index f58ac118a9d..9533c66b6dc 100644 --- a/Estate/models/estate_property.py +++ b/Estate/models/estate_property.py @@ -24,3 +24,16 @@ class EstateProperty(models.Model): ('east', 'East'), ('west', 'West'), ]) + state = fields.Selection( + [ + ('new', 'New'), + ('offer_received', 'Offer Received'), + ('offer_accepted', 'Offer Accepted'), + ('sold', 'Sold'), + ('canceled', 'Canceled'), + ], + string="Status", + required=True, + copy=False, + default='new' + ) \ No newline at end of file diff --git a/Estate/views/estate_menus.xml b/Estate/views/estate_menus.xml index a94b6c98069..d1826527722 100644 --- a/Estate/views/estate_menus.xml +++ b/Estate/views/estate_menus.xml @@ -5,12 +5,10 @@ - -
+ + + estate.property.search + estate.property + + + + + + + + + + + +
From c9b39135a8f2583c03658ca728ce730fdaeb306b Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Mon, 10 Nov 2025 00:00:39 +0530 Subject: [PATCH 06/13] [IMP] estate: Implemented models and views for property offers, tags, and types Implemented models and views for property offers tags and types --- Estate/__manifest__.py | 3 ++ Estate/models/__init__.py | 3 ++ Estate/models/estate_property.py | 8 +++++- Estate/models/estate_property_offer.py | 16 +++++++++++ Estate/models/estate_property_tag.py | 7 +++++ Estate/models/estate_property_type.py | 7 +++++ Estate/security/ir.model.access.csv | 3 ++ Estate/views/estate_menus.xml | 13 +++++++++ Estate/views/estate_property_offer_views.xml | 29 ++++++++++++++++++++ Estate/views/estate_property_tags_views.xml | 7 +++++ Estate/views/estate_property_type_views.xml | 7 +++++ Estate/views/estate_property_views.xml | 22 +++++++++++++-- 12 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 Estate/models/estate_property_offer.py create mode 100644 Estate/models/estate_property_tag.py create mode 100644 Estate/models/estate_property_type.py create mode 100644 Estate/views/estate_property_offer_views.xml create mode 100644 Estate/views/estate_property_tags_views.xml create mode 100644 Estate/views/estate_property_type_views.xml diff --git a/Estate/__manifest__.py b/Estate/__manifest__.py index a38f73ebb1b..68e2053758a 100644 --- a/Estate/__manifest__.py +++ b/Estate/__manifest__.py @@ -9,6 +9,9 @@ 'data': [ 'security/ir.model.access.csv', 'views/estate_property_views.xml', + 'views/estate_property_type_views.xml', + 'views/estate_property_offer_views.xml', + 'views/estate_property_tags_views.xml', 'views/estate_menus.xml', ], } diff --git a/Estate/models/__init__.py b/Estate/models/__init__.py index c5006b18cf8..c58783065a3 100644 --- a/Estate/models/__init__.py +++ b/Estate/models/__init__.py @@ -1,2 +1,5 @@ from . import estate_property +from . import estate_property_offer +from . import estate_property_type +from . import estate_property_tag diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py index 9533c66b6dc..fa8df5520b1 100644 --- a/Estate/models/estate_property.py +++ b/Estate/models/estate_property.py @@ -36,4 +36,10 @@ class EstateProperty(models.Model): required=True, copy=False, default='new' - ) \ No newline at end of file + ) + active = fields.Boolean(default=True) + property_type_id = fields.Many2one("estate.property.type", string="Property Type") + buyer_id = fields.Many2one("res.partner", string="Buyer") + salesperson_id = fields.Many2one("res.users", string="Salesperson") + tag_ids = fields.Many2many("estate.property.tag", string="Tags") + offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers") diff --git a/Estate/models/estate_property_offer.py b/Estate/models/estate_property_offer.py new file mode 100644 index 00000000000..467eca5a3c6 --- /dev/null +++ b/Estate/models/estate_property_offer.py @@ -0,0 +1,16 @@ +from odoo import models, fields + +class EstatePropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Real Estate Property Offer" + price = fields.Float(required=True) + status = fields.Selection( + [ + ('pending', 'Pending'), + ('accepted', 'Accepted'), + ('refused', 'Refused'), + ], + ) + + property_id = fields.Many2one("estate.property", string="Property", required=True) + partner_id = fields.Many2one("res.partner", string="Buyer", required=True) diff --git a/Estate/models/estate_property_tag.py b/Estate/models/estate_property_tag.py new file mode 100644 index 00000000000..8612845e807 --- /dev/null +++ b/Estate/models/estate_property_tag.py @@ -0,0 +1,7 @@ +from odoo import models, fields + +class EstatePropertyTag(models.Model): + _name = "estate.property.tag" + _description = "Real Estate Property Tag" + + name = fields.Char(required=True) \ No newline at end of file diff --git a/Estate/models/estate_property_type.py b/Estate/models/estate_property_type.py new file mode 100644 index 00000000000..85a0f7217e3 --- /dev/null +++ b/Estate/models/estate_property_type.py @@ -0,0 +1,7 @@ +from odoo import models, fields + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Real Estate Property Type" + + name = fields.Char(required=True) \ No newline at end of file diff --git a/Estate/security/ir.model.access.csv b/Estate/security/ir.model.access.csv index 3b6948e942e..f9b2ee19371 100644 --- a/Estate/security/ir.model.access.csv +++ b/Estate/security/ir.model.access.csv @@ -1,2 +1,5 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink estate.access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1 + +estate.access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1 +estate.access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/Estate/views/estate_menus.xml b/Estate/views/estate_menus.xml index d1826527722..dc6ef565650 100644 --- a/Estate/views/estate_menus.xml +++ b/Estate/views/estate_menus.xml @@ -18,4 +18,17 @@ name="Form" parent="estate_property_menu" action="estate_property_form_action"/> + + + + + diff --git a/Estate/views/estate_property_offer_views.xml b/Estate/views/estate_property_offer_views.xml new file mode 100644 index 00000000000..80115a18077 --- /dev/null +++ b/Estate/views/estate_property_offer_views.xml @@ -0,0 +1,29 @@ + + + estate.property.offer.list + estate.property.offer + + + + + + + + + + + estate.property.offer.form + estate.property.offer + +
+ + + + + + + +
+
+
+
\ No newline at end of file diff --git a/Estate/views/estate_property_tags_views.xml b/Estate/views/estate_property_tags_views.xml new file mode 100644 index 00000000000..9f06bbdbf11 --- /dev/null +++ b/Estate/views/estate_property_tags_views.xml @@ -0,0 +1,7 @@ + + + Property Tags + estate.property.tag + list,form + + \ No newline at end of file diff --git a/Estate/views/estate_property_type_views.xml b/Estate/views/estate_property_type_views.xml new file mode 100644 index 00000000000..6cbd93a23cf --- /dev/null +++ b/Estate/views/estate_property_type_views.xml @@ -0,0 +1,7 @@ + + + Property Types + estate.property.type + list,form + + \ No newline at end of file diff --git a/Estate/views/estate_property_views.xml b/Estate/views/estate_property_views.xml index 2d8ef30fa32..fa3e0b10d5f 100644 --- a/Estate/views/estate_property_views.xml +++ b/Estate/views/estate_property_views.xml @@ -40,7 +40,6 @@

- @@ -53,8 +52,25 @@ - + + + + + + + + + + + + + + + + + + @@ -87,4 +103,6 @@ + + From b4739528f8ec955792ea185ece57905e2ea667e1 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Mon, 10 Nov 2025 15:31:47 +0530 Subject: [PATCH 07/13] [IMP] estate: added automation logic Enhanced property model and views with new fields and improved form layout --- Estate/__manifest__.py | 2 +- Estate/models/estate_property.py | 44 +++++++++++- Estate/views/estate_property_views.xml | 99 +++++++++++++++----------- 3 files changed, 99 insertions(+), 46 deletions(-) diff --git a/Estate/__manifest__.py b/Estate/__manifest__.py index 68e2053758a..8f29426172d 100644 --- a/Estate/__manifest__.py +++ b/Estate/__manifest__.py @@ -8,10 +8,10 @@ 'license': 'AGPL-3', 'data': [ 'security/ir.model.access.csv', - 'views/estate_property_views.xml', 'views/estate_property_type_views.xml', 'views/estate_property_offer_views.xml', 'views/estate_property_tags_views.xml', + 'views/estate_property_views.xml', 'views/estate_menus.xml', ], } diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py index fa8df5520b1..a1b64665664 100644 --- a/Estate/models/estate_property.py +++ b/Estate/models/estate_property.py @@ -1,5 +1,6 @@ -from odoo import models, fields +from odoo import models, fields , api +from datetime import timedelta class EstateProperty(models.Model): @@ -9,7 +10,7 @@ class EstateProperty(models.Model): name = fields.Char(required=True) description = fields.Text() postcode = fields.Char() - date_availability = fields.Date() + create_date = fields.Date() expected_price = fields.Float(required=True) selling_price = fields.Float() bedrooms = fields.Integer() @@ -43,3 +44,42 @@ class EstateProperty(models.Model): salesperson_id = fields.Many2one("res.users", string="Salesperson") tag_ids = fields.Many2many("estate.property.tag", string="Tags") offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers") + total_area = fields.Float(compute="_compute_total_area", string="Total Area", store=True) + best_price = fields.Float(compute="_compute_best_price", string="Best Offer", store=True) + validity_days = fields.Integer(default=7) + deadline_date = fields.Date(compute="_compute_validity_date", string="Validity Date", store=True) + @api.depends('living_area', 'garden_area') + def _compute_total_area(self): + for record in self: + record.total_area = record.living_area + (record.garden_area or 0) + @api.depends('offer_ids.price') + def _compute_best_price(self): + for record in self: + if record.offer_ids: + record.best_price = max(record.offer_ids.mapped('price')) + else: + record.best_price = 0.0 + + @api.depends('create_date', 'validity_days') + def _compute_validity_date(self): + if self.create_date: + for record in self: + record.deadline_date = record.create_date + timedelta(days=record.validity_days) + else: + for record in self: + record.deadline_date = fields.Date.today() + timedelta(days=record.validity_days) + + @api.onchange('garden_area') + def _onchange_garden(self): + for record in self: + if self.garden_area == 10: + self.garden_orientation = 'north' + if self.garden_area == 20: + self.garden_orientation = 'south' + if self.garden_area == 30: + self.garden_orientation = 'east' + if self.garden_area == 40: + self.garden_orientation = 'west' + else: + self.garden_area = 0 + self.garden_orientation = False \ No newline at end of file diff --git a/Estate/views/estate_property_views.xml b/Estate/views/estate_property_views.xml index fa3e0b10d5f..deac9838911 100644 --- a/Estate/views/estate_property_views.xml +++ b/Estate/views/estate_property_views.xml @@ -30,51 +30,64 @@ + + estate.property.form + estate.property + +
+ +

+ +

+ + + + + + + + + + + + + + - - estate.property.form - estate.property - - - -

- -

- - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - -
- -
-
+ +
+ + + + + + + + + + + + + + + +
+ +
+
+ Property(Form) From 87dad3d1a96223a97544dabb65cf22b8f5777972 Mon Sep 17 00:00:00 2001 From: hapat-odoo Date: Mon, 10 Nov 2025 18:37:49 +0530 Subject: [PATCH 08/13] [IMP] estate: Implemented offer acceptance and refusal actions Implemented offer acceptance and refusal actions; added state management buttons in property views [FIX] estate: resolve Runbot style and linting errors (Ruff/Semgrep) This commit fixes all Runbot Check Style issues for the estate module. [FIX] estate: Cleaned up code by removing unnecessary blank lines in model files --- Estate/__init__.py | 1 - Estate/models/__init__.py | 1 - Estate/models/estate_property.py | 127 +++++++++++-------- Estate/models/estate_property_offer.py | 11 +- Estate/models/estate_property_tag.py | 3 +- Estate/models/estate_property_type.py | 3 +- Estate/views/estate_property_offer_views.xml | 4 + Estate/views/estate_property_views.xml | 9 ++ 8 files changed, 102 insertions(+), 57 deletions(-) diff --git a/Estate/__init__.py b/Estate/__init__.py index 899bcc97f0f..0650744f6bc 100644 --- a/Estate/__init__.py +++ b/Estate/__init__.py @@ -1,2 +1 @@ from . import models - diff --git a/Estate/models/__init__.py b/Estate/models/__init__.py index c58783065a3..82c319c6537 100644 --- a/Estate/models/__init__.py +++ b/Estate/models/__init__.py @@ -2,4 +2,3 @@ from . import estate_property_offer from . import estate_property_type from . import estate_property_tag - diff --git a/Estate/models/estate_property.py b/Estate/models/estate_property.py index a1b64665664..8b6c983c2cc 100644 --- a/Estate/models/estate_property.py +++ b/Estate/models/estate_property.py @@ -1,5 +1,4 @@ - -from odoo import models, fields , api +from odoo import models, fields, api from datetime import timedelta @@ -10,7 +9,7 @@ class EstateProperty(models.Model): name = fields.Char(required=True) description = fields.Text() postcode = fields.Char() - create_date = fields.Date() + create_date = fields.Datetime() expected_price = fields.Float(required=True) selling_price = fields.Float() bedrooms = fields.Integer() @@ -20,66 +19,90 @@ class EstateProperty(models.Model): garden = fields.Boolean() garden_area = fields.Integer() garden_orientation = fields.Selection([ - ('north', 'North'), - ('south', 'South'), - ('east', 'East'), - ('west', 'West'), + ("north", "North"), + ("south", "South"), + ("east", "East"), + ("west", "West"), ]) - state = fields.Selection( - [ - ('new', 'New'), - ('offer_received', 'Offer Received'), - ('offer_accepted', 'Offer Accepted'), - ('sold', 'Sold'), - ('canceled', 'Canceled'), - ], - string="Status", - required=True, - copy=False, - default='new' - ) active = fields.Boolean(default=True) - property_type_id = fields.Many2one("estate.property.type", string="Property Type") + + state = fields.Selection([ + ("new", "New"), + ("offer_received", "Offer Received"), + ("offer_accepted", "Offer Accepted"), + ("sold", "Sold"), + ("canceled", "Canceled"), + ], string="Status", required=True, copy=False, default="new") + + property_type_id = fields.Many2one("estate.property.type", string="Property Type") buyer_id = fields.Many2one("res.partner", string="Buyer") salesperson_id = fields.Many2one("res.users", string="Salesperson") tag_ids = fields.Many2many("estate.property.tag", string="Tags") offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers") + total_area = fields.Float(compute="_compute_total_area", string="Total Area", store=True) best_price = fields.Float(compute="_compute_best_price", string="Best Offer", store=True) - validity_days = fields.Integer(default=7) - deadline_date = fields.Date(compute="_compute_validity_date", string="Validity Date", store=True) - @api.depends('living_area', 'garden_area') + + validity = fields.Integer(default=7) + date_deadline = fields.Date( + compute="_compute_date_deadline", + inverse="_inverse_date_deadline", + store=True, + ) + + @api.depends("living_area", "garden_area") def _compute_total_area(self): for record in self: - record.total_area = record.living_area + (record.garden_area or 0) - @api.depends('offer_ids.price') + record.total_area = (record.living_area or 0) + (record.garden_area or 0) + + @api.depends("offer_ids.price") def _compute_best_price(self): for record in self: - if record.offer_ids: - record.best_price = max(record.offer_ids.mapped('price')) - else: - record.best_price = 0.0 - - @api.depends('create_date', 'validity_days') - def _compute_validity_date(self): - if self.create_date: - for record in self: - record.deadline_date = record.create_date + timedelta(days=record.validity_days) - else: - for record in self: - record.deadline_date = fields.Date.today() + timedelta(days=record.validity_days) - - @api.onchange('garden_area') - def _onchange_garden(self): + record.best_price = max(record.offer_ids.mapped("price")) if record.offer_ids else 0.0 + + @api.depends("create_date", "validity") + def _compute_date_deadline(self): for record in self: - if self.garden_area == 10: - self.garden_orientation = 'north' - if self.garden_area == 20: - self.garden_orientation = 'south' - if self.garden_area == 30: - self.garden_orientation = 'east' - if self.garden_area == 40: - self.garden_orientation = 'west' + create_date = record.create_date or fields.Date.today() + if hasattr(create_date, "date"): + create_date = create_date.date() + record.date_deadline = create_date + timedelta(days=record.validity) + + def _inverse_date_deadline(self): + for record in self: + create_date = record.create_date or fields.Date.today() + if hasattr(create_date, "date"): + create_date = create_date.date() + delta = (record.date_deadline - create_date).days if record.date_deadline else 0 + record.validity = delta + + @api.onchange("garden") + def _onchange_garden(self): + for record in self: + if record.garden: + record.garden_area = 10 + record.garden_orientation = "north" else: - self.garden_area = 0 - self.garden_orientation = False \ No newline at end of file + record.garden_area = 0 + record.garden_orientation = False + + def action_set_sold(self): + for record in self: + record.state = "sold" + + def action_set_canceled(self): + for record in self: + record.state = "canceled" + + def action_set_next_status(self): + for record in self: + if record.state == "new": + record.state = "offer_received" + elif record.state == "offer_received": + record.state = "offer_accepted" + elif record.state == "offer_accepted": + record.state = "sold" + + def action_back_to_new(self): + for record in self: + record.state = "new" diff --git a/Estate/models/estate_property_offer.py b/Estate/models/estate_property_offer.py index 467eca5a3c6..7a2e3dd34aa 100644 --- a/Estate/models/estate_property_offer.py +++ b/Estate/models/estate_property_offer.py @@ -1,5 +1,6 @@ from odoo import models, fields + class EstatePropertyOffer(models.Model): _name = "estate.property.offer" _description = "Real Estate Property Offer" @@ -11,6 +12,14 @@ class EstatePropertyOffer(models.Model): ('refused', 'Refused'), ], ) - + property_id = fields.Many2one("estate.property", string="Property", required=True) partner_id = fields.Many2one("res.partner", string="Buyer", required=True) + + def action_accept_offer(self): + for record in self: + record.status = 'accepted' + + def action_refuse_offer(self): + for record in self: + record.status = 'refused' diff --git a/Estate/models/estate_property_tag.py b/Estate/models/estate_property_tag.py index 8612845e807..3f730299abb 100644 --- a/Estate/models/estate_property_tag.py +++ b/Estate/models/estate_property_tag.py @@ -1,7 +1,8 @@ from odoo import models, fields + class EstatePropertyTag(models.Model): _name = "estate.property.tag" _description = "Real Estate Property Tag" - name = fields.Char(required=True) \ No newline at end of file + name = fields.Char(required=True) diff --git a/Estate/models/estate_property_type.py b/Estate/models/estate_property_type.py index 85a0f7217e3..ad121b33163 100644 --- a/Estate/models/estate_property_type.py +++ b/Estate/models/estate_property_type.py @@ -1,7 +1,8 @@ from odoo import models, fields + class EstatePropertyType(models.Model): _name = "estate.property.type" _description = "Real Estate Property Type" - name = fields.Char(required=True) \ No newline at end of file + name = fields.Char(required=True) diff --git a/Estate/views/estate_property_offer_views.xml b/Estate/views/estate_property_offer_views.xml index 80115a18077..8dbc66dec82 100644 --- a/Estate/views/estate_property_offer_views.xml +++ b/Estate/views/estate_property_offer_views.xml @@ -6,6 +6,8 @@ +