-
Notifications
You must be signed in to change notification settings - Fork 2.3k
<
8000
div class="d-flex flex-column flex-md-row flex-items-start flex-md-items-center">
[ADD] estate: initial Real Estate module with models, views, and rela… #757
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
Draft
raaa-odoo
wants to merge
15
commits into
odoo:18.0
Choose a base branch
from
odoo-dev:18.0-training-raaa
base: 18.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1b57e98
[ADD] estate: initial Real Estate module with models, views, and rela…
raaa-odoo e65a6c3
[ADD] estate: constraints, compute fields, and offer logic enhancements
raaa-odoo d265965
[IMP] estate: implement business logic for offers, constraints, state…
raaa-odoo 734a361
[IMP] estate: apply styling improvements to code
raaa-odoo 35f9b50
[IMP] estate: Again apply styling improvements to code
raaa-odoo d52e2a3
[IMP] estate: add chatter, demo data, access rules, and PDF report
raaa-odoo f2062aa
[IMP] estate: add website controller, offer wizard & tests
raaa-odoo c431e83
[IMP] estate: add website controller, offer wizard & tests
raaa-odoo 6f6bcb8
[IMP] estate, awesome_owl: update estate tests and complete OWL exerc…
raaa-odoo 1cbf9c3
[IMP] estate: update the test cases logic
raaa-odoo 4c06dbd
[IMP] awesome_dashboard: make dashboard items dynamic and reusable
raaa-odoo 8b6372c
[ADD] rental,sale: implement mandatory rental deposit system
raaa-odoo 0f69fe9
[IMP] estate: implement business logic for offers, constraints, state…
raaa-odoo a656668
[IMP] rental_deposit: Fix the the error.
raaa-odoo bc2e9aa
[IMP] rental_deposit: Fix the the error.
raaa-odoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
[IMP] estate: add website controller, offer wizard & tests
This commit includes three major enhancements to the estate module: 1. Website Controller: - Added a new website controller to render a list of available properties on the frontend (`/properties`). - Implemented optional filtering by min and max price using query parameters. 2. Add Offer Wizard: - Introduced a wizard to allow adding offers to multiple properties in bulk. - Activated via a new Add Offer button on the estate property list view. 3. Test Cases: - Added unit tests to ensure the correctness of the code and logic. These improvements significantly enhance usability for both website visitors and internal users, especially salespeople handling bulk property offers.
- Loading branch information
commit f2062aa5cdcff3d88bcd3dc6a66176312c9e7d7a
There are no files selected for viewing
This file contains hidden or 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 controllers | ||
from . import wizard |
This file contains hidden or 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 hidden or 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 main |
This file contains hidden or 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,39 @@ | ||
from odoo import http | ||
from odoo.http import request | ||
|
||
class EstateWebsiteController(http.Controller): | ||
|
||
@http.route('/properties', type='http', auth='public', website=True) | ||
def list_properties(self, min_price=0, max_price=0, **kwargs): | ||
domain = [] | ||
try: | ||
min_price = float(min_price) | ||
except (ValueError, TypeError): | ||
min_price = 0 | ||
try: | ||
max_price = float(max_price) | ||
except (ValueError, TypeError): | ||
max_price = 0 | ||
|
||
if min_price: | ||
domain.append(('selling_price', '>=', min_price)) | ||
if max_price: | ||
domain.append(('selling_price', '<=', max_price)) | ||
|
||
properties = request.env['estate.property'].sudo().search(domain) | ||
|
||
return request.render('estate.property_listing', { | ||
'properties': properties, | ||
'min_price': min_price, | ||
'max_price': max_price, | ||
}) | ||
|
||
@http.route('/properties/<int:property_id>', type='http', auth='public', website=True) | ||
def property_detail(self, property_id, **kwargs): | ||
property_rec = request.env['estate.property'].sudo().browse(property_id) | ||
if not property_rec.exists(): | ||
return request.not_found() | ||
|
||
return request.render('estate.property_detail', { | ||
'property': property_rec | ||
}) |
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 test_estate_property |
This file contains hidden or 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,99 @@ | ||
from odoo import Command | ||
from odoo.exceptions import UserError | ||
from odoo.tests import tagged, Form | ||
from odoo.tests.common import TransactionCase | ||
|
||
|
||
@tagged("post_install", "-at_install") | ||
class EstateTestCase(TransactionCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
|
||
cls.properties = cls.env["estate.property"].create( | ||
[ | ||
{ | ||
"name": "Sale Test Property", | ||
"description": "Test Description", | ||
"expected_price": 100000, | ||
"living_area": 50, | ||
}, | ||
{ | ||
"name": "Garden Test Property", | ||
"description": "Test Description Garden", | ||
"expected_price": 200000, | ||
"living_area": 100, | ||
}, | ||
] | ||
) | ||
|
||
cls.offers = cls.env["estate.property.offer"].create( | ||
[ | ||
{ | ||
"partner_id": cls.env.ref("base.res_partner_2").id, | ||
"offer_price": 110000, | ||
"property_id": cls.properties[0].id, | ||
}, | ||
{ | ||
"partner_id": cls.env.ref("base.res_partner_12").id, | ||
"offer_price": 130000, | ||
"property_id": cls.properties[0].id, | ||
}, | ||
{ | ||
"partner_id": cls.env.ref("base.res_partner_2").id, | ||
"offer_price": 150000, | ||
"property_id": cls.properties[0].id, | ||
}, | ||
] | ||
) | ||
|
||
def test_sell_property_without_accepted_offer(self): | ||
""" | ||
Test selling a property without an accepted offer. | ||
Ensure that a UserError is raised when trying to sell a property without an accepted offer. | ||
Ensure that other offers are not allowed to be created after the property is sold. | ||
""" | ||
|
||
with self.assertRaises(UserError): | ||
self.properties[0].action_sold() | ||
|
||
self.offers[1].action_accept() | ||
self.properties[0].action_sold() | ||
|
||
self.assertEqual( | ||
self.properties[0].state, "sold", "Property was not marked as sold" | ||
) | ||
|
||
with self.assertRaises(UserError): | ||
self.properties[0].offer_ids = [ | ||
Command.create( | ||
{ | ||
"partner_id": self.env.ref("base.res_partner_2").id, | ||
"price": 200000, | ||
"property_id": self.properties[0].id, | ||
} | ||
) | ||
] | ||
|
||
def test_garden_toggle(self): | ||
""" | ||
Test toggling the garden field on the property. | ||
Ensure that the garden area and orientation are resetting. | ||
""" | ||
|
||
with Form(self.properties[1]) as form: | ||
form.garden = True | ||
self.assertEqual(form.garden_area, 10, "Garden area should be reset to 10") | ||
self.assertEqual( | ||
form.garden_orientation, | ||
"north", | ||
"Garden orientation should be reset to north", | ||
) | ||
|
||
form.garden = False | ||
self.assertEqual(form.garden_area, 0, "Garden area should be reset to 0") | ||
self.assertEqual( | ||
form.garden_orientation, | ||
False, | ||
"Garden orientation should be reset to False", | ||
) |
This file contains hidden or 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,67 @@ | ||
<odoo> | ||
<template id="property_listing" name="Property Listing"> | ||
<t t-call="website.layout"> | ||
<div class="container mt-4"> | ||
<!-- Search Form --> | ||
<form method="get" class="mb-4"> | ||
<div class="row"> | ||
<div class="col-md-3"> | ||
<input type="text" name="name" class="form-control" | ||
t-att-value="search_name" placeholder="Search by name..."/> | ||
</div> | ||
<div class="col-md-3"> | ||
<input type="number" name="min_price" class="form-control" | ||
t-att-value="min_price" placeholder="Min Price"/> | ||
</div> | ||
<div class="col-md-3"> | ||
<input type="number" name="max_price" class="form-control" | ||
t-att-value="max_price" placeholder="Max Price"/> | ||
</div> | ||
<div class="col-md-3"> | ||
<button type="submit" class="btn btn-primary">Filter</button> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<!-- Property Cards --> | ||
<div class="row"> | ||
<t t-foreach="properties" t-as="property"> | ||
<div class="col-md-4 mb-4"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h5 class="card-title" t-esc="property.name"/> | ||
<p class="card-text"> | ||
Price: <span t-esc="property.expected_price"/> | ||
<br/> | ||
Bedrooms: <span t-esc="property.bedrooms"/> | ||
</p> | ||
<a t-att-href="'/properties/%s' % property.id" | ||
class="btn btn-primary"> | ||
View Details | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</t> | ||
</div> | ||
</div> | ||
</t> | ||
</template> | ||
|
||
<template id="property_detail" name="Property Detail"> | ||
<t t-call="website.layout"> | ||
<div class="container mt-5"> | ||
<div class="card shadow p-4"> | ||
<h1 class="mb-3"><t t-esc="property.name"/></h1> | ||
<p><strong>Price:</strong> <t t-esc="property.selling_price"/></p> | ||
<p><strong>Bedrooms:</strong> <t t-esc="property.bedrooms"/></p> | ||
<p><strong>Living Area:</strong> <t t-esc="property.living_area"/> m²</p> | ||
<p><strong>Garden:</strong> <t t-esc="property.garden and 'Yes' or 'No'"/></p> | ||
<p><strong>Description:</strong> <t t-esc="property.description"/></p> | ||
<a href="/properties" class="btn btn-outline-secondary mt-3">← Back to Listings</a> | ||
</div> | ||
</div> | ||
</t> | ||
</template> | ||
|
||
</odoo> |
This file contains hidden or 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 hidden or 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_wizard |
This file contains hidden or 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,35 @@ | ||
from odoo import api, fields, models | ||
|
||
|
||
class MakeOfferWizard(models.TransientModel): | ||
_name = 'estate.property.offer.wizard' | ||
_description = 'Property Offer Wizard' | ||
|
||
offer_price = fields.Float('Offer Price', required=True) | ||
status = fields.Selection( | ||
[('accepted', 'Accepted'), ('refused', 'Refused')], | ||
string='Status' | ||
) | ||
partner_id = fields.Many2one('res.partner', 'Buyer', required=True) | ||
property_ids = fields.Many2many( | ||
'estate.property', | ||
string='Selected Properties', | ||
) | ||
|
||
@api.model | ||
def default_get(self, fields): | ||
res = super().default_get(fields) | ||
property_ids = self.env.context.get("active_ids", []) | ||
if property_ids: | ||
res["property_ids"] = [(6, 0, property_ids)] | ||
return res | ||
|
||
def action_make_offer(self): | ||
for property in self.property_ids: | ||
self.env['estate.property.offer'].create({ | ||
"offer_price": self.offer_price, | ||
'status': self.status, | ||
'partner_id': self.partner_id.id, | ||
'property_id': property.id, | ||
}) | ||
return {'type': 'ir.actions.act_window_close'} |
This file contains hidden or 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,28 @@ | ||
<odoo> | ||
<record id="action_add_offer_wizard" model="ir.actions.act_window"> | ||
<field name="name">Add Offer</field> | ||
<field name="res_model">estate.property.offer.wizard</field> | ||
<field name="view_mode">form</field> | ||
<field name="target">new</field> | ||
<field name="binding_model_id" ref="model_estate_property"/> | ||
<field name="binding_view_types">list</field> | ||
</record> | ||
|
||
<record id="view_estate_property_offer_wizard_form" model="ir.ui.view"> | ||
<field name="name">estate.property.offer.wizard.form</field> | ||
<field name="model">estate.property.offer.wizard</field> | ||
<field name="arch" type="xml"> | ||
<form> | ||
<group> | ||
<field name="offer_price"/> | ||
<field name="partner_id"/> | ||
<field name="property_ids" widget="many2many_tags"/> | ||
</group> | ||
<footer> | ||
<button name="action_make_offer" string="Make Offer" type="object" class="btn-primary"/> | ||
<button string="Cancel" special="cancel"/> | ||
</footer> | ||
</form> | ||
</field> | ||
</record> | ||
</odoo> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.