-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IMP] estate: wizard,controllers,security
*Add 'Properties' menu to list available properties with images and pagination on website using of controller. - Created a 'Properties' menu on the website to display available properties in a grid. - Added image support for properties and displayed them on the front end. - Implemented pagination to display a maximum of 6 properties per page. - Created a dedicated, responsive property detail page using Bootstrap. *Add 'Add Offer' wizard to Real Estate module for bulk offer creation - Added 'Add Offer' button to the estate property tree view header. - Implemented wizard for selecting multiple properties to make an offer. - Wizard includes fields for price, validity, and buyer details. - Added 'Make an Offer' and 'Cancel' buttons to handle business logic and cancellation. *Implement security restrictions for Real Estate module - Created security.xml file to define security groups and access rights. - Added Real Estate Agent and Manager groups with appropriate access levels. - Set access rights: full access for Managers, limited access for Agents, and r estricted access for non-agents. - Defined record rules to restrict access to properties based on the agent assigned. - Implemented bypass for invoice creation security checks in estate_account module using `sudo()`. - Added company-based record rules for multi-company security management. - Restricted Settings menu visibility to Managers only.
- Loading branch information
Showing
16 changed files
with
313 additions
and
12 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
@@ -1 +1,3 @@ | ||
from . import models | ||
from . import controller | ||
from . import wizard |
This file contains 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
This file contains 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 estate_property_controller |
This file contains 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,50 @@ | ||
from odoo import http | ||
from odoo.http import request | ||
|
||
|
||
class EstatePropertyController(http.Controller): | ||
|
||
@http.route(["/properties"], type="http", auth="public", website=True) | ||
def properties_list(self, page=1, **kwargs): | ||
try: | ||
page = int(page) | ||
except ValueError: | ||
page = 1 | ||
Property = request.env["estate.property"].sudo() | ||
properties_per_page = 6 | ||
|
||
total_properties = Property.search_count( | ||
[ | ||
("state", "in", ["offer received", "offer accepted"]), | ||
] | ||
) | ||
total_pages = ( | ||
total_properties + properties_per_page - 1 | ||
) // properties_per_page | ||
page = max(1, min(page, total_pages)) | ||
offset = (page - 1) * properties_per_page | ||
properties = Property.search( | ||
[ | ||
("state", "in", ["offer received", "offer accepted"]), | ||
], | ||
limit=properties_per_page, | ||
offset=offset, | ||
) | ||
return request.render( | ||
"estate.property_template", | ||
{ | ||
"properties": properties, | ||
"page": page, | ||
"total_pages": total_pages, | ||
}, | ||
) | ||
|
||
@http.route("/properties/<int:record_id>", type="http", auth="public", website=True) | ||
def get_record(self, record_id, **kwargs): | ||
record = request.env["estate.property"].sudo().browse(record_id) | ||
if not record.exists(): | ||
return request.not_found() | ||
return request.render( | ||
"estate.property_view_details", | ||
{"record": record}, | ||
) |
Empty file.
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -1,5 +1,14 @@ | ||
"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 | ||
estate.access_real_estate_property_type,access_real_estate_property_type,estate.model_real_estate_property_type,base.group_user,1,1,1,1 | ||
estate.access_real_estate_property_tag,access_real_estate_property_tag,estate.model_real_estate_property_tag,base.group_user,1,1,1,1 | ||
estate.access_estate_property_offer,access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,1,1,1 | ||
access_estate_property,access_estate_property,model_estate_property,base.group_user,1,0,0,0 | ||
estate.access_estate_property_type,access_estate_property_type,estate.model_real_estate_property_type,base.group_user,1,0,0,0 | ||
estate.access_estate_property_tag,access_estate_property_tag,estate.model_real_estate_property_tag,base.group_user,1,0,0,0 | ||
estate.access_estate_property_offer,access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,0,0,0 | ||
estate.access_add_offer,access_add_offer,estate.model_property_offer_wizard,base.group_user,1,0,0,0 | ||
access_estate_property_group_user,access_estate_property_group_user,model_estate_property,estate.estate_group_user,1,1,1,0 | ||
estate.access_estate_property_type_group_user,access_estate_property_type_group_user,estate.model_real_estate_property_type,estate.estate_group_user,1,0,0,0 | ||
estate.access_estate_property_tag_group_user,access_estate_property_tag_group_user,estate.model_real_estate_property_tag,estate.estate_group_user,1,0,0,0 | ||
access_estate_property_manager,access_estate_property_manager,model_estate_property,estate.estate_group_manager,1,1,1,0 | ||
estate.access_estate_property_type_manager,access_estate_property_type_manager,estate.model_real_estate_property_type,estate.estate_group_manager,1,1,1,1 | ||
estate.access_estate_property_tag_manager,access_estate_property_tag_manager,estate.model_real_estate_property_tag,estate.estate_group_manager,1,1,1,1 | ||
estate.access_estate_property_offer_manager,access_estate_property_offer_manager,estate.model_estate_property_offer,estate.estate_group_manager,1,1,1,1 | ||
estate.access_add_offer_manager,access_add_offer_manager,estate.model_property_offer_wizard,estate.estate_group_manager,1,1,1,1 |
This file contains 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,32 @@ | ||
<odoo> | ||
<record id="estate_group_user" model="res.groups"> | ||
<field name="name">Agent</field> | ||
<field name="category_id" ref="base.module_category_real_estate_brokerage"/> | ||
</record> | ||
<record id="estate_group_manager" model="res.groups"> | ||
<field name="name">Manager</field> | ||
<field name="category_id" ref="base.module_category_real_estate_brokerage"/> | ||
<field name="implied_ids" eval="[(4, ref('estate_group_user'))]"/> | ||
</record> | ||
<record id="rule_estate_group_user" model="ir.rule"> | ||
<field ref="model_estate_property" name="model_id"/> | ||
<field name="name">Agent permissions</field> | ||
<field name="perm_unlink" eval="False"/> | ||
<field name="groups" eval="[Command.link(ref('estate.estate_group_user'))]"/> | ||
<field name="domain_force">['|', ('salesman_id', '=', user.id), ('salesman_id', '=', False)]</field> | ||
</record> | ||
|
||
<record id="rule_estate_group_manager" model="ir.rule"> | ||
<field ref="model_estate_property" name="model_id"/> | ||
<field name="name">Manager permissions</field> | ||
<field name="perm_unlink" eval="False"/> | ||
<field name="groups" eval="[Command.link(ref('estate.estate_group_manager'))]"/> | ||
</record> | ||
|
||
<record model="ir.rule" id="estate_property_rule_estate_group_user"> | ||
<field name="name">multi-company security</field> | ||
<field name="model_id" ref="model_estate_property"/> | ||
<field name="global" eval="True"/> | ||
<field name="domain_force">['|',('company_id', '=', False),('company_id', 'in', company_ids)]</field> | ||
</record> | ||
</odoo> |
This file contains 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,137 @@ | ||
<odoo> | ||
<template id="property_template" name="Property List"> | ||
<t t-call="website.layout"> | ||
<div class="container my-5"> | ||
<h1 class="text-center mb-4">Available Properties</h1> | ||
<div class="row"> | ||
<t t-foreach="properties" t-as="property"> | ||
<div class="col-lg-4 col-md-6 mb-4 d-flex align-items-stretch"> | ||
<div class="card shadow-sm h-100"> | ||
<img t-if="property.property_image" t-att-src="image_data_uri(property.property_image)" class="card-img-top" alt="Property Image" style="height: 300px; width: 400px; object-fit: cover;"/> | ||
<div class="card-body d-flex flex-column"> | ||
<h5 class="card-title"> | ||
<t t-esc="property.name"/> | ||
</h5> | ||
<div class="mt-auto"> | ||
<a t-att-href="'/properties/%s' % property.id" class="btn btn-primary btn-block">View Details</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</t> | ||
</div> | ||
<nav aria-label="Page navigation"> | ||
<ul class="pagination justify-content-center"> | ||
<li class="page-item" t-att-class="page == 1 and 'disabled'"> | ||
<a t-att-href="'/properties?page=%d' % (page - 1)" class="page-link" aria-label="Previous"> | ||
<span aria-hidden="true">«</span> | ||
</a> | ||
</li> | ||
<t t-foreach="range(1, total_pages + 1)" t-as="p"> | ||
<li class="page-item" t-att-class="p == page and 'active'"> | ||
<a t-att-href="'/properties?page=%d' % p" class="page-link"> | ||
<t t-esc="p"/> | ||
</a> | ||
</li> | ||
</t> | ||
<li class="page-item" t-att-class="page == total_pages and 'disabled'"> | ||
<a t-att-href="'/properties?page=%d' % (page + 1)" class="page-link" aria-label="Next"> | ||
<span aria-hidden="true">»</span> | ||
</a> | ||
</li> | ||
</ul> | ||
</nav> | ||
</div> | ||
</t> | ||
</template> | ||
|
||
|
||
|
||
|
||
<template id="property_view_details" name="View Property"> | ||
<t t-call="website.layout"> | ||
<div class="container mt-5"> | ||
<div class="row justify-content-center"> | ||
<div class="col-md-10"> | ||
<div class="card shadow-lg"> | ||
<div class="row g-0"> | ||
<div class="col-md-7"> | ||
<img t-if="record.property_image" t-att-src="image_data_uri(record.property_image)" class="img-fluid h-100 w-100 rounded-start" alt="Property image"/> | ||
</div> | ||
<div class="col-md-5"> | ||
<div class="card-body"> | ||
<h3 class="card-title"> | ||
<t t-esc="record.name"/> | ||
</h3> | ||
<hr/> | ||
<p class="card-text"> | ||
<strong>State:</strong> | ||
<t t-esc="record.state"/> | ||
</p> | ||
<p class="card-text"> | ||
<strong>Expected Price:</strong> | ||
<t t-esc="record.expected_price" /> | ||
</p> | ||
<p class="card-text"> | ||
<strong>Selling Price:</strong> | ||
<t t-esc="record.selling_price" /> | ||
</p> | ||
<hr/> | ||
<p class="card-text"> | ||
<small class="text-muted"> | ||
<div> | ||
<strong>Type:</strong> | ||
<t t-esc="record.property_type_id.name"/> | ||
</div> | ||
<div> | ||
<strong>Salesman:</strong> | ||
<t t-esc="record.salesman_id.name"/> | ||
</div> | ||
<div> | ||
<strong>Postcode:</strong> | ||
<t t-esc="record.postcode"/> | ||
</div> | ||
<div> | ||
<strong>Available From:</strong> | ||
<t t-esc="record.date_availability"/> | ||
</div> | ||
<div> | ||
<strong>Bedrooms:</strong> | ||
<t t-esc="record.bedrooms"/> | ||
</div> | ||
<div> | ||
<strong>Living Area (sqm):</strong> | ||
<t t-esc="record.living_area"/> | ||
</div> | ||
<div> | ||
<strong>Facades:</strong> | ||
<t t-esc="record.facades"/> | ||
</div> | ||
<div> | ||
<strong>Garage:</strong> | ||
<t t-esc="record.garage" t-if="record.garage"/> | ||
<t t-if="not record.garage">No</t> | ||
</div> | ||
<div> | ||
<strong>Garden:</strong> | ||
<t t-esc="record.garden" t-if="record.garden"/> | ||
<t t-if="not record.garden">No</t> | ||
</div> | ||
<div> | ||
<strong>Description:</strong> | ||
<t t-esc="record.description" t-if="record.garden"/> | ||
</div> | ||
</small> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</t> | ||
</template> | ||
|
||
|
||
</odoo> |
This file contains 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
This file contains 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
This file contains 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 estate_property_offer |
This file contains 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,24 @@ | ||
from odoo import fields, models | ||
|
||
|
||
class AddOffer(models.TransientModel): | ||
_name = "property.offer.wizard" | ||
_description = "Add offer" | ||
_order = "price desc" | ||
|
||
price = fields.Float(string="Price", required=True) | ||
partner_id = fields.Many2one("res.partner", string="Partner", required=True) | ||
validity = fields.Integer(string="Validity (days)", default=7) | ||
|
||
def action_make_offer(self): | ||
context = self.env.context | ||
active_ids = context.get("active_ids", []) | ||
for property_id in active_ids: | ||
self.env["estate.property.offer"].create( | ||
{ | ||
"price": self.price, | ||
"validity": self.validity, | ||
"partner_id": self.partner_id.id, | ||
"property_id": property_id, | ||
} | ||
) |
This file contains 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 @@ | ||
<odoo> | ||
<record id="property_offer_wizard_form" model="ir.ui.view"> | ||
<field name="name">estate.property.offer.form.wizard</field> | ||
<field name="model">property.offer.wizard</field> | ||
<field name="arch" type="xml"> | ||
<form> | ||
<sheet> | ||
<group> | ||
<field name="price" /> | ||
<field name="partner_id" /> | ||
<field name="validity" /> | ||
</group> | ||
</sheet> | ||
<footer> | ||
<button name="action_make_offer" type="object" string="Make an Offer" class="btn-primary"/> | ||
<button special="cancel" string="Cancel" class="btn-secondary"/> | ||
</footer> | ||
</form> | ||
</field> | ||
</record> | ||
|
||
<record id="action_add_offer_wizard" model="ir.actions.act_window"> | ||
<field name="name">Offer</field> | ||
<field name="res_model">property.offer.wizard</field> | ||
<field name="view_mode">form</field> | ||
<field name="view_id" ref="property_offer_wizard_form"/> | ||
<field name="target">new</field> | ||
</record> | ||
</odoo> |
Oops, something went wrong.