-
Notifications
You must be signed in to change notification settings - Fork 3k
[ADD] estate: add module to sell property #1187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
prsan-odoo
wants to merge
9
commits into
odoo:19.0
Choose a base branch
from
odoo-dev:19.0-tutorials-estate-prsan
base: 19.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
e91c815
[ADD] estate: add module to sell property
prsan-odoo a944174
[ADD] estate: add security groups with differentiated access rights
prsan-odoo c404b9b
[IMP] estate: set field rules and reserved fields
prsan-odoo 7020cc1
[ADD] estate: add list and form views
prsan-odoo 29bea67
[IMP] estate: improve list and form views with search and filters
prsan-odoo 6c43077
[ADD] estate: add relational fields, demo data, and app logo
prsan-odoo cfd5397
[ADD] estate: add computed fields for area, best price and offer dead…
prsan-odoo b47c635
[IMP] estate: add onchange method for garden field
prsan-odoo 042e840
[IMP] estate: add optional columns, search domains, and default search
prsan-odoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from . import models |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| 'name': 'RealEstate', | ||
| 'version': '1.0', | ||
| 'category': 'Real Estate/Brokerage', | ||
| 'summary': 'A module to manage real estate advertisements and property offers', | ||
| 'description': """A simple module to manage real estate ads.List your properties, track details like bedrooms and garden,let buyers make offers, and accept or reject them.""", | ||
| 'author': 'Pranjali Sangavekar(prsan)', | ||
| 'license': 'LGPL-3', | ||
| 'depends': ['base'], | ||
| 'data': [ | ||
| 'security/security.xml', | ||
| 'security/ir.model.access.csv', | ||
| 'views/estate_property_views.xml', | ||
| 'views/estate_property_type_views.xml', | ||
| 'views/estate_property_tags_views.xml', | ||
| 'views/estate_property_offers_views.xml', | ||
| 'views/estate_menus.xml', | ||
| ], | ||
| 'demo': [ | ||
| 'demo/estate_property_data.xml', | ||
| ], | ||
| 'application': True, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
| <record id="estate_property_1" model="estate.property"> | ||
| <field name="name">Beautiful Villa in Downtown</field> | ||
| <field name="description">A stunning 3-bedroom villa with modern amenities</field> | ||
| <field name="postcode">382421</field> | ||
| <field name="date_availability">2026-06-15</field> | ||
| <field name="expected_price">6767676.00</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">9234</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">5000</field> | ||
| <field name="garden_orientation">south</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_2" model="estate.property"> | ||
| <field name="name">Cozy House with Garden</field> | ||
| <field name="description">Perfect starter home with large garden</field> | ||
| <field name="postcode">400605</field> | ||
| <field name="date_availability">2026-07-01</field> | ||
| <field name="expected_price">100000.00</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">500</field> | ||
| <field name="facades">1</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">2000</field> | ||
| <field name="garden_orientation">north</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_3" model="estate.property"> | ||
| <field name="name">Modern Apartment</field> | ||
| <field name="description">Newly built apartment in city center</field> | ||
| <field name="postcode">382421</field> | ||
| <field name="date_availability">2026-05-20</field> | ||
| <field name="expected_price">250000.00</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">750</field> | ||
| <field name="facades">3</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">False</field> | ||
| <field name="garden_area">0</field> | ||
| <field name="garden_orientation">east</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_4" model="estate.property"> | ||
| <field name="name">Traditional Cottage</field> | ||
| <field name="description">Charming countryside cottage</field> | ||
| <field name="postcode">400605</field> | ||
| <field name="date_availability">2026-08-10</field> | ||
| <field name="expected_price">180000.00</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">650</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">3000</field> | ||
| <field name="garden_orientation">west</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_5" model="estate.property"> | ||
| <field name="name">Luxury Penthouse</field> | ||
| <field name="description">High-end penthouse with panoramic views</field> | ||
| <field name="postcode">382421</field> | ||
| <field name="date_availability">2026-04-01</field> | ||
| <field name="expected_price">500000.00</field> | ||
| <field name="bedrooms">4</field> | ||
| <field name="living_area">1200</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">1000</field> | ||
| <field name="garden_orientation">south</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_6" model="estate.property"> | ||
| <field name="name">Seaside Bungalow</field> | ||
| <field name="description">Relaxing bungalow with sea view</field> | ||
| <field name="postcode">600001</field> | ||
| <field name="date_availability">2026-10-01</field> | ||
| <field name="expected_price">420000.00</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">800</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">1500</field> | ||
| <field name="garden_orientation">east</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_7" model="estate.property"> | ||
| <field name="name">Mountain Cabin</field> | ||
| <field name="description">Cozy cabin in the mountains</field> | ||
| <field name="postcode">700002</field> | ||
| <field name="date_availability">2026-11-15</field> | ||
| <field name="expected_price">210000.00</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">600</field> | ||
| <field name="facades">1</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">1200</field> | ||
| <field name="garden_orientation">west</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_8" model="estate.property"> | ||
| <field name="name">City Studio</field> | ||
| <field name="description">Compact studio apartment for singles</field> | ||
| <field name="postcode">800003</field> | ||
| <field name="date_availability">2026-12-01</field> | ||
| <field name="expected_price">95000.00</field> | ||
| <field name="bedrooms">1</field> | ||
| <field name="living_area">350</field> | ||
| <field name="facades">1</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">False</field> | ||
| <field name="garden_area">0</field> | ||
| <field name="garden_orientation">north</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_9" model="estate.property"> | ||
| <field name="name">Family Home</field> | ||
| <field name="description">Spacious home perfect for families</field> | ||
| <field name="postcode">900004</field> | ||
| <field name="date_availability">2027-01-10</field> | ||
| <field name="expected_price">300000.00</field> | ||
| <field name="bedrooms">4</field> | ||
| <field name="living_area">1100</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">2000</field> | ||
| <field name="garden_orientation">south</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| <record id="estate_property_10" model="estate.property"> | ||
| <field name="name">Downtown Office Space</field> | ||
| <field name="description">Modern office space in business district</field> | ||
| <field name="postcode">100005</field> | ||
| <field name="date_availability">2027-02-01</field> | ||
| <field name="expected_price">800000.00</field> | ||
| <field name="bedrooms">0</field> | ||
| <field name="living_area">2000</field> | ||
| <field name="facades">4</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">False</field> | ||
| <field name="garden_area">0</field> | ||
| <field name="garden_orientation">east</field> | ||
| <field name="state">new</field> | ||
| </record> | ||
| </odoo> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from . import estate_property | ||
| from . import estate_property_type | ||
| from . import estate_property_tag | ||
| from . import estate_property_offer |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| from dateutil.relativedelta import relativedelta | ||
|
|
||
| from odoo import api, fields, models | ||
|
|
||
|
|
||
| class EstateProperty(models.Model): | ||
| _name = "estate.property" | ||
| _description = "Real estate system" | ||
|
|
||
| def _get_default_date_calculation(self): | ||
| return fields.Date.today() + relativedelta(months=3) | ||
|
|
||
| name = fields.Char(string="Property Name", required=True) | ||
| description = fields.Text() | ||
| postcode = fields.Char(string="Postal Code") | ||
| date_availability = fields.Date(copy=False, default=_get_default_date_calculation) | ||
| expected_price = fields.Float(string="Expected Price", required=True) | ||
| selling_price = fields.Float(readonly=True, copy=False) | ||
| bedrooms = fields.Integer(default=2) | ||
| living_area = fields.Integer(string="Living Area", help="Living area in square meters") | ||
| facades = fields.Integer() | ||
| garage = fields.Boolean() | ||
| garden = fields.Boolean(string="Garden", help="Has garden") | ||
| garden_area = fields.Integer() | ||
| garden_orientation = fields.Selection([ | ||
| ('north', 'North'), | ||
| ('south', 'South'), | ||
| ('east', 'East'), | ||
| ('west', 'West') | ||
| ]) | ||
| active = fields.Boolean(default=True, help="Uncheck to archive this property") | ||
|
|
||
prsan-odoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| state = fields.Selection([ | ||
| ('new', 'New'), | ||
| ('offer_received', 'Offer Received'), | ||
| ('offer_accepted', 'Offer Accepted'), | ||
| ('sold', 'Sold'), | ||
| ('cancelled', 'Cancelled'), | ||
| ], required=True, copy=False, default='new') | ||
|
|
||
prsan-odoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| property_type_id = fields.Many2one('estate.property.type', string="Property Type", ondelete='cascade') | ||
| buyer_id = fields.Many2one('res.partner', string="Buyer", copy=False) | ||
| seller_id = fields.Many2one('res.users', string="Seller", default=lambda self: self.env.user) | ||
|
|
||
prsan-odoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| tag_ids = fields.Many2many('estate.property.tag', 'pranjali', 'property_id', 'tag_id', string="Tags") | ||
| offer_ids = fields.One2many('estate.property.offer', 'property_id', string="Offers") | ||
|
|
||
prsan-odoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| total_area = fields.Float(compute='_compute_total_area', store=True) | ||
| best_price = fields.Float(compute='_compute_best_price', readonly=True, 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 | ||
|
|
||
| @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.0) | ||
|
|
||
| @api.onchange('garden') | ||
| def _onchange_garden(self): | ||
| if not self.garden: | ||
| self.garden_area = 0 | ||
| self.garden_orientation = False | ||
| else: | ||
| self.garden_area = 10 | ||
| self.garden_orientation = 'north' | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| from datetime import timedelta | ||
|
|
||
| from odoo import api, fields, models | ||
prsan-odoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| class EstatePropertyOffer(models.Model): | ||
| _name = "estate.property.offer" | ||
| _description = "Real estate system - Property Offer" | ||
|
|
||
| price = fields.Float(string="Offer Price") | ||
| status = fields.Selection([ | ||
| ('accepted', 'Accepted'), | ||
| ('refused', 'Refused') | ||
| ], copy=False) | ||
|
|
||
| partner_id = fields.Many2one('res.partner', required=True) | ||
| property_id = fields.Many2one('estate.property', required=True) | ||
|
|
||
| validity = fields.Integer(default=7) | ||
|
|
||
| date_deadline = fields.Date( | ||
| compute='_compute_date_deadline', | ||
| inverse='_inverse_date_deadline' | ||
| ) | ||
|
|
||
| @api.depends('create_date', 'validity') | ||
| def _compute_date_deadline(self): | ||
| for offer in self: | ||
| date = offer.create_date or fields.Date.today() | ||
| offer.date_deadline = date + timedelta(days=offer.validity) | ||
|
|
||
| def _inverse_date_deadline(self): | ||
| for record in self: | ||
| start = record.create_date.date() if record.create_date else fields.Date.today() | ||
| record.validity = (record.date_deadline - start).days | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from odoo import fields, models | ||
|
|
||
|
|
||
| class EstatePropertyTag(models.Model): | ||
| _name = "estate.property.tag" | ||
| _description = "Real estate system - Property Tag" | ||
|
|
||
| name = fields.Char(string="Tag Name", required=True) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from odoo import fields, models | ||
|
|
||
|
|
||
| class EstatePropertyType(models.Model): | ||
| _name = "estate.property.type" | ||
| _description = "Real estate system - Property Type" | ||
|
|
||
| name = fields.Char(string="Property Type Name", required=True) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
| access_estate_property_manager,estate.property manager,model_estate_property,estate.estate_group_manager,1,1,1,1 | ||
| access_estate_property_user,estate.property user,model_estate_property,estate.estate_group_user,1,1,0,0 | ||
| access_estate_property_type_manager,estate.property.type manager,model_estate_property_type,estate.estate_group_manager,1,1,1,1 | ||
| access_estate_property_type_user,estate.property.type user,model_estate_property_type,estate.estate_group_user,1,0,0,0 | ||
| access_estate_property_tag_manager,estate.property.tag manager,model_estate_property_tag,estate.estate_group_manager,1,1,1,1 | ||
| access_estate_property_tag_user,estate.property.tag user,model_estate_property_tag,estate.estate_group_user,1,0,0,0 | ||
| access_estate_property_offer_manager,estate.property.offer manager,model_estate_property_offer,estate.estate_group_manager,1,1,1,1 | ||
| access_estate_property_offer_user,estate.property.offer user,model_estate_property_offer,estate.estate_group_user,1,1,1,0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
| <data> | ||
| <record id="module_category_real_estate_brokerage" model="ir.module.category"> | ||
| <field name="name">Real Estate</field> | ||
| <field name="description">Real Estate Management</field> | ||
| </record> | ||
|
|
||
| <record model="res.groups.privilege" id="groups_privilege_real_estate"> | ||
| <field name="name">Real Estate</field> | ||
| <field name="category_id" ref="module_category_real_estate_brokerage"/> | ||
| </record> | ||
|
|
||
| <record id="estate_group_user" model="res.groups"> | ||
| <field name="name">Agent</field> | ||
| <field name="privilege_id" ref="groups_privilege_real_estate"/> | ||
| </record> | ||
|
|
||
| <record id="estate_group_manager" model="res.groups"> | ||
| <field name="name">Manager</field> | ||
| <field name="privilege_id" ref="groups_privilege_real_estate"/> | ||
| <field name="implied_ids" eval="[Command.link(ref('estate_group_user'))]"/> | ||
| </record> | ||
|
|
||
| <record id="base.user_admin" model="res.users"> | ||
| <field name="group_ids" eval="[Command.link(ref('estate_group_manager'))]"/> | ||
| </record> | ||
| </data> | ||
| </odoo> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
| <menuitem id="estate_menu_root" name="Real Estate" web_icon="estate,static/description/icon.png"> | ||
| <menuitem id="estate_first_level_menu" name="Advertisements"> | ||
| <menuitem id="estate_property_menu_action" name="Properties" action="estate_property_action"/> | ||
| </menuitem> | ||
| <menuitem id="estate_settings_menu" name="Settings"> | ||
| <menuitem id="estate_property_type_menu" name="Property Types" action="estate_property_type_action"/> | ||
| <menuitem id="estate_property_tags_menu" name="Property Tags" action="estate_property_tags_action"/> | ||
| </menuitem> | ||
| </menuitem> | ||
| </odoo> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
| <record id="estate_property_offers_view_form" model="ir.ui.view"> | ||
| <field name="name">estate.property.offer.form</field> | ||
| <field name="model">estate.property.offer</field> | ||
| <field name="arch" type="xml"> | ||
| <form> | ||
| <sheet> | ||
| <group> | ||
| <field name="price"/> | ||
| <field name="partner_id"/> | ||
| <field name="validity"/> | ||
| <field name="date_deadline"/> | ||
| <field name="status"/> | ||
| </group> | ||
| </sheet> | ||
| </form> | ||
| </field> | ||
| </record> | ||
|
|
||
| <record id="estate_property_offers_view_list" model="ir.ui.view"> | ||
| <field name="name">estate.property.offer.list</field> | ||
| <field name="model">estate.property.offer</field> | ||
| <field name="arch" type="xml"> | ||
| <list editable="bottom" default_order="price desc"> | ||
| <field name="price"/> | ||
| <field name="partner_id"/> | ||
| <field name="validity"/> | ||
| <field name="date_deadline"/> | ||
| <field name="status"/> | ||
| </list> | ||
| </field> | ||
| </record> | ||
| </odoo> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.