From 24780a6ea0c310e141cdb12b8d113c2a50f3290d Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Mon, 19 May 2025 14:00:56 +0200 Subject: [PATCH 01/14] [ADD] Estate: Adding the new Real Estate Module's directory. In this PR, I initialized the basic structure of the new Estate module directory (manifest and init files). This work is related to the second chapter of the server framework 101 official documentation by Odoo. --- estate/__init__.py | 0 estate/__manifest__.py | 15 +++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 estate/__init__.py create mode 100644 estate/__manifest__.py diff --git a/estate/__init__.py b/estate/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..18b473b2c22 --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,15 @@ +{ + 'name': 'Estate', + 'version': '1.0', + 'category': 'Real Estate', + 'sequence': 15, + 'summary': 'Track Real Estate', + 'description': "This app is made for real estate tracking.", + 'website': 'https://www.odoo.com/page/estate', + 'depends': [ + 'base' + ], + 'installable': True, + 'application': True, + 'license': 'LGPL-3' +} From 4269025440912d288daddb9cf5df37ff04805429 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Mon, 19 May 2025 16:29:56 +0200 Subject: [PATCH 02/14] [ADD] Estate: Adding Estate Model. In this PR, I added the main structure of the Estate model in order to create the estate_property table. This work is related to the third chapter of the technical onboarding (Server framework 101) from Odoo. --- estate/__init__.py | 1 + estate/models/__init__.py | 1 + estate/models/estate_property.py | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+) 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 index e69de29bb2d..0650744f6bc 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models 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..bcabd1a367a --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,25 @@ +from odoo import models, fields + + +class EstateModel(models.Model): + _name = "estate_property" + _description = "Real Estate" + _order = "sequence" + + name = fields.Char('Name', required=True) + description = fields.Char('Description') + post_code = fields.Char('Post Code') + date_availability = fields.Date('Available From') + expected_price = fields.Float('Expected Price', required=True) + selling_price = fields.Float('Selling Price') + bedrooms = fields.Integer('Bedrooms Count') + living_area = fields.Float('Living Area size') + facades = fields.Integer('Number of facades') + garage = fields.Boolean('Has garage') + garden = fields.Boolean('Has garden') + garden_area = fields.Integer('Garden area') + garden_orientation = fields.Selection( + string='Garden Orientation', + selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('west', 'West')], + help="Garden orientation selection" + ) From 7f3c5785f63032102ab0f52c2218c931b67850a8 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Tue, 20 May 2025 09:09:06 +0200 Subject: [PATCH 03/14] [ADD] Estate: Adding security access csv file. In this PR, I added the security access csv file (ir.model.access.csv) for the new Estate Model inorder to remove the undesired warning: WARNING rd-demo odoo.modules.loading: The models ['estate.property'] have no access rules in module estate, consider adding some, like: id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink. This commit is related to the 4th chapter of the Server Framework 101 from Odoo's documentation. --- estate/__manifest__.py | 3 +++ estate/security/ir.model.access.csv | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 estate/security/ir.model.access.csv diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 18b473b2c22..eb59e79dd80 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -9,6 +9,9 @@ 'depends': [ 'base' ], + 'data': [ + 'security/ir.model.access.csv', + ], 'installable': True, 'application': True, 'license': 'LGPL-3' diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..32389642d4f --- /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 +access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1 From 62e444343904a515f7b40234284a34d82ff38797 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Tue, 20 May 2025 10:37:01 +0200 Subject: [PATCH 04/14] [IMP] Estate: Adding estate property view and menus. In this commit, I added the estate property view and menus in order to start interacting with our new model using the UI. I also added two new attributes to the estate property model, which are active and state, and I set some attributes to have a default values and to not be copied when a duplication is created. This is related to the 5th chapter of the Server Framework 101 Odoo's course. --- estate/__manifest__.py | 2 ++ estate/models/estate_property.py | 17 +++++++++++++---- estate/views/estate_menus.xml | 8 ++++++++ estate/views/estate_property_views.xml | 8 ++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 estate/views/estate_menus.xml create mode 100644 estate/views/estate_property_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index eb59e79dd80..cd0087af1a4 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -11,6 +11,8 @@ ], 'data': [ 'security/ir.model.access.csv', + 'views/estate_property_views.xml', + 'views/estate_menus.xml' ], 'installable': True, 'application': True, diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index bcabd1a367a..d22b97641a6 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,18 +1,26 @@ from odoo import models, fields +from dateutil.relativedelta import relativedelta class EstateModel(models.Model): _name = "estate_property" _description = "Real Estate" - _order = "sequence" name = fields.Char('Name', required=True) description = fields.Char('Description') post_code = fields.Char('Post Code') - date_availability = fields.Date('Available From') + state = fields.Selection( + string="State", + selection=[('new', 'New'), ('offer received', 'Offer Received'), ('offer accepted', 'Offer Accepted'), ('sold', 'Sold'), ('canceled', 'Canceled')], + help="Estate current state", + required=True, + default='new', + copy=False + ) + date_availability = fields.Date('Available From', copy=False, default=lambda self: fields.Date.today() + relativedelta(months=3)) expected_price = fields.Float('Expected Price', required=True) - selling_price = fields.Float('Selling Price') - bedrooms = fields.Integer('Bedrooms Count') + selling_price = fields.Float('Selling Price', readonly=True, copy=False) + bedrooms = fields.Integer('Bedrooms Count', default=2) living_area = fields.Float('Living Area size') facades = fields.Integer('Number of facades') garage = fields.Boolean('Has garage') @@ -23,3 +31,4 @@ class EstateModel(models.Model): selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('west', 'West')], help="Garden orientation selection" ) + active = fields.Boolean('Is Active', default=True) diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml new file mode 100644 index 00000000000..338e1d54f78 --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml new file mode 100644 index 00000000000..f403335fd17 --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,8 @@ + + + + Estate Action + estate_property + list,form + + From 830ba914d800ae0fa7dfe1cf2086ee1ec98a1cdf Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Tue, 20 May 2025 13:41:10 +0200 Subject: [PATCH 05/14] [IMP] Adding basic views for estate property view. In this commit, I added a customizable list view for the estate property view. Also, I added the search, filter and group by feature using specific attributes of the estate property. This part is based on the 6th chapter of Server Framework 101 Odoo's documentation. --- estate/views/estate_property_views.xml | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index f403335fd17..8f8aae18596 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,5 +1,80 @@ + + estate.property.search + estate_property + + + + + + + + + + + + + + + + + + estate.property.form + estate_property + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.list + estate_property + + + + + + + + + + + + + Estate Action estate_property From 64b95a0f651d800412ca40cd536f473d4715f4e5 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Tue, 20 May 2025 17:09:26 +0200 Subject: [PATCH 06/14] [IMP] Estate: Adding Estate Relationships with Offers, types and tags. In this commit, I added the needed relationships between types, tags and offers using Many2one, Many2many and One2many. I also added the needed views, forms and actions (only for tags and types). I added a new notebook page within the estate property view model to display and edit the list of offers. This commit is related to the 7th chapter of Server Framework 101 in Odoo's documentation. --- estate/__manifest__.py | 3 ++ estate/models/__init__.py | 3 ++ estate/models/estate_property.py | 9 +++- estate/models/estate_property_offer.py | 15 ++++++ estate/models/estate_property_tag.py | 8 ++++ estate/models/estate_property_type.py | 8 ++++ estate/security/ir.model.access.csv | 3 ++ estate/views/estate_menus.xml | 4 +- estate/views/estate_property_offer_views.xml | 48 ++++++++++++++++++++ estate/views/estate_property_tag_views.xml | 42 +++++++++++++++++ estate/views/estate_property_type_views.xml | 42 +++++++++++++++++ estate/views/estate_property_views.xml | 40 ++++++++++++---- 12 files changed, 212 insertions(+), 13 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_tag_views.xml create mode 100644 estate/views/estate_property_type_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index cd0087af1a4..8caf9c92d35 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -11,6 +11,9 @@ ], 'data': [ 'security/ir.model.access.csv', + 'views/estate_property_tag_views.xml', + 'views/estate_property_offer_views.xml', + 'views/estate_property_type_views.xml', 'views/estate_property_views.xml', 'views/estate_menus.xml' ], diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 5e1963c9d2f..2f1821a39c1 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1,4 @@ from . import estate_property +from . import estate_property_type +from . import estate_property_tag +from . import estate_property_offer diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index d22b97641a6..2eef6a52081 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -2,8 +2,8 @@ from dateutil.relativedelta import relativedelta -class EstateModel(models.Model): - _name = "estate_property" +class EstateProperty(models.Model): + _name = "estate.property" _description = "Real Estate" name = fields.Char('Name', required=True) @@ -32,3 +32,8 @@ class EstateModel(models.Model): help="Garden orientation selection" ) active = fields.Boolean('Is Active', default=True) + property_type_id = fields.Many2one('estate.property.type', string='Property Type') + buyer_id = fields.Many2one('res.partner', 'Buyer', copy=False) + salesperson_id = fields.Many2one('res.users', 'Salesperson', index=True, default=lambda self: self.env.user) + 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..7049166136b --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,15 @@ +from odoo import models, fields + + +class EstatePropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Estate Property Offer" + + price = fields.Float(string="Price") + status = fields.Selection( + string="Status", + selection=[('accepted', 'Accepted'), ('refused', 'Refused')], + copy=False + ) + partner_id = fields.Many2one('res.partner', required=True, string="Partner") + property_id = fields.Many2one('estate.property', required=True, string="Property") diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py new file mode 100644 index 00000000000..5a39d04c914 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,8 @@ +from odoo import models, fields + + +class EstatePropertyTag(models.Model): + _name = 'estate.property.tag' + _description = 'Estate Property Tags' + + name = fields.Char(string='Name', required=True) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 00000000000..b08647d76bc --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import models, fields + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Estate Property Type" + + name = fields.Char(string="Property Type", required=True) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 32389642d4f..89f97c50842 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 access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1 +access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1 +access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1 +access_estate_property_offer,access_estate_property_offer,model_estate_property_offer,base.group_user,1,1,1,1 diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml index 338e1d54f78..8c07cc02118 100644 --- a/estate/views/estate_menus.xml +++ b/estate/views/estate_menus.xml @@ -2,7 +2,9 @@ - + + + diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml new file mode 100644 index 00000000000..454af2677d2 --- /dev/null +++ b/estate/views/estate_property_offer_views.xml @@ -0,0 +1,48 @@ + + + + estate.property.offer.search + estate.property.offer + + + + + + + + + + + + + + + estate.property.offer.form + estate.property.offer + +
+ + + + + + + + +
+
+
+ + + estate.property.offer.list + estate.property.offer + + + + + + + + + +
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml new file mode 100644 index 00000000000..f6e81a725a5 --- /dev/null +++ b/estate/views/estate_property_tag_views.xml @@ -0,0 +1,42 @@ + + + + estate.property.tag.search + estate.property.tag + + + + + + + + + estate.property.tag.form + estate.property.tag + +
+ + + + + +
+
+
+ + + estate.property.tag.list + estate.property.tag + + + + + + + + + Property tag Action + estate.property.tag + list,form + +
diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml new file mode 100644 index 00000000000..d5eae1bc78e --- /dev/null +++ b/estate/views/estate_property_type_views.xml @@ -0,0 +1,42 @@ + + + + estate.property.type.search + estate.property.type + + + + + + + + + estate.property.type.form + estate.property.type + +
+ + + + + +
+
+
+ + + estate.property.type.list + estate.property.type + + + + + + + + + Property Type Action + estate.property.type + list,form + +
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 8f8aae18596..37442994997 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,10 +1,11 @@ - + estate.property.search - estate_property + estate.property + @@ -12,16 +13,17 @@ - + + - + estate.property.form - estate_property + estate.property
@@ -30,8 +32,10 @@ + + @@ -53,15 +57,30 @@ + + + + + + + + + + + + + + +
- + estate.property.list - estate_property + estate.property @@ -71,13 +90,14 @@ + - - Estate Action - estate_property + + Properties + estate.property list,form
From 190a7c2efd7a9d3ed479da38d6f6f57b8e33d3c4 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Wed, 21 May 2025 10:24:42 +0200 Subject: [PATCH 07/14] [IMP] Estate: Adding computed fields to estate property model. In this commit, I added the following computed fields: - Estate Property: best_price and total_area - Estate Offer: validaty and date_deadline Also, I introduced the onchange method to set default values of the garden area and garden orientation when the garden attribute is set to True. This commit is related to the 8th chapter of Server Framework 101 Odoo's official documentation. --- estate/models/estate_property.py | 22 ++++++++++++++++++++-- estate/models/estate_property_offer.py | 16 +++++++++++++++- estate/views/estate_property_views.xml | 4 ++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 2eef6a52081..24bfc172b01 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,5 +1,5 @@ -from odoo import models, fields from dateutil.relativedelta import relativedelta +from odoo import api, fields, models class EstateProperty(models.Model): @@ -20,20 +20,38 @@ class EstateProperty(models.Model): date_availability = fields.Date('Available From', copy=False, default=lambda self: fields.Date.today() + relativedelta(months=3)) expected_price = fields.Float('Expected Price', required=True) selling_price = fields.Float('Selling Price', readonly=True, copy=False) + best_price = fields.Float('Best Price', compute='_compute_best_price') bedrooms = fields.Integer('Bedrooms Count', default=2) living_area = fields.Float('Living Area size') facades = fields.Integer('Number of facades') garage = fields.Boolean('Has garage') garden = fields.Boolean('Has garden') - garden_area = fields.Integer('Garden area') + garden_area = fields.Float('Garden area') garden_orientation = fields.Selection( string='Garden Orientation', selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('west', 'West')], help="Garden orientation selection" ) + total_area = fields.Float('Total Area', compute='_compute_total_area') active = fields.Boolean('Is Active', default=True) property_type_id = fields.Many2one('estate.property.type', string='Property Type') buyer_id = fields.Many2one('res.partner', 'Buyer', copy=False) salesperson_id = fields.Many2one('res.users', 'Salesperson', index=True, default=lambda self: self.env.user) tag_ids = fields.Many2many('estate.property.tag', string='Tags') offer_ids = fields.One2many('estate.property.offer', 'property_id', string='Offers') + + @api.depends('living_area', 'garden_area') + def _compute_total_area(self): + for record in self: + record.total_area = record.living_area + record.garden_area + + @api.depends('offer_ids.price') + def _compute_best_price(self): + for record in self: + prices = record.offer_ids.mapped('price') + record.best_price = max(prices) if prices else 0 + + @api.onchange('garden') + def _onchange_garden_checkbox(self): + self.garden_area = 10 if self.garden else 0 + self.garden_orientation = 'north' if self.garden else None diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index 7049166136b..8c625e0bc8c 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,4 +1,5 @@ -from odoo import models, fields +from odoo import models, fields, api +from datetime import timedelta class EstatePropertyOffer(models.Model): @@ -11,5 +12,18 @@ class EstatePropertyOffer(models.Model): selection=[('accepted', 'Accepted'), ('refused', 'Refused')], copy=False ) + validity = fields.Integer(string="Validity (days)", default=7) + date_deadline = fields.Date(string="Deadline", compute="_compute_date_deadline", inverse="_inverse_date_deadline", store=True) partner_id = fields.Many2one('res.partner', required=True, string="Partner") property_id = fields.Many2one('estate.property', required=True, string="Property") + + @api.depends('create_date', 'validity') + def _compute_date_deadline(self): + for offer in self: + create_date = offer.create_date or fields.Datetime.now() + offer.date_deadline = create_date.date() + timedelta(days=offer.validity) + + def _inverse_date_deadline(self): + for offer in self: + create_date = offer.create_date or fields.Datetime.now() + offer.validity = (offer.date_deadline - create_date.date()).days if offer.date_deadline else 0 diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 37442994997..3aa8c06b22a 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -40,6 +40,7 @@ + @@ -55,12 +56,15 @@ + + + From 8ce976bea69ac5f7810f533189ca1c45d0cf77d5 Mon Sep 17 00:00:00 2001 From: karygauss03 Date: Wed, 21 May 2025 13:26:24 +0200 Subject: [PATCH 08/14] [IMP] Estate: Adding button actions for estate. In this commit, I added buttons to the estate form view in order to set an estate as sold or canceled. Also, I did the same thing within the offer line, to accept or reject offers. This work is related to the 9th chapter of Server Framework 101 from Odoo's documentation. --- estate/models/estate_property.py | 22 +++++++++++++++++++ estate/models/estate_property_offer.py | 30 +++++++++++++++++++++++++- estate/views/estate_property_views.xml | 7 ++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 24bfc172b01..c2a4ea4751c 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,5 +1,6 @@ from dateutil.relativedelta import relativedelta from odoo import api, fields, models +from odoo.exceptions import UserError class EstateProperty(models.Model): @@ -55,3 +56,24 @@ def _compute_best_price(self): def _onchange_garden_checkbox(self): self.garden_area = 10 if self.garden else 0 self.garden_orientation = 'north' if self.garden else None + + def action_set_sold(self): + for record in self: + if (record.state == 'sold'): + raise UserError('Property Already Sold') + if record.state != 'canceled': + record.active = False + record.state = 'sold' + else: + raise UserError("Cannot sell a canceled property") + return True + + def action_set_cancel(self): + for record in self: + if record.state == 'sold': + raise UserError('Cannot cancel a sold property') + if (record.state == 'canceled'): + raise UserError("Property Already canceled") + record.active = False + record.state = 'canceled' + return True diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index 8c625e0bc8c..b68959b65ba 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,6 +1,8 @@ -from odoo import models, fields, api from datetime import timedelta +from odoo import api, fields, models +from odoo.exceptions import UserError + class EstatePropertyOffer(models.Model): _name = "estate.property.offer" @@ -27,3 +29,29 @@ def _inverse_date_deadline(self): for offer in self: create_date = offer.create_date or fields.Datetime.now() offer.validity = (offer.date_deadline - create_date.date()).days if offer.date_deadline else 0 + + def action_set_accept(self): + for record in self: + if (record.property_id.state in ('offer accepted', 'sold')): + raise UserError('An offer already accepted for this property') + if (record.property_id.state == 'canceled'): + raise UserError('Property canceled') + if (record.status in ('refused', 'accepted')): + raise UserError('Offer already accepted/refused') + + record.property_id.selling_price = record.price + record.property_id.state = 'offer accepted' + record.property_id.buyer_id = record.partner_id + record.status = 'accepted' + return True + + def action_set_refuse(self): + for record in self: + if (record.property_id.state in ('offer accepted', 'sold')): + raise UserError('An offer already accepted for this property') + if (record.property_id.state == 'canceled'): + raise UserError('Property canceled') + if (record.status in ('accepted', 'refused')): + raise UserError('Offer already accepted/refused') + record.status = 'refused' + return True diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 3aa8c06b22a..e984fa3ee74 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -27,6 +27,10 @@
+
+

@@ -40,6 +44,7 @@ + @@ -66,6 +71,8 @@ +

+
+

- + - + - @@ -59,24 +60,24 @@ - - + +
- - + + -