Skip to content
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

[ADD] estate: adding a new real estate module #317

Draft
wants to merge 8 commits into
base: 18.0
Choose a base branch
from

Conversation

ptpu-odoo
Copy link

Added real estate module for tutorial purpose

…new addon named estate_property, included 2 files namely __init__.py and __manifest__.py. Also created table with name estate_property with some fields in it.
Add access file 'ir.model.access.csv' with read, write, create and unlink permissions to the group base.group_user set to 1. Also imported the same file in manifest file in data field.
… - 5)

Added menu xml files and created a UI which shows list and form views from where one can create, update and delete data from database. Made selling prices in read only mode and added 3 months from today's date in avalability date section.
…(chap - 6)

Add and modified list view. Costomised form view. Added search options to be searched with multiple fields. Added multiple filter like availibility using current date and state selected. Also added group by option on similar postcode data.
Added relations between models with estate_property model.

Many2one relation - estate_property_type
Many2Many relation - estate_property_tag
One2Many relation - estate_propery_offer
@robodoo
Copy link

robodoo commented Feb 5, 2025

Pull request status dashboard

Copy link

@rare-odoo rare-odoo left a comment

Choose a reason for hiding this comment

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

Hello @ptpu-odoo 👋,

Great work so far!

This is the first set of the review.
Please make sure to add a new line at the end of every file.

@@ -0,0 +1 @@
from . import models

Choose a reason for hiding this comment

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

Please remove the unnecessary lines and ensure there is only one empty line per file.

@@ -0,0 +1,68 @@
from odoo import api,fields, models
# import for adding months with relativedelta

Choose a reason for hiding this comment

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

Please remove the commented-out code.

Comment on lines 7 to 24

#function calculting total area by adding living area and garden 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 calculation
@api.depends('offer_ids.price')
def _computer_best_price(self):
for record in self:
if record.offer_ids:
record.best_price = max(record.offer_ids.mapped('price'))
else:
record.best_price = 0.0

_name = "estate.property"
_description = "Estate property tables"

Choose a reason for hiding this comment

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

Suggested change
#function calculting total area by adding living area and garden 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 calculation
@api.depends('offer_ids.price')
def _computer_best_price(self):
for record in self:
if record.offer_ids:
record.best_price = max(record.offer_ids.mapped('price'))
else:
record.best_price = 0.0
_name = "estate.property"
_description = "Estate property tables"
_name = "estate.property"
_description = "Estate property tables"
#function calculting total area by adding living area and garden 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 calculation
@api.depends('offer_ids.price')
def _computer_best_price(self):
for record in self:
if record.offer_ids:
record.best_price = max(record.offer_ids.mapped('price'))
else:
record.best_price = 0.0

The model class declaration should be followed by the name and description.
Additionally, the description should clearly explain the purpose of adding the model.

_name = "estate.property"
_description = "Estate property tables"

name = fields.Char(string="Title",required=True)

Choose a reason for hiding this comment

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

Could you please explain the purpose of the required parameter in this context?
Also, what would happen if it is not used?

Copy link
Author

Choose a reason for hiding this comment

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

The required parameter is applied to the name field to ensure that the user provides a value. If the field is left empty, the form cannot be saved in the database.

name = fields.Char(string="Title",required=True)
description = fields.Text(string="Description")
postcode = fields.Char(string="Postcode")
date_availability = fields.Date(string="Available From",copy=False, default=(fields.Date.today()+relativedelta(months=+3))) #Added 3 months

Choose a reason for hiding this comment

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

Suggested change
date_availability = fields.Date(string="Available From",copy=False, default=(fields.Date.today()+relativedelta(months=+3))) #Added 3 months
date_availability = fields.Date(string="Available From", copy=False, default=(fields.Date.today() + relativedelta(months=+3))) #Added 3 months

Please ensure the entire module follows coding guidelines by adding spaces wherever necessary.
Also, could you explain the purpose of default and copy parameter in this context?

Copy link
Author

Choose a reason for hiding this comment

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

The default parameter is used to assign default values to the field, which the user can modify if desired.

The copy parameter is configured to determine whether the field should be copied when duplicating the item.

required=True,
default="new",
copy=False,
selection=[('new', 'New'), ('offer_received', 'Offer Received'), ('offer_accepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')],

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_received', 'Offer Received'), ('offer_accepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')],
selection=[
('new', 'New'),
('offer_received', 'Offer Received'),
('offer_accepted', 'Offer Accepted'),
('sold', 'Sold'),
('cancelled', 'Cancelled')],

Comment on lines 5 to 6


Choose a reason for hiding this comment

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

Please remove the unnecessary lines

Comment on lines 2 to 5
estate.access_estate_property,estate.access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1
estate.access_estate_property_type,estate.access_estate_property_type,estate.model_estate_property_type,base.group_user,1,1,1,1
estate.access_estate_property_tag,estate.access_estate_property_tag,estate.model_estate_property_tag,base.group_user,1,1,1,1
estate.access_estate_property_offer,estate.access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,1,1,1

Choose a reason for hiding this comment

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

Could you please explain why there's a 1,1,1,1 at the end?

Copy link
Author

Choose a reason for hiding this comment

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

"1,1,1,1" at the end represents the permissions assigned to the user for reading, writing, creating, and deleting (unlinking) items.

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

Choose a reason for hiding this comment

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

What is the purpose of adding view_mode here?

Copy link
Author

Choose a reason for hiding this comment

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

The "view_mode" parameter specifies the views to be displayed for the model. In this case, it includes both the list and form views, through which the model will be presented to the user.

<h1 class="mb32">
<field name="name" class="mb16" />
</h1>
<field name="tag" widget="many2many_tags"/>

Choose a reason for hiding this comment

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

What is the purpose of adding widget="many2many_tags" here?

Copy link
Author

Choose a reason for hiding this comment

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

The widget="many2many_tags" is used to display the user interface in a way that allows users to select multiple tags from a dropdown, which are then displayed as tab-style pills.

Comment on lines 102 to 96
<filter string="Available" name="date_availability" domain="[('date_availability', '>=', context_today())]"/>
<!-- Filter on checking the availability and if the selected state is new or offer_recievied -->
<filter string="New or Offer Recieved" name="state" domain="[('date_availability', '>=', context_today()), '|', ('state', '=', 'new'),('state', '=', 'offer_received')]"/>

Choose a reason for hiding this comment

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

Could you please explain, What is the purpose of adding domain attribute here?

Copy link
Author

Choose a reason for hiding this comment

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

The "domain" attribute is used to define the conditions for filters, specifying the criteria on which the filter should apply to the search.

<filter string="New or Offer Recieved" name="state" domain="[('date_availability', '>=', context_today()), '|', ('state', '=', 'new'),('state', '=', 'offer_received')]"/>
<!-- Group by on similar postcode and making visible the remaining (no value in postcode field) -->
<group expand="1" string="Group By">
<filter string="Postcode" name="postcode" context="{'group_by':'postcode', 'residual_visible':True}"/>

Choose a reason for hiding this comment

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

Could you please explain, What is the purpose of adding context attribute here?
Also, what does the group_by, residual_visible do?

Copy link
Author

Choose a reason for hiding this comment

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

The "context" attribute is used with filters intended to function as group-by filters. It allows us to define the parameter by which the grouping should occur and determine whether the residual values should be visible.

The "group_by" option specifies the parameter on which the grouping function will be applied, while the "residual_visible" option controls the visibility of records that do not have a value in the specified parameter field (in this case, the postcode field).

@ptpu-odoo ptpu-odoo force-pushed the 18.0-tutorials-ptpu branch from dadb606 to 5a7a42c Compare February 6, 2025 05:03
Implemented compute and inverse function  using @api decorater.
'depends' and 'onchange' decorater is implements here.

Using 'depends' decorater, deadline date is calculated using the validity field
and also inverse function of it is created.
Using 'onchange' decorater, 'garden_area' and 'garden_orientation' is set on
selecting the garden field, and it is set to default on unselecting the garden
field.
@ptpu-odoo ptpu-odoo force-pushed the 18.0-tutorials-ptpu branch from 5a7a42c to 67e11e0 Compare February 6, 2025 05:10
Implemented Sold and Cancel buttons in the header, with functionality to
update the status based on the current status of the record.

Introduced icon buttons to accept or decline an offer. Upon acceptance, the
selling price and buyer's name are automatically updated based on the accepted
offer. Additionally, ensured that only one offer can be accepted at a time.
Added constraints for:
The property expected price must be strictly positive.
The property selling price must be positive.
The offer price must be strictly positive.
The property tag name and property type name must be unique.
Additionally, a constraint has been implemented to ensure that the selling price
is not lower than 90% of the expected price.
@ptpu-odoo ptpu-odoo force-pushed the 18.0-tutorials-ptpu branch from 69f871b to 5451c5e Compare February 6, 2025 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants