From 4b94903de2799173dcb6c41799104a84f27cac06 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 13:38:31 +0200 Subject: [PATCH 01/24] [ADD] chapter 2 --- estate/__init__.py | 0 estate/__manifest__.py | 7 +++++++ 2 files changed, 7 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..5db28ba6b16 --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,7 @@ +{ + 'name': 'estate', + 'depends': [ + 'base', + ], + 'application': 'true', +} \ No newline at end of file From 732cd24748bf2150a0ad149918b7d3e18003918c Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 14:49:44 +0200 Subject: [PATCH 02/24] [ADD] estate: chapter 3 --- estate/__init__.py | 1 + estate/__manifest__.py | 2 +- estate/models/__init__.py | 1 + estate/models/estate_property.py | 22 ++++++++++++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) 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..9a7e03eded3 100644 --- a/estate/__init__.py +++ 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 index 5db28ba6b16..36b6f715646 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -3,5 +3,5 @@ 'depends': [ 'base', ], - 'application': 'true', + 'application': 'True', } \ No newline at end of file diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 00000000000..f4c8fd6db6d --- /dev/null +++ b/estate/models/__init__.py @@ -0,0 +1 @@ +from . import estate_property \ No newline at end of file diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py new file mode 100644 index 00000000000..83f767e87e3 --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,22 @@ +from odoo import models, fields + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "test description" + + name = fields.Char('Name', required=True) + description = fields.Text('Description') + postcode = fields.Char('Post Code') + date_availability = fields.Date('Date availability') + expected_price = fields.Float('Expected price', required=True) + selling_price = fields.Float('Selling price') + bedrooms = fields.Integer('Bedrooms') + living_area = fields.Integer('Living area') + facades = fields.Integer('Facades') + garage = fields.Boolean('Garage') + garden = fields.Boolean('Garden') + garden_area = fields.Integer('Garden area') + garden_orientation = fields.Selection( + string='Orientation', + selection=[('north','North'), ('east','East'), ('south','South'), ('west','West')], + ) \ No newline at end of file From abf17f465de54e72490f9aa197739f30761a7d1b Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 15:05:30 +0200 Subject: [PATCH 03/24] [ADD] estate: author and license for chapter 2 --- estate/__manifest__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 36b6f715646..0b153381a83 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -4,4 +4,6 @@ 'base', ], 'application': 'True', + 'author': 'Odoo S.A.', + 'license': 'LGPL-3', } \ No newline at end of file From 755ef94a1cba030faa120dcb0a38588390876083 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 15:30:54 +0200 Subject: [PATCH 04/24] [ADD] estate: chapter 4 --- 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 0b153381a83..c9a94740b5e 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -6,4 +6,7 @@ 'application': 'True', 'author': 'Odoo S.A.', 'license': 'LGPL-3', + 'data': [ + 'security/ir.model.access.csv', + ], } \ No newline at end of file diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..976b61e8cb3 --- /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 \ No newline at end of file From 77b28abcacbd4d68a7a13813361013ae2d90732e Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 16:49:00 +0200 Subject: [PATCH 05/24] [ADD] estate: chapter 5 --- estate/__manifest__.py | 3 +++ estate/models/estate_property.py | 13 ++++++++++--- estate/views/estate_menus.xml | 8 ++++++++ estate/views/estate_property_views.xml | 11 +++++++++++ 4 files changed, 32 insertions(+), 3 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 c9a94740b5e..6de588a3072 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -8,5 +8,8 @@ 'license': 'LGPL-3', 'data': [ 'security/ir.model.access.csv', + + 'views/estate_menus.xml', + 'views/estate_property_views.xml', ], } \ No newline at end of file diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 83f767e87e3..0ba4cf1fdbc 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,4 +1,6 @@ from odoo import models, fields +import datetime +from dateutil.relativedelta import relativedelta class EstateProperty(models.Model): _name = "estate.property" @@ -7,10 +9,10 @@ class EstateProperty(models.Model): name = fields.Char('Name', required=True) description = fields.Text('Description') postcode = fields.Char('Post Code') - date_availability = fields.Date('Date availability') + date_availability = fields.Date('Date availability', copy=False, default=datetime.date.today()+relativedelta(months=+3)) expected_price = fields.Float('Expected price', required=True) - selling_price = fields.Float('Selling price') - bedrooms = fields.Integer('Bedrooms') + selling_price = fields.Float('Selling price', readonly=True, copy=False) + bedrooms = fields.Integer('Bedrooms', default=2) living_area = fields.Integer('Living area') facades = fields.Integer('Facades') garage = fields.Boolean('Garage') @@ -19,4 +21,9 @@ class EstateProperty(models.Model): garden_orientation = fields.Selection( string='Orientation', selection=[('north','North'), ('east','East'), ('south','South'), ('west','West')], + ) + active = fields.Boolean('Active', default=True) + state = fields.Selection( + string='state', + selection=[('new','New'),('offerreceived','Offer Received'),('offeraccepted','Offer Accepted'),('sold','Sold'),('cancelled','Cancelled')], ) \ No newline at end of file diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml new file mode 100644 index 00000000000..3885af3593b --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml new file mode 100644 index 00000000000..3b2615509aa --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,11 @@ + + + + property action + estate.property + list,form + +

Hello

+
+
+
\ No newline at end of file From f79026463710bd6cdef89d638bd7f01f9cfd016b Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 16:57:05 +0200 Subject: [PATCH 06/24] [FIX] estate errors runbot --- estate/models/estate_property.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 0ba4cf1fdbc..f7143422ddf 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -6,7 +6,7 @@ class EstateProperty(models.Model): _name = "estate.property" _description = "test description" - name = fields.Char('Name', required=True) + name = fields.Char('Name', required=True) description = fields.Text('Description') postcode = fields.Char('Post Code') date_availability = fields.Date('Date availability', copy=False, default=datetime.date.today()+relativedelta(months=+3)) @@ -20,10 +20,11 @@ class EstateProperty(models.Model): garden_area = fields.Integer('Garden area') garden_orientation = fields.Selection( string='Orientation', - selection=[('north','North'), ('east','East'), ('south','South'), ('west','West')], + selection=[('north', 'North'), ('east', 'East'), ('south', 'South'), ('west', 'West')], ) active = fields.Boolean('Active', default=True) state = fields.Selection( string='state', selection=[('new','New'),('offerreceived','Offer Received'),('offeraccepted','Offer Accepted'),('sold','Sold'),('cancelled','Cancelled')], - ) \ No newline at end of file + ) + \ No newline at end of file From 2ca3c10c49437da8313b02ff0e5ef7ac00a793b1 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 17:05:52 +0200 Subject: [PATCH 07/24] [FIX] estate errors runbot 2 --- estate/__init__.py | 2 +- estate/__manifest__.py | 4 ++-- estate/models/__init__.py | 2 +- estate/models/estate_property.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/estate/__init__.py b/estate/__init__.py index 9a7e03eded3..0650744f6bc 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -1 +1 @@ -from . import models \ No newline at end of file +from . import models diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 6de588a3072..d1a68ef9f75 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -8,8 +8,8 @@ 'license': 'LGPL-3', 'data': [ 'security/ir.model.access.csv', - + 'views/estate_menus.xml', 'views/estate_property_views.xml', ], -} \ No newline at end of file +} diff --git a/estate/models/__init__.py b/estate/models/__init__.py index f4c8fd6db6d..5e1963c9d2f 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1 @@ -from . import estate_property \ No newline at end of file +from . import estate_property diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index f7143422ddf..589ce7f4c43 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -2,6 +2,7 @@ import datetime from dateutil.relativedelta import relativedelta + class EstateProperty(models.Model): _name = "estate.property" _description = "test description" @@ -9,7 +10,7 @@ class EstateProperty(models.Model): name = fields.Char('Name', required=True) description = fields.Text('Description') postcode = fields.Char('Post Code') - date_availability = fields.Date('Date availability', copy=False, default=datetime.date.today()+relativedelta(months=+3)) + date_availability = fields.Date('Date availability', copy=False, default=datetime.date.today() + relativedelta(months=+3)) expected_price = fields.Float('Expected price', required=True) selling_price = fields.Float('Selling price', readonly=True, copy=False) bedrooms = fields.Integer('Bedrooms', default=2) @@ -25,6 +26,5 @@ class EstateProperty(models.Model): active = fields.Boolean('Active', default=True) state = fields.Selection( string='state', - selection=[('new','New'),('offerreceived','Offer Received'),('offeraccepted','Offer Accepted'),('sold','Sold'),('cancelled','Cancelled')], + selection=[('new', 'New'),('offerreceived', 'Offer Received'),('offeraccepted', 'Offer Accepted'),('sold', 'Sold'),('cancelled', 'Cancelled')], ) - \ No newline at end of file From 5108d34265542c4cd0d233880ae19644d2435b96 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Mon, 20 Oct 2025 17:14:10 +0200 Subject: [PATCH 08/24] [ADD] estate: default value to state --- estate/models/estate_property.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 589ce7f4c43..10e0649d361 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -26,5 +26,6 @@ class EstateProperty(models.Model): active = fields.Boolean('Active', default=True) state = fields.Selection( string='state', - selection=[('new', 'New'),('offerreceived', 'Offer Received'),('offeraccepted', 'Offer Accepted'),('sold', 'Sold'),('cancelled', 'Cancelled')], + selection=[('new', 'New'), ('offerreceived', 'Offer Received'), ('offeraccepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')], + default='new', ) From 950aa6ac58b4235d122a22e67e0a637cc25ed39b Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Tue, 21 Oct 2025 11:16:13 +0200 Subject: [PATCH 09/24] [ADD] chapter 6 --- estate/models/estate_property.py | 2 +- estate/views/estate_property_views.xml | 75 ++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 10e0649d361..2a38c9b8f24 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -9,7 +9,7 @@ class EstateProperty(models.Model): name = fields.Char('Name', required=True) description = fields.Text('Description') - postcode = fields.Char('Post Code') + postcode = fields.Char('Postcode') date_availability = fields.Date('Date availability', copy=False, default=datetime.date.today() + relativedelta(months=+3)) expected_price = fields.Float('Expected price', required=True) selling_price = fields.Float('Selling price', readonly=True, copy=False) diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 3b2615509aa..457598229de 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -8,4 +8,79 @@

Hello

+ + + estate.property.list + estate.property + + + + + + + + + + + + + + + estate.property.form + estate.property + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + estate.property.view.search + estate.property + + + + + + + + + + + + + \ No newline at end of file From ebd00a800e4af3e455bb2435db032d84e0b67875 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Tue, 21 Oct 2025 14:20:12 +0200 Subject: [PATCH 10/24] [ADD] chapter 7 --- estate/__manifest__.py | 3 ++- estate/models/__init__.py | 3 +++ estate/models/estate_property.py | 5 +++++ 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 | 5 ++++- estate/views/estate_menus.xml | 3 +++ estate/views/estate_property_type_views.xml | 8 ++++++++ estate/views/estate_property_views.xml | 17 ++++++++++++++--- 10 files changed, 70 insertions(+), 5 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_type_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index d1a68ef9f75..c76858b4b8f 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -9,7 +9,8 @@ 'data': [ 'security/ir.model.access.csv', - 'views/estate_menus.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 2a38c9b8f24..867571acb5f 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -29,3 +29,8 @@ class EstateProperty(models.Model): selection=[('new', 'New'), ('offerreceived', 'Offer Received'), ('offeraccepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')], default='new', ) + property_type_id = fields.Many2one('estate.property.type', string="Property Type") + salesperson_id = fields.Many2one('res.users', string='Salesman', default=lambda self: self.env.user) + buyer_id = fields.Many2one('res.partner', string='Buyer', copy=False) + tag_ids = fields.Many2many('estate.property.tag', string="Property 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..f98bc7e85f1 --- /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 = "test description" + + price = fields.Float('Price') + status = fields.Selection( + string='Status', + selection=[('accepted', 'Accepted'), ('refused', 'Refused')], + copy=False, + ) + partner_id = fields.Many2one('res.partner', string='Partner',required=True) + property_id = fields.Many2one('estate.property', string='Property', required=True) diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py new file mode 100644 index 00000000000..a499de518f9 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyTag(models.Model): + _name = "estate.property.tag" + _description = "test description" + + name = fields.Char('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..01ef745f97b --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "test description" + + name = fields.Char('Name', required=True) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 976b61e8cb3..4c593ed42e4 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 \ No newline at end of file +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 \ No newline at end of file diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml index 3885af3593b..18054d94ad8 100644 --- a/estate/views/estate_menus.xml +++ b/estate/views/estate_menus.xml @@ -4,5 +4,8 @@ + + + \ 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..c82d85d0b3e --- /dev/null +++ b/estate/views/estate_property_type_views.xml @@ -0,0 +1,8 @@ + + + + property type action + 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 457598229de..2a89c39f4dd 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -34,18 +34,18 @@ + - - + - + @@ -61,6 +61,17 @@ + + + + + + + + + + + From eab30ee0264d7a06fbb368a579d653e9c6c00600 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Tue, 21 Oct 2025 14:23:46 +0200 Subject: [PATCH 11/24] [FIX] style check for chapter 7 --- estate/models/estate_property_offer.py | 2 +- estate/models/estate_property_type.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index f98bc7e85f1..ee85d829ad3 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -11,5 +11,5 @@ class EstatePropertyOffer(models.Model): selection=[('accepted', 'Accepted'), ('refused', 'Refused')], copy=False, ) - partner_id = fields.Many2one('res.partner', string='Partner',required=True) + partner_id = fields.Many2one('res.partner', string='Partner', required=True) property_id = fields.Many2one('estate.property', string='Property', required=True) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py index 01ef745f97b..59b89a23937 100644 --- a/estate/models/estate_property_type.py +++ b/estate/models/estate_property_type.py @@ -4,5 +4,5 @@ class EstatePropertyType(models.Model): _name = "estate.property.type" _description = "test description" - + name = fields.Char('Name', required=True) From bfdee5e69c7c0df8fd82a7b3b57a2cbee7799836 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Tue, 21 Oct 2025 16:34:31 +0200 Subject: [PATCH 12/24] [IMP] Chapter 8 --- estate/__manifest__.py | 1 + estate/models/estate_property.py | 27 +++++++++++++++++--- estate/models/estate_property_offer.py | 14 +++++++++- estate/views/estate_property_offer_views.xml | 16 ++++++++++++ estate/views/estate_property_views.xml | 4 ++- 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 estate/views/estate_property_offer_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index c76858b4b8f..91d0a8b872e 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -9,6 +9,7 @@ 'data': [ 'security/ir.model.access.csv', + '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/estate_property.py b/estate/models/estate_property.py index 867571acb5f..75223f95145 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import api, models, fields import datetime from dateutil.relativedelta import relativedelta @@ -14,11 +14,11 @@ class EstateProperty(models.Model): expected_price = fields.Float('Expected price', required=True) selling_price = fields.Float('Selling price', readonly=True, copy=False) bedrooms = fields.Integer('Bedrooms', default=2) - living_area = fields.Integer('Living area') + living_area = fields.Integer('Living area (sqm)') facades = fields.Integer('Facades') garage = fields.Boolean('Garage') garden = fields.Boolean('Garden') - garden_area = fields.Integer('Garden area') + garden_area = fields.Integer('Garden area (sqm)') garden_orientation = fields.Selection( string='Orientation', selection=[('north', 'North'), ('east', 'East'), ('south', 'South'), ('west', 'West')], @@ -29,8 +29,29 @@ class EstateProperty(models.Model): selection=[('new', 'New'), ('offerreceived', 'Offer Received'), ('offeraccepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')], default='new', ) + total_area = fields.Integer('Total area (sqm)', compute='_compute_total_area') + best_offer = fields.Float('Best price', compute='_compute_best_offer') property_type_id = fields.Many2one('estate.property.type', string="Property Type") salesperson_id = fields.Many2one('res.users', string='Salesman', default=lambda self: self.env.user) buyer_id = fields.Many2one('res.partner', string='Buyer', copy=False) tag_ids = fields.Many2many('estate.property.tag', string="Property 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_offer(self): + for record in self: + record.best_offer = max(record.offer_ids.mapped('price')) if record.offer_ids else 0 + + @api.onchange('garden') + def _onchange_garden(self): + if self.garden: + self.garden_area = 10 + self.garden_orientation = 'north' + else: + self.garden_area = 0 + self.garden_orientation = None diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index ee85d829ad3..0dd1eafb74f 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 api, models, fields +import datetime class EstatePropertyOffer(models.Model): @@ -13,3 +14,14 @@ class EstatePropertyOffer(models.Model): ) partner_id = fields.Many2one('res.partner', string='Partner', required=True) property_id = fields.Many2one('estate.property', string='Property', required=True) + validity = fields.Integer('Validity', default=7) + date_deadline = fields.Date('Deadline', compute='_compute_deadline', inverse='inverse_deadline') + + @api.depends('validity') + def _compute_deadline(self): + for records in self: + records.date_deadline = fields.Datetime.add(fields.Date.today(), days=records.validity) + + def inverse_deadline(self): + for records in self: + records.validity = (records.date_deadline - fields.Date.today()).days diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml new file mode 100644 index 00000000000..d6c3fe08c77 --- /dev/null +++ b/estate/views/estate_property_offer_views.xml @@ -0,0 +1,16 @@ + + + + property type offer + estate.property.offer + + + + + + + + + + + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 2a89c39f4dd..5e0367c346c 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -43,6 +43,7 @@ + @@ -53,11 +54,12 @@ - + + From 91f5f42dd68a6cd664f308b55ffe2b63c21e6e25 Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Tue, 21 Oct 2025 16:40:11 +0200 Subject: [PATCH 13/24] [FIX] style check for chapter 8 --- estate/models/estate_property.py | 2 +- estate/models/estate_property_offer.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 75223f95145..0984ad686b0 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -41,7 +41,7 @@ class EstateProperty(models.Model): 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_offer(self): for record in self: diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index 0dd1eafb74f..869aa035cc2 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,5 +1,4 @@ from odoo import api, models, fields -import datetime class EstatePropertyOffer(models.Model): @@ -20,7 +19,7 @@ class EstatePropertyOffer(models.Model): @api.depends('validity') def _compute_deadline(self): for records in self: - records.date_deadline = fields.Datetime.add(fields.Date.today(), days=records.validity) + records.date_deadline = fields.Datetime.add(fields.Date.today(), days=records.validity) def inverse_deadline(self): for records in self: From dd92e48e6143e64938b36ac9a123b27c07e3ca4f Mon Sep 17 00:00:00 2001 From: maler-odoo Date: Wed, 22 Oct 2025 09:28:33 +0200 Subject: [PATCH 14/24] [IMP] Chapter 9 --- estate/models/estate_property.py | 17 +++++++++++++++++ estate/models/estate_property_offer.py | 19 +++++++++++++++++++ estate/views/estate_property_offer_views.xml | 6 ++++-- estate/views/estate_property_views.xml | 4 ++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 0984ad686b0..d1f0ee3b9f5 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,4 +1,5 @@ from odoo import api, models, fields +from odoo.exceptions import UserError import datetime from dateutil.relativedelta import relativedelta @@ -55,3 +56,19 @@ def _onchange_garden(self): else: self.garden_area = 0 self.garden_orientation = None + + def action_set_cancelled(self): + for record in self: + if record.state == 'sold': + raise UserError('A sold property cannot be cancelled') + else: + record.state = 'cancelled' + return True + + def action_set_sold(self): + for record in self: + if record.state == 'cancelled': + raise UserError('A cancelled property cannot be sold') + else: + record.state = 'sold' + return True diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index 869aa035cc2..d154d38098c 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,4 +1,5 @@ from odoo import api, models, fields +from odoo.exceptions import UserError class EstatePropertyOffer(models.Model): @@ -24,3 +25,21 @@ def _compute_deadline(self): def inverse_deadline(self): for records in self: records.validity = (records.date_deadline - fields.Date.today()).days + + def action_accept(self): + for record in self: + record.status = 'accepted' + if not record.property_id.buyer_id: + record.property_id.buyer_id = record.partner_id + record.property_id.selling_price = record.price + else: + raise UserError('An offer has already been accepted') + return True + + def action_decline(self): + for record in self: + if record.status == 'accepted': + raise UserError('This offer has already been accepted') + else: + record.status = 'refused' + return True diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml index d6c3fe08c77..51c8c8dc33b 100644 --- a/estate/views/estate_property_offer_views.xml +++ b/estate/views/estate_property_offer_views.xml @@ -6,11 +6,13 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + estate.property.list + estate.property.type + + + + + + + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index f91c275a077..7dc28034469 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -4,6 +4,7 @@ property action estate.property list,form + {'search_default_inactive': True}

Hello

@@ -13,14 +14,15 @@ estate.property.list estate.property - + + - + @@ -30,15 +32,19 @@ estate.property
+
+ +
- -