Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
956e40e
[ADD] estate: Initialize the real estate busniess
Piyush11204 Jul 2, 2026
8718baf
[ADD] estate: add estate property model
Piyush11204 Jul 2, 2026
bb27eb2
[LINT] estate: ensure consistent coding style
Piyush11204 Jul 3, 2026
157ce4b
[LINT] estate: resolve remaining lint errors
Piyush11204 Jul 3, 2026
c218672
[ADD] estate: add access control for property model
Piyush11204 Jul 3, 2026
dce4853
[LINT] estate: resolve security file issues
Piyush11204 Jul 3, 2026
648424f
[LINT] estate: fix spacing inconsistencies
Piyush11204 Jul 3, 2026
bf65082
[ADD] estate: add property views and menus
Piyush11204 Jul 6, 2026
ac5be22
[FIX] estate: correct property default values
Piyush11204 Jul 6, 2026
69fc96a
[IMP] estate: improve property form and search
Piyush11204 Jul 7, 2026
ec93d3a
[IMP] estate: filter expensive properties
Piyush11204 Jul 7, 2026
afdd419
[ADD] estate: add property types and tags
Piyush11204 Jul 9, 2026
d5bc7b6
[LINT] estate: resolve Runbot lint errors
Piyush11204 Jul 9, 2026
31cbc6a
[ADD] estate: add property offer model
Piyush11204 Jul 10, 2026
1bd0e1c
[FIX] estate: prevent changing offer property
Piyush11204 Jul 13, 2026
53b1939
[REF] estate: clean up whitespace and formatting
Piyush11204 Jul 20, 2026
781a2c8
[IMP] estate: complete property offer setup
Piyush11204 Jul 24, 2026
b0df03f
[LINT] estate: document invisible property field
Piyush11204 Jul 24, 2026
c42e855
[LINT] estate: removed the invisible property field
Piyush11204 Jul 24, 2026
1c376a8
[ADD] estate: automate total area calculation
Piyush11204 Jul 28, 2026
5705b98
[LINT] estate: fix computed field style
Piyush11204 Jul 28, 2026
7a544ec
[IMP] estate: display highest offer on properties
Piyush11204 Jul 30, 2026
d7cc3ed
[IMP] estate: compute offer deadline from validity
Piyush11204 Jul 31, 2026
a2e8f28
[IMP] estate: add deadline computation for property offers
Piyush11204 Aug 3, 2026
d247bd0
[IMP] estate: automate property and offer fields
Piyush11204 Aug 5, 2026
de62760
[REF] estate: reuse base date calculation for offer deadlines
Piyush11204 Aug 5, 2026
5ac9b7d
[CLN] estate: remove temporary list ordering
Piyush11204 Aug 6, 2026
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
22 changes: 22 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "Real Estate",
"version": "1.0",
"summary": "Real Estate Management",
"description": """
Real Estate Tutorial Module
""",
"author": "Piyush",
"category": "Tutorials",
"depends": ["base"],
"license": "LGPL-3",
"data": [
"security/ir.model.access.csv",
"views/estate_property_views.xml",
"views/estate_property_type_views.xml",
"views/estate_property_tag_view.xml",
"views/estate_property_offer_view.xml",
"views/estate_menus.xml",
],
"application": True,
"installable": True,
}
4 changes: 4 additions & 0 deletions estate/models/__init__.py
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
79 changes: 79 additions & 0 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from odoo import api, fields, models


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

name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
date_availability = fields.Date(
copy=False, default=lambda self: fields.Date.add(fields.Date.today(), months=3)
)
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(
selection=[
("north", "North"),
("south", "South"),
("east", "East"),
("west", "West"),
],
string="Garden Orientation",
)
active = fields.Boolean(default=True)
state = fields.Selection(
selection=[
("new", "New"),
("offer_received", "Offer Received"),
("offer_accepted", "Offer Accepted"),
("sold", "Sold"),
("canceled", "Canceled"),
],
copy=False,
default="new",
required=True,
)
property_type_id = fields.Many2one("estate.property.type", string="Type")
seller_id = fields.Many2one(
"res.users",
string="Sales Person",
default=lambda self: self.env.user,
)
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
tag_ids = fields.Many2many("estate.property.tag", string="Tags")
offer_ids = fields.One2many(
"estate.property.offer",
"property_id",
string="Offers",
)
total_area = fields.Integer(compute="_compute_total_area", string="Total Area")

@api.depends("living_area", "garden_area")
def _compute_total_area(self):
for record in self:
record.total_area = record.living_area + record.garden_area

best_price = fields.Float(compute="_compute_best_price", string="Best Offer")

@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):
for record in self:
if record.garden:
record.garden_area = 10
record.garden_orientation = "north"
else:
record.garden_area = False
record.garden_orientation = False
40 changes: 40 additions & 0 deletions estate/models/estate_property_offer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from odoo import api, fields, models


class EstatePropertyOffer(models.Model):
_name = "estate.property.offer"
_description = "its for the offers that we recive in the estate"

price = fields.Float()
status = fields.Selection(
selection=[
("accepted", "Accepted"),
("refused", "Refused"),
],
copy=False,
)
partner_id = fields.Many2one("res.partner", required=True)
property_id = fields.Many2one("estate.property", required=True, readonly=True)
validity = fields.Integer(default=7)

date_deadline = fields.Date(
compute="_compute_date_deadline",
inverse="_inverse_date_deadline",
)

def _get_base_date(self):
self.ensure_one()
return self.create_date.date() if self.create_date else fields.Date.today()

@api.depends("create_date", "validity")
def _compute_date_deadline(self):
for offer in self:
offer.date_deadline = fields.Date.add(
offer._get_base_date(),
days=offer.validity,
)

def _inverse_date_deadline(self):
for offer in self:
if offer.date_deadline:
offer.validity = (offer.date_deadline - offer._get_base_date()).days
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 EstatePropertyTags(models.Model):
_name = "estate.property.tag"
_description = "This model will have tags"

name = fields.Char(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 = "It stores the property types"

name = fields.Char(required=True)
5 changes: 5 additions & 0 deletions estate/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +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
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
12 changes: 12 additions & 0 deletions estate/views/estate_menus.xml
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">
<menuitem id="estate_advertisements_menu" name="Advertisements">
<menuitem id="estate_property_menu_action" action="estate_property_action"/>
</menuitem>
<menuitem id="estate_settings_menu" name="Settings">
<menuitem id="estate_property_type_menu_action" name="Property Types" action="estate_property_type_action"/>
<menuitem id="estate_property_tag_menu_action" name="Property Tags" action="estate_property_tag_action"/>
</menuitem>
</menuitem>
</odoo>
38 changes: 38 additions & 0 deletions estate/views/estate_property_offer_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="estate_property_offer_action" model="ir.actions.act_window">
<field name="name">Estate Property Offers</field>
<field name="res_model">estate.property.offer</field>
<field name="view_mode">tree,form</field>
</record>
<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="price"/>
<field name="partner_id"/>
<field name="status"/>
<field name="validity"/>
<field name="date_deadline"/>
</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="price"/>
<field name="partner_id"/>
<field name="status"/>
<field name="validity"/>
<field name="date_deadline"/>
</group>
</sheet>
</form>
</field>
</record>
</odoo>
8 changes: 8 additions & 0 deletions estate/views/estate_property_tag_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<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>
8 changes: 8 additions & 0 deletions estate/views/estate_property_type_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<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>
98 changes: 98 additions & 0 deletions estate/views/estate_property_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<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>
<record id="estate_property_view_list" 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="expected_price"/>
<field name="selling_price"/>
<field name="bedrooms"/>
<field name="living_area"/>
<field name="postcode"/>
<field name="state"/>
</list>
</field>
</record>
<record id="estate_property_view_form" model="ir.ui.view">
<field name="name">estate.property.view.form</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name"/>
<field name="expected_price"/>
<field name="bedrooms"/>
<field name="property_type_id" />
<field name="living_area"/>
<field name="facades"/>
<field name="best_price" readonly="1"/>
<!-- <field name="total_area" readonly="1"/> -->
<field name="total_area"/>
</group>
<group>
<field name="selling_price"/>
<field name="postcode"/>
<field name="tag_ids" widget="many2many_tags"/>
<field name="date_availability"/>
<field name="garden"/>
<field name="garden_area"/>
<field name="garden_orientation"/>
</group>
</group>
<notebook>
<page string="Description">
<group>
<field name="description"/>
</group>
</page>
<page string="Other Info">
<group >
<group>
<field name="seller_id"/>
<field name="buyer_id"/>
</group>
</group>
</page>
<page name="Offers" string="Offers">
<group >
<group>
<field name="offer_ids"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>

<record id="estate_property_view_search" model="ir.ui.view">
<field name="name">estate.property.view.search</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<search string="Properties">
<field name="name"/>
<field name="postcode"/>
<field name="expected_price"/>
<field name="bedrooms"/>
<field name="living_area"/>
<field name="facades"/>
<filter name="available" string="Available" domain="[('state', 'in', ['new', 'offer_received'])]" />
<filter name="expensive" string="Expensive" domain="[('expected_price', '>', 50000)]" />
<group >
<filter name="group_by_postcode" string="Postcode" context="{'group_by': 'postcode'}" />
<filter name="group_by_bedroom" string="Bedrooms" context="{'group_by': 'bedrooms'}" />
</group>
</search>
</field>
</record>
</odoo>