-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Developing a real estate advertisement module from scratch #1188
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
base: 19.0
Are you sure you want to change the base?
Changes from 3 commits
8b78ab6
83d1383
b97eef7
1809d22
cb8ff1b
722f7fb
68a2994
8682567
c15c79c
ecaacdc
9e2f6c6
ee3ef0e
d67e6f1
ac8ae99
bff1879
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from . import models |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| { | ||
| 'name': 'Real Estate', | ||
| 'version': '1.0', | ||
| 'license': 'LGPL-3', | ||
| 'summary': 'Real estate advertisement management', | ||
| 'description': """ | ||
| Real Estate tutorial module. | ||
| """, | ||
| 'author': 'Parth Sawant', | ||
| 'depends': ['base'], | ||
| 'category': 'Real Estate', | ||
| 'data': [ | ||
| 'security/ir.model.access.csv', | ||
| 'views/estate_property_views.xml', | ||
| 'views/estate_menus.xml', | ||
| ], | ||
| 'demo': [ | ||
| 'demo/demo.xml', | ||
| ], | ||
| 'application': True, | ||
| 'installable': True, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the meaning of
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. installable true means it becomes visible in all filter and we can install that specific module
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we dont need to write this as it is already true in default manifest which is in module.py |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| <odoo> | ||
| <data> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the purpose of this data tag?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tag was used in older Odoo versions and is now completely optional. But if we are using noupdate="1", the logic is — when a user renames a field and saves it in the DB, but the .xml file on disk doesn't change, then on upgrade the old data comes back from the XML. But with noupdate="1" it doesn't update and keeps what the user had renamed. And if we are writing inside the tag and want to apply noupdate="1" to all records we can put it directly on , but if we want to apply it to only a few records then we can add a separate block for those specific ones. |
||
|
|
||
| <record id="property_1" model="estate.property"> | ||
| <field name="name">Modern Downtown Apartment</field> | ||
| <field name="description">Sleek apartment in the heart of the city</field> | ||
| <field name="postcode">10001</field> | ||
| <field name="date_availability">2025-06-01</field> | ||
| <field name="expected_price">250000</field> | ||
| <field name="selling_price">245000</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">85</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> | ||
| </record> | ||
|
|
||
| <record id="property_2" model="estate.property"> | ||
| <field name="name">Suburban Family Home</field> | ||
| <field name="description">Spacious home with a large backyard</field> | ||
| <field name="postcode">20002</field> | ||
| <field name="date_availability">2025-07-15</field> | ||
| <field name="expected_price">450000</field> | ||
| <field name="selling_price">440000</field> | ||
| <field name="bedrooms">4</field> | ||
| <field name="living_area">180</field> | ||
| <field name="facades">3</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">120</field> | ||
| <field name="garden_orientation">south</field> | ||
| </record> | ||
|
|
||
| <record id="property_3" model="estate.property"> | ||
| <field name="name">Cozy Studio Near University</field> | ||
| <field name="description">Compact studio ideal for students</field> | ||
| <field name="postcode">30003</field> | ||
| <field name="date_availability">2025-05-01</field> | ||
| <field name="expected_price">95000</field> | ||
| <field name="selling_price">90000</field> | ||
| <field name="bedrooms">1</field> | ||
| <field name="living_area">35</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">east</field> | ||
| </record> | ||
|
|
||
| <record id="property_4" model="estate.property"> | ||
| <field name="name">Luxury Beachfront Villa</field> | ||
| <field name="description">Stunning villa with direct beach access</field> | ||
| <field name="postcode">40004</field> | ||
| <field name="date_availability">2025-09-01</field> | ||
| <field name="expected_price">1200000</field> | ||
| <field name="selling_price">1150000</field> | ||
| <field name="bedrooms">5</field> | ||
| <field name="living_area">350</field> | ||
| <field name="facades">4</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">500</field> | ||
| <field name="garden_orientation">south</field> | ||
| </record> | ||
|
|
||
| <record id="property_5" model="estate.property"> | ||
| <field name="name">Countryside Cottage</field> | ||
| <field name="description">Charming cottage surrounded by nature</field> | ||
| <field name="postcode">50005</field> | ||
| <field name="date_availability">2025-08-01</field> | ||
| <field name="expected_price">175000</field> | ||
| <field name="selling_price">170000</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">90</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">200</field> | ||
| <field name="garden_orientation">west</field> | ||
| </record> | ||
|
|
||
| <record id="property_6" model="estate.property"> | ||
| <field name="name">City Center Penthouse</field> | ||
| <field name="description">Exclusive penthouse with panoramic views</field> | ||
| <field name="postcode">60006</field> | ||
| <field name="date_availability">2025-10-01</field> | ||
| <field name="expected_price">850000</field> | ||
| <field name="selling_price">820000</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">210</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">False</field> | ||
| <field name="garden_area">0</field> | ||
| <field name="garden_orientation">north</field> | ||
| </record> | ||
|
|
||
| <record id="property_7" model="estate.property"> | ||
| <field name="name">Industrial Loft Conversion</field> | ||
| <field name="description">Trendy loft in a converted warehouse</field> | ||
| <field name="postcode">70007</field> | ||
| <field name="date_availability">2025-06-15</field> | ||
| <field name="expected_price">320000</field> | ||
| <field name="selling_price">310000</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">130</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">east</field> | ||
| </record> | ||
|
|
||
| <record id="property_8" model="estate.property"> | ||
| <field name="name">Hillside Bungalow</field> | ||
| <field name="description">Peaceful bungalow with valley views</field> | ||
| <field name="postcode">80008</field> | ||
| <field name="date_availability">2025-07-01</field> | ||
| <field name="expected_price">290000</field> | ||
| <field name="selling_price">280000</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">110</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">80</field> | ||
| <field name="garden_orientation">west</field> | ||
| </record> | ||
|
|
||
| <record id="property_9" model="estate.property"> | ||
| <field name="name">Gated Community Townhouse</field> | ||
| <field name="description">Secure townhouse in a premium gated complex</field> | ||
| <field name="postcode">90009</field> | ||
| <field name="date_availability">2025-11-01</field> | ||
| <field name="expected_price">530000</field> | ||
| <field name="selling_price">515000</field> | ||
| <field name="bedrooms">3</field> | ||
| <field name="living_area">150</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">60</field> | ||
| <field name="garden_orientation">south</field> | ||
| </record> | ||
|
|
||
| <record id="property_10" model="estate.property"> | ||
| <field name="name">Riverside Duplex</field> | ||
| <field name="description">Beautiful duplex with riverside views</field> | ||
| <field name="postcode">10010</field> | ||
| <field name="date_availability">2025-08-15</field> | ||
| <field name="expected_price">390000</field> | ||
| <field name="selling_price">375000</field> | ||
| <field name="bedrooms">4</field> | ||
| <field name="living_area">160</field> | ||
| <field name="facades">3</field> | ||
| <field name="garage">True</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">90</field> | ||
| <field name="garden_orientation">east</field> | ||
| </record> | ||
|
|
||
| <record id="property_11" model="estate.property"> | ||
| <field name="name">Mountain Cabin Retreat</field> | ||
| <field name="description">Rustic cabin with stunning mountain views</field> | ||
| <field name="postcode">11011</field> | ||
| <field name="date_availability">2025-09-15</field> | ||
| <field name="expected_price">210000</field> | ||
| <field name="selling_price">200000</field> | ||
| <field name="bedrooms">2</field> | ||
| <field name="living_area">75</field> | ||
| <field name="facades">1</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">True</field> | ||
| <field name="garden_area">150</field> | ||
| <field name="garden_orientation">south</field> | ||
|
|
||
| </record> | ||
|
|
||
| <record id="property_12" model="estate.property"> | ||
| <field name="name">Historic Downtown Loft</field> | ||
| <field name="description">Unique loft in a historic building</field> | ||
| <field name="postcode">12012</field> | ||
| <field name="date_availability">2025-10-15</field> | ||
| <field name="expected_price">280000</field> | ||
| <field name="selling_price">270000</field> | ||
| <field name="bedrooms">1</field> | ||
| <field name="living_area">95</field> | ||
| <field name="facades">2</field> | ||
| <field name="garage">False</field> | ||
| <field name="garden">False</field> | ||
| <field name="garden_area">0</field> | ||
| <field name="garden_orientation">north</field> | ||
| </record> | ||
|
|
||
| </data> | ||
| </odoo> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Always leave an extra line at the end of the file. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from . import estate_property |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||||||||||
| from dateutil.relativedelta import relativedelta | ||||||||||||||||||||||||||
| from odoo import fields, models | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| class EstateProperty(models.Model): | ||||||||||||||||||||||||||
|
Comment on lines
+1
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow these guidelines to import in a correct order and proper format. |
||||||||||||||||||||||||||
| _name = 'estate.property' | ||||||||||||||||||||||||||
| _description = 'Real Estate Property' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| name = fields.Char(string='Property Name', required=True, help='Enter the name of the property') | ||||||||||||||||||||||||||
| description = fields.Text(string='Property Description', help='Enter a description of the property') | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Functional strings (the strings which are shown to user) should be in double quotes. |
||||||||||||||||||||||||||
| postcode = fields.Char(string='Postcode', help='Enter the postcode of the property') | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Even if you don't mention string here, it will directly take the field name. |
||||||||||||||||||||||||||
| date_availability = fields.Date(string='Availability Date', help='Enter the date when the property becomes available', copy=False, default=lambda self: fields.Date.today() + relativedelta(months=3)) | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: try to make it <100 for a better readability.
Suggested change
|
||||||||||||||||||||||||||
| expected_price = fields.Float(string='Expected Price', required=True, help='Enter the expected price of the property') | ||||||||||||||||||||||||||
| selling_price = fields.Float(string='Selling Price', help='Enter the selling price of the property', readonly=True, copy=False) | ||||||||||||||||||||||||||
| bedrooms = fields.Integer(string='Number of Bedrooms', help='Enter the number of bedrooms in the property', default=2) | ||||||||||||||||||||||||||
| living_area = fields.Integer(string='Living Area', help='Enter the living area of the property in square meters') | ||||||||||||||||||||||||||
| facades = fields.Integer(string='Number of Facades', help='Enter the number of facades of the property') | ||||||||||||||||||||||||||
| garage = fields.Boolean(string='Garage', help='Check if the property has a garage') | ||||||||||||||||||||||||||
| garden = fields.Boolean(string='Garden', help='Check if the property has a garden') | ||||||||||||||||||||||||||
| garden_area = fields.Integer(string='Garden Area', help='Enter the area of the garden in square meters') | ||||||||||||||||||||||||||
| garden_orientation = fields.Selection( | ||||||||||||||||||||||||||
| selection=[ | ||||||||||||||||||||||||||
| ('north', 'North'), | ||||||||||||||||||||||||||
| ('south', 'South'), | ||||||||||||||||||||||||||
| ('east', 'East'), | ||||||||||||||||||||||||||
| ('west', 'West'), | ||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||
|
Comment on lines
+40
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
keep the key in single quotes and value in double quotes |
||||||||||||||||||||||||||
| string='Garden Orientation', | ||||||||||||||||||||||||||
| help='Select the orientation of the garden' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| active = fields.Boolean(string='Active', default=True, help='Set to False to archive the property') | ||||||||||||||||||||||||||
| state = fields.Selection( | ||||||||||||||||||||||||||
| selection=[ | ||||||||||||||||||||||||||
| ('new', 'New Offer'), | ||||||||||||||||||||||||||
| ('offer_received', 'Offer Received'), | ||||||||||||||||||||||||||
| ('offer_accepted', 'Offer Accepted'), | ||||||||||||||||||||||||||
| ('sold', 'Sold'), | ||||||||||||||||||||||||||
| ('cancelled', 'Cancelled') | ||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||
| string='Status', | ||||||||||||||||||||||||||
| required=True, | ||||||||||||||||||||||||||
| copy=False, | ||||||||||||||||||||||||||
| default='new', | ||||||||||||||||||||||||||
| help='Current status of the property' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,9 @@ | ||||||||||||
|
|
||||||||||||
| <odoo> | ||||||||||||
| <menuitem id="estate_menu_root" name="Estate"> | ||||||||||||
| <menuitem id="estate_first_level_menu" name="Advertisements"> | ||||||||||||
| <menuitem id="estate_property_menu_action" action="estate_property_action"/> | ||||||||||||
| </menuitem> | ||||||||||||
|
|
||||||||||||
| </menuitem> | ||||||||||||
|
Comment on lines
+5
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| </odoo> | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
|
|
||
| <record id="estate_property_view_tree" model="ir.ui.view" > | ||
| <field name="name">estate.property.list</field> | ||
| <field name="model">estate.property</field> | ||
| <field name="arch" type="xml"> | ||
| <list> | ||
| <field name="name"/> | ||
| <field name="postcode"/> | ||
| <field name="bedrooms"/> | ||
| <field name="living_area"/> | ||
| <field name="expected_price"/> | ||
| <field name="selling_price"/> | ||
| <field name="date_availability"/> | ||
| </list> | ||
| </field> | ||
| </record> | ||
|
|
||
| <record id="estate_property_view_form" model="ir.ui.view"> | ||
| <field name="name">estate.property.form</field> | ||
| <field name="model">estate.property</field> | ||
| <field name="arch" type="xml"> | ||
| <form> | ||
| <sheet> | ||
| <group> | ||
| <group> | ||
| <field name="postcode"/> | ||
| <field name="date_availability"/> | ||
| </group> | ||
| <group> | ||
| <field name="expected_price"/> | ||
| <field name="selling_price"/> | ||
| </group> | ||
| </group> | ||
| <notebook> | ||
| <page string="Description"> | ||
| <group> | ||
| <field name="description"/> | ||
| <field name="bedrooms"/> | ||
| <field name="living_area"/> | ||
| <field name="facades"/> | ||
| <field name="garage"/> | ||
| <field name="garden"/> | ||
| <field name="garden_area"/> | ||
| <field name="garden_orientation"/> | ||
| </group> | ||
| </page> | ||
| </notebook> | ||
| </sheet> | ||
| </form> | ||
| </field> | ||
| </record> | ||
|
|
||
| <record id="estate_property_view_search" model="ir.ui.view"> | ||
| <field name="name">estate.property.search</field> | ||
| <field name="model">estate.property</field> | ||
| <field name="arch" type="xml"> | ||
| <search> | ||
| <field name="name"/> | ||
| <field name="postcode"/> | ||
| <field name="expected_price"/> | ||
| <field name="selling_price"/> | ||
| <field name="date_availability"/> | ||
| <filter | ||
| name="available" | ||
| string="Available" | ||
| domain="['|', ('state', '=', 'new'), ('state', '=', 'offer_received')]" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you optimize this domain? |
||
| /> | ||
| <group expand="0" string="Group By"> | ||
| <filter name="group_by_postcode" string="Postcode" context="{'group_by': 'postcode'}"/> | ||
| </group> | ||
| </search> | ||
| </field> | ||
| </record> | ||
|
|
||
|
|
||
|
|
||
| <record id="estate_property_action" model="ir.actions.act_window"> | ||
| <field name="name">Properties</field> | ||
| <field name="res_model">estate.property</field> | ||
| <field name="view_mode">list,form</field> | ||
| </record> | ||
| </odoo> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.