From 42c7f60a214a419c5d4a438cdcbe8d99e8057057 Mon Sep 17 00:00:00 2001 From: manv-afk Date: Mon, 16 Sep 2024 14:57:16 +0200 Subject: [PATCH 01/10] first commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 89e6a2b229..13524591ac 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,5 @@ It has 3 branches for each Odoo version: one for the bases, one for The first contains the code of the modules that serve as base for the tutorials, and the others contains the code of each chapter with the complete solution. + +First changes From ba9fce52c433919eeea3147940bfd6f4139a0bad Mon Sep 17 00:00:00 2001 From: manv-afk Date: Tue, 17 Sep 2024 11:44:46 +0200 Subject: [PATCH 02/10] Tutorial: end of chapter 5 --- estate/__init__.py | 1 + estate/__manifest__.py | 13 ++++++++++++ estate/models/__init__.py | 1 + estate/models/estate_property.py | 28 ++++++++++++++++++++++++++ estate/security/ir.model.access.csv | 2 ++ estate/views/estate_menu.xml | 8 ++++++++ estate/views/estate_property_views.xml | 8 ++++++++ 7 files changed, 61 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 create mode 100644 estate/security/ir.model.access.csv create mode 100644 estate/views/estate_menu.xml create mode 100644 estate/views/estate_property_views.xml diff --git a/estate/__init__.py b/estate/__init__.py new file mode 100644 index 0000000000..9a7e03eded --- /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 0000000000..ca9213e86e --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,13 @@ +{ + 'name': 'Real estate', + 'depends': [ + 'base', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/estate_property_views.xml', + 'views/estate_menu.xml', + ], + 'application': True, + 'license': 'OEEL-1' +} \ No newline at end of file diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 0000000000..f4c8fd6db6 --- /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 0000000000..a0c80947eb --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,28 @@ +from odoo import fields, models +from datetime import timedelta + + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "Real estate property" + active = fields.Boolean(default=True) + name = fields.Char(required=True) + postcode = fields.Char() + date_availability = fields.Date(copy=False, default=lambda self: fields.Date.today() + timedelta(days=90)) + expected_price = fields.Float(required=True) + selling_price = fields.Float(readonly=True, copy=False) + bedrooms = fields.Integer(default=2) + 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")] + ) + state = fields.Selection( + [("new", "New"), ("offer_received", "Offer Received"), ("offer_accepted", "Offer Accepted"), ("sold", "Sold")], + default="new", + required=True, + copy = False, + ) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 0000000000..fe21e56c6d --- /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,estate.model_estate_property,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml new file mode 100644 index 0000000000..570bdf40c7 --- /dev/null +++ b/estate/views/estate_menu.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 0000000000..f86e19d736 --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,8 @@ + + + + Properties + estate.property + tree,form + + \ No newline at end of file From 2f9aeb480dbd6c5493e1c9b90bdde0a545722cdd Mon Sep 17 00:00:00 2001 From: manv-afk Date: Tue, 17 Sep 2024 14:58:32 +0200 Subject: [PATCH 03/10] Tutorial: end of chapter 6 --- estate/models/estate_property.py | 4 +- estate/views/estate_property_views.xml | 76 ++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index a0c80947eb..60319c855e 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -6,13 +6,13 @@ class EstateProperty(models.Model): _name = "estate.property" _description = "Real estate property" active = fields.Boolean(default=True) - name = fields.Char(required=True) + name = fields.Char(required=True, string="Title") postcode = fields.Char() date_availability = fields.Date(copy=False, default=lambda self: fields.Date.today() + timedelta(days=90)) expected_price = fields.Float(required=True) selling_price = fields.Float(readonly=True, copy=False) bedrooms = fields.Integer(default=2) - living_area = fields.Integer() + living_area = fields.Integer(string="Living area (sqm)") facades = fields.Integer() garage = fields.Boolean() garden = fields.Boolean() diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index f86e19d736..7d13660db1 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -5,4 +5,80 @@ estate.property tree,form + + + estate.property.tree + estate.property + + + + + + + + + + + + + + + estate.property.form + estate.property + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.search + estate.property + + + + + + + + + + + + + + + + \ No newline at end of file From 383466153997e3ef4d4d751b64575a998e38a8a1 Mon Sep 17 00:00:00 2001 From: manv-afk Date: Tue, 17 Sep 2024 17:28:26 +0200 Subject: [PATCH 04/10] Tutorial: end of chapter 7 --- estate/__manifest__.py | 3 ++ estate/models/__init__.py | 5 +++- 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 | 9 ++++++ estate/security/ir.model.access.csv | 5 +++- estate/views/estate_menu.xml | 4 +++ estate/views/estate_property_offer_views.xml | 29 ++++++++++++++++++++ estate/views/estate_property_tag_views.xml | 8 ++++++ estate/views/estate_property_type_views.xml | 8 ++++++ estate/views/estate_property_views.xml | 18 +++++++++++- 12 files changed, 114 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_tag_views.xml create mode 100644 estate/views/estate_property_type_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index ca9213e86e..ccea5a6a27 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -6,6 +6,9 @@ 'data': [ 'security/ir.model.access.csv', 'views/estate_property_views.xml', + 'views/estate_property_type_views.xml', + 'views/estate_property_tag_views.xml', + 'views/estate_property_offer_views.xml', 'views/estate_menu.xml', ], 'application': True, diff --git a/estate/models/__init__.py b/estate/models/__init__.py index f4c8fd6db6..09b2099fe8 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1,4 @@ -from . import estate_property \ No newline at end of file +from . import estate_property +from . import estate_property_type +from . import estate_property_tag +from . import estate_property_offer \ No newline at end of file diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 60319c855e..ceebfcbaf3 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -26,3 +26,8 @@ class EstateProperty(models.Model): required=True, copy = False, ) + property_type_id = fields.Many2one("estate.property.type", string="Property Type") + buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False) + salesperson_id = fields.Many2one("res.users", string="Salesperson", default=lambda self: self.env.user) + 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 0000000000..d20508fd03 --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,15 @@ +from odoo import fields, models + + +class EstatePropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Real estate property offer" + + price = fields.Float(required=True) + status = fields.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 0000000000..881e5206d5 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyTags(models.Model): + _name = "estate.property.tag" + _description = "Real estate property tag" + + name = fields.Char(required=True) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 0000000000..e936cfeabd --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,9 @@ +from odoo import fields, models + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Real estate property type" + + name = fields.Char(required=True) + # property_ids = fields.One2many("estate.property", "property_type_id") \ No newline at end of file diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index fe21e56c6d..78458c1cb6 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,estate.model_estate_property,base.group_user,1,1,1,1 \ No newline at end of file +estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1 +estate.access_estate_property_type,access_estate_property_type,estate.model_estate_property_type,base.group_user,1,1,1,1 +estate.access_estate_property_tag,access_estate_property_tag,estate.model_estate_property_tag,base.group_user,1,1,1,1 +estate.access_estate_property_offer,access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,1,1,1 diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml index 570bdf40c7..195ceb5036 100644 --- a/estate/views/estate_menu.xml +++ b/estate/views/estate_menu.xml @@ -4,5 +4,9 @@ + + + + \ No newline at end of file diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml new file mode 100644 index 0000000000..e52ad83239 --- /dev/null +++ b/estate/views/estate_property_offer_views.xml @@ -0,0 +1,29 @@ + + + + estate.property.offer.tree + estate.property.offer + + + + + + + + + + + estate.property.offer.form + estate.property.offer + +
+ + + + + +
+
+
+ +
\ No newline at end of file diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml new file mode 100644 index 0000000000..5b48773965 --- /dev/null +++ b/estate/views/estate_property_tag_views.xml @@ -0,0 +1,8 @@ + + + + Property tags + estate.property.tag + tree,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 0000000000..fb2174307b --- /dev/null +++ b/estate/views/estate_property_type_views.xml @@ -0,0 +1,8 @@ + + + + Property types + estate.property.type + tree,form + + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 7d13660db1..d9160d1fb2 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -18,6 +18,7 @@ + @@ -33,6 +34,9 @@ + + + @@ -46,6 +50,7 @@ + @@ -53,7 +58,17 @@ - + + + + + + + + + + + @@ -73,6 +88,7 @@ + From 7a91d1fcaf047d4abd0a6320bc04074e10fc2f47 Mon Sep 17 00:00:00 2001 From: manv-afk Date: Wed, 18 Sep 2024 14:00:44 +0200 Subject: [PATCH 05/10] Tutorial: end of chapter 8 --- estate/models/estate_property.py | 24 +++++++++++++++++++- estate/models/estate_property_offer.py | 17 +++++++++++++- estate/views/estate_property_offer_views.xml | 5 +++- estate/views/estate_property_views.xml | 4 +++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index ceebfcbaf3..88ab0249ed 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,4 +1,4 @@ -from odoo import fields, models +from odoo import fields, models, api from datetime import timedelta @@ -31,3 +31,25 @@ class EstateProperty(models.Model): salesperson_id = fields.Many2one("res.users", string="Salesperson", default=lambda self: self.env.user) tag_ids = fields.Many2many("estate.property.tag", string="Property Tags") offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers") + total_area = fields.Float(compute="_compute_total_area") + best_price = fields.Float(compute="_compute_best_price") + + @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: + record.best_price = max(record.offer_ids.mapped('price'), default=0) + + @api.onchange("garden") + def _onchange_garden(self): + if self.garden: + self.garden_area = 10 + self.garden_orientation = "north" + else: + self.garden_area = None + self.garden_orientation = None + diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index d20508fd03..b602bcfd50 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,4 +1,4 @@ -from odoo import fields, models +from odoo import fields, models, api class EstatePropertyOffer(models.Model): @@ -13,3 +13,18 @@ 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(default=7) + date_deadline = fields.Date(compute="_compute_date_deadline", inverse="_inverse_date_deadline") + + @api.depends("validity", "create_date") + def _compute_date_deadline(self): + for record in self: + if record.create_date: + record.date_deadline = fields.Datetime.add(record.create_date, days=record.validity) + else: + record.date_deadline = fields.Datetime.add(fields.Datetime.today(), days=record.validity) + + def _inverse_date_deadline(self): + for record in self: + date = record.create_date.date() if record.create_date else fields.Date.today() + record.validity = (record.date_deadline - date).days \ No newline at end of file diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml index e52ad83239..6449167be8 100644 --- a/estate/views/estate_property_offer_views.xml +++ b/estate/views/estate_property_offer_views.xml @@ -7,6 +7,8 @@ + + @@ -20,10 +22,11 @@ + + - \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index d9160d1fb2..3197c16a07 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -39,18 +39,19 @@ + + - @@ -58,6 +59,7 @@ + From 791541786b593dbc8f3eb818944d2b4961b564ae Mon Sep 17 00:00:00 2001 From: manv-afk Date: Wed, 18 Sep 2024 14:56:50 +0200 Subject: [PATCH 06/10] Tutorial: end of chapter 9 --- estate/models/estate_property.py | 17 ++++++++++++++++- estate/models/estate_property_offer.py | 18 +++++++++++++++++- estate/views/estate_property_offer_views.xml | 2 ++ estate/views/estate_property_views.xml | 6 ++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 88ab0249ed..168c5f9af5 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,5 +1,6 @@ from odoo import fields, models, api from datetime import timedelta +from odoo.exceptions import UserError class EstateProperty(models.Model): @@ -21,7 +22,7 @@ class EstateProperty(models.Model): [("north", "North"), ("south", "South"), ("east", "East"), ("west", "West")] ) state = fields.Selection( - [("new", "New"), ("offer_received", "Offer Received"), ("offer_accepted", "Offer Accepted"), ("sold", "Sold")], + [("new", "New"), ("offer_received", "Offer Received"), ("offer_accepted", "Offer Accepted"), ("sold", "Sold"), ("canceled", "Canceled")], default="new", required=True, copy = False, @@ -53,3 +54,17 @@ def _onchange_garden(self): self.garden_area = None self.garden_orientation = None + def action_sold_property(self): + for record in self: + if record.state == "canceled": + raise UserError("A canceled property cannot be sold") + record.state = "sold" + return True + + def action_cancel_property(self): + for record in self: + if record.state == "sold": + raise UserError("A sold property cannot be canceled") + record.state = "canceled" + return True + diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index b602bcfd50..11ef340932 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -1,4 +1,5 @@ from odoo import fields, models, api +from odoo.exceptions import UserError class EstatePropertyOffer(models.Model): @@ -27,4 +28,19 @@ def _compute_date_deadline(self): def _inverse_date_deadline(self): for record in self: date = record.create_date.date() if record.create_date else fields.Date.today() - record.validity = (record.date_deadline - date).days \ No newline at end of file + record.validity = (record.date_deadline - date).days + + def action_accept_offer(self): + for record in self: + if record.property_id.state == "sold": + raise UserError("The property is already sold") + record.status = "accepted" + record.property_id.buyer_id = record.partner_id + record.property_id.selling_price = record.price + record.property_id.state = "sold" + return True + + def action_refuse_offer(self): + for record in self: + record.status = "refused" + return True \ No newline at end of file diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml index 6449167be8..a785f73d3b 100644 --- a/estate/views/estate_property_offer_views.xml +++ b/estate/views/estate_property_offer_views.xml @@ -9,6 +9,8 @@ + + +
+

+ +

+
+ + + + + + + + + + + + + +
+ + + + estate_property_type.view.tree + 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 aa06a2b501..256aceb636 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -4,21 +4,23 @@ Properties estate.property tree,form + {'search_default_available': True} estate.property.tree estate.property - + - + + @@ -29,8 +31,9 @@
-
@@ -40,11 +43,11 @@ - + - + @@ -62,15 +65,15 @@ - - + + - + @@ -94,7 +97,7 @@ - + From 7ac7317da4ed01bd86dd500c8361178ec28a2593 Mon Sep 17 00:00:00 2001 From: manv-afk Date: Thu, 19 Sep 2024 17:14:20 +0200 Subject: [PATCH 09/10] Tutorial: end of chapter 12 --- estate/__manifest__.py | 1 + estate/models/__init__.py | 3 ++- estate/models/estate_property.py | 5 +++++ estate/models/estate_property_offer.py | 10 +++++++++- estate/models/res_user.py | 6 ++++++ estate/views/res_users_views.xml | 19 +++++++++++++++++++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 estate/models/res_user.py create mode 100644 estate/views/res_users_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index e346ea73f2..af543c238b 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -10,6 +10,7 @@ 'views/estate_property_offer_views.xml', 'views/estate_property_type_views.xml', 'views/estate_menu.xml', + 'views/res_users_views.xml', ], 'application': True, 'license': 'OEEL-1' diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 09b2099fe8..4419cea280 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1,4 +1,5 @@ from . import estate_property from . import estate_property_type from . import estate_property_tag -from . import estate_property_offer \ No newline at end of file +from . import estate_property_offer +from . import res_user \ No newline at end of file diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 9f5862fbc1..9640b9f25d 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -83,3 +83,8 @@ def action_cancel_property(self): record.state = "canceled" return True + @api.ondelete(at_uninstall=False) + def _unlink_if_new_or_canceled(self): + for record in self: + if record.state not in ('new', 'canceled'): + raise UserError("Can't delete active property") \ No newline at end of file diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index 8da24129c2..b5d24cc7c2 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -48,4 +48,12 @@ def action_accept_offer(self): def action_refuse_offer(self): for record in self: record.status = "refused" - return True \ No newline at end of file + return True + + @api.model + def create(self, vals): + property_id = self.env["estate.property"].browse(vals['property_id']) + if vals['price'] < property_id.best_price: + raise UserError("Your offer is too low") + property_id.state = "offer_received" + return super().create(vals) diff --git a/estate/models/res_user.py b/estate/models/res_user.py new file mode 100644 index 0000000000..7c29943314 --- /dev/null +++ b/estate/models/res_user.py @@ -0,0 +1,6 @@ +from odoo import models, fields + +class User(models.Model): + _inherit = ['res.users'] + + property_ids = fields.One2many("estate.property", "salesperson_id", string="Sales person") \ No newline at end of file diff --git a/estate/views/res_users_views.xml b/estate/views/res_users_views.xml new file mode 100644 index 0000000000..0b92d21da8 --- /dev/null +++ b/estate/views/res_users_views.xml @@ -0,0 +1,19 @@ + + + + + res.users.view.form.inherit.estate + res.users + + + + + + + + + + + + + \ No newline at end of file From 7fdd19571f4a38a151c45b628a04ee8bd39b39ee Mon Sep 17 00:00:00 2001 From: manv-afk Date: Fri, 20 Sep 2024 12:53:02 +0200 Subject: [PATCH 10/10] Tutorial: end of chapter 14 --- estate/views/estate_property_views.xml | 33 +++++++++++++++++++++++- estate_account/__init__.py | 1 + estate_account/__manifest__.py | 8 ++++++ estate_account/models/__init__.py | 1 + estate_account/models/estate_property.py | 24 +++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 estate_account/__init__.py create mode 100644 estate_account/__manifest__.py create mode 100644 estate_account/models/__init__.py create mode 100644 estate_account/models/estate_property.py diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 256aceb636..7e7cad3a41 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -3,7 +3,7 @@ Properties estate.property - tree,form + tree,form,kanban {'search_default_available': True} @@ -108,4 +108,35 @@ + + + estate_property.view.kanban + estate.property + + + + + +
+ +
+ Expected price: + +
+ + Best offer: + + + + Selling price: + + +
+
+
+
+
+
+
+ \ No newline at end of file diff --git a/estate_account/__init__.py b/estate_account/__init__.py new file mode 100644 index 0000000000..9a7e03eded --- /dev/null +++ b/estate_account/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/estate_account/__manifest__.py b/estate_account/__manifest__.py new file mode 100644 index 0000000000..0c02ab4da7 --- /dev/null +++ b/estate_account/__manifest__.py @@ -0,0 +1,8 @@ +{ + 'name': 'Estate account', + 'depends': [ + 'estate', + 'account', + ], + 'license': 'OEEL-1' +} \ No newline at end of file diff --git a/estate_account/models/__init__.py b/estate_account/models/__init__.py new file mode 100644 index 0000000000..f4c8fd6db6 --- /dev/null +++ b/estate_account/models/__init__.py @@ -0,0 +1 @@ +from . import estate_property \ No newline at end of file diff --git a/estate_account/models/estate_property.py b/estate_account/models/estate_property.py new file mode 100644 index 0000000000..88a05a6c00 --- /dev/null +++ b/estate_account/models/estate_property.py @@ -0,0 +1,24 @@ +from odoo import models, Command + +class EstateProperty(models.Model): + _inherit = "estate.property" + + def action_sold_property(self): + for record in self: + self.env["account.move"].create({ + 'partner_id': record.buyer_id.id, + 'move_type': 'out_invoice', + "invoice_line_ids": [ + Command.create({ + "name": "6% of selling price", + "quantity": 1, + "price_unit": self.selling_price*0.06 + }), + Command.create({ + "name": "Administration fees", + "quantity": 1, + "price_unit": 100 + }) + ] + }) + return super().action_sold_property() \ No newline at end of file