Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions estate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
24 changes: 24 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "Real Estate",
"version": "19.0.0",
"category": "Tutorials",
"depends": ["base"],
"author": "hemeh",
"application": True,
"summary": "Manage real estate properties",
"description": """
Manage real estate properties.
""",
"data": [
"security/ir.model.access.csv",
"views/estate_property_type_views.xml",
"views/estate_property_offer_views.xml",
"views/estate_property_tag_views.xml",
"views/estate_property_views.xml",
"views/estate_menus.xml",
],
"website": "https://odoo.com",
"license": "LGPL-3",
"installable": True,

}
6 changes: 6 additions & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from . import (
estate_property,
estate_property_offer,
estate_property_tag,
estate_property_type,
)
80 changes: 80 additions & 0 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from dateutil.relativedelta import relativedelta

from odoo import fields, models


class EstateProperty(models.Model):
_name = "estate.property"
_description = "estate property used to buy and sell houses"

name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
date_availability = fields.Date(
default=lambda self: fields.Date.context_today(self) + relativedelta(months=3),
copy=False,
)
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(required=True)
garden_orientation = fields.Selection(
selection=[
("north", "North"),
("south", "South"),
("east", "East"),
("west", "West"),
],
)
state = fields.Selection(
selection=[
("new", "New"),
("offer_accepted", "Offer Accepted"),
("offer_received", "Offer Received"),
("sold", "Sold"),
("cancelled", "Cancelled"),
],
Comment on lines 36 to 42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
selection=[
("New", "New"),
("Offer Accepted", "Offer Accepted"),
("Offer Received", "Offer Received"),
("Sold", "Sold"),
("Cancelled", "Cancelled"),
],
selection=[
('new', "New"),
('offer_accepted', "Offer Accepted"),
('offer_received', "Offer Received"),
('sold', "Sold"),
('cancelled', "Cancelled"),
],

Use underscores while defining keys for selection field.
Also the key should always come first, followed by the value.

string="State",
)

active = fields.Boolean(default=False)

property_type_id = fields.Many2one(
"estate.property.type",
string="Property Type",
)

salesman_id = fields.Many2one(
'res.users',
string="Salesman",
default=lambda self: self.env.user,

)

buyer_id = fields.Many2one(
'res.partner',
string="Buyer",
copy=False,
)

tag_id = fields.Many2many(
string='Tags',
comodel_name='estate.property.tag',
)
property_id = fields.One2many(
string='property',
comodel_name='estate.property.offer',
inverse_name='property_id',
)

offer_id = fields.One2many(
'estate.property.offer',
'property_id',
string='Offers',
)
26 changes: 26 additions & 0 deletions estate/models/estate_property_offer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from odoo import fields, models


class EstatePropertyOffer(models.Model):
_name = "estate.property.offer"
_description = "Real Estate Property Offer"

price = fields.Float(string="Price")
status = fields.Selection(
selection=[
("accepted", "Accepted"),
("refused", "Refused"),
],
string="Status",
copy=False,
)
partner_id = fields.Many2one(
"res.partner",
string="Partner",
required=True,
)
property_id = fields.Many2one(
"estate.property",
string="Property",
required=True,
)
8 changes: 8 additions & 0 deletions estate/models/estate_property_tag.py
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 = "Estate Property Tags"

name = fields.Char(string="Name", required=True)
8 changes: 8 additions & 0 deletions estate/models/estate_property_type.py
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 = "Estate Property Types"

name = fields.Char(string="Property Type", required=True)
6 changes: 6 additions & 0 deletions estate/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1
access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1
access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1
access_estate_property_,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
42 changes: 42 additions & 0 deletions estate/views/estate_menus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the <data> tag here, what was the reason for adding it?
Do you think the <data> tag changes anything functionally here, or would it behave the same without it?

Copy link
Author

@hemeh-odoo hemeh-odoo Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mam generally the data tag acts as a container inside the odoo tag so that Odoo can load all records correctly. Initially, it worked when I had only one menuitem but later, after adding sub-menus and an action menu it started throwing an exception error . That’s why I included the data tag to ensure everything loads properly


<menuitem
id="estate_menu_root"
name="Real Estate" />

<menuitem
id="estate_menu_advertisements"
name="Advertisements"
parent="estate_menu_root"
sequence="5" />

<menuitem
id="estate_menu_properties"
name="Properties"
parent="estate_menu_advertisements"
action="estate_property_action" />

<menuitem
id="estate_property_menu_settings"
name="Settings"
parent="estate_menu_root" />

<menuitem
id="estate_property_menu_types"
name="Property Types"
parent="estate_property_menu_settings"
action="estate_property_type_action"
sequence="50"/>

<menuitem
id="estate_property_menu_tags"
name="Property Tags"
action="estate_property_tag_action"
parent="estate_property_menu_settings"
sequence="50"/>


</data>
</odoo>
32 changes: 32 additions & 0 deletions estate/views/estate_property_offer_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="estate_property_offer_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>
<field name="property_id"/>
<field name="price"/>
<field name="partner_id"/>
<field name="status"/>
</list>
</field>
</record>

<record id="estate_property_offer_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="property_id"/>
<field name="price"/>
<field name="partner_id"/>
<field name="status"/>
</group>
</sheet>
</form>
</field>
</record>
</odoo>
33 changes: 33 additions & 0 deletions estate/views/estate_property_tag_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<record id="estate_property_tag_view_list" model="ir.ui.view">
<field name="name">estate.property.tag.view.list</field>
<field name="model">estate.property.tag</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
</list>
</field>
</record>

<record id="estate_property_tag_view_form" model="ir.ui.view">
<field name="name">estate.property.tag.view.form</field>
<field name="model">estate.property.tag</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="name" string="Name"/>
</group>
</sheet>
</form>
</field>
</record>

<record id="estate_property_tag_action" model="ir.actions.act_window">
<field name="name">Property Tags</field>
<field name="res_model">estate.property.tag</field>
<field name="view_mode">list,form</field>

</record>
</odoo>
32 changes: 32 additions & 0 deletions estate/views/estate_property_type_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<record id="estate_property_type_view_list" model="ir.ui.view">
<field name="name">estate.property.type.view.list</field>
<field name="model">estate.property.type</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
</list>
</field>
</record>

<record id="estate_property_type_view_form" model="ir.ui.view">
<field name="name">estate.property.type.view.form</field>
<field name="model">estate.property.type</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="name" placeholder="Estate Property Type"/>
</group>
</sheet>
</form>
</field>
</record>

<record id="estate_property_type_action" model="ir.actions.act_window">
<field name="name"> Property Types </field>
<field name="res_model">estate.property.type</field>
<field name="view_mode">list,form</field>
</record>
</odoo>
Loading