-
Notifications
You must be signed in to change notification settings - Fork 2.8k
[ADD] real_estate: Real Estate #546
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
base: 18.0
Are you sure you want to change the base?
Conversation
dhrs-odoo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @chga-odoo
I have given some changes implement that and also give the file name as estate_property.py
estate/__init__.py
Outdated
| @@ -0,0 +1 @@ | |||
| from . import models No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure an extra newline is added at the end of the file.
estate/__manifest__.py
Outdated
| 'version': '1.0', | ||
| 'summary': 'Real Estate Management Module', | ||
| 'author': 'Your Name', | ||
| 'category': 'Sales', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 'category': 'Sales', | |
| 'category': 'Brokerage', |
estate/__manifest__.py
Outdated
| ], | ||
| 'installable': True, # This is required! | ||
| 'application': True, | ||
| 'auto-install': False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 'auto-install': False, |
estate/models/estateProperty.py
Outdated
| copy=False, | ||
| required=True, | ||
| ) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def action_do_sold(self): | ||
| for record in self: | ||
| if record.state == "cancelled": | ||
| raise UserError("A canceled property cannot be sold!") | ||
| acceptOffer = False | ||
| for offer in record.offer_ids: | ||
| if offer.status == "accepted": | ||
| acceptOffer = True | ||
| break | ||
| if not acceptOffer: | ||
| raise UserError("Accept any offer before sold!") | ||
| record.state = "sold" | ||
| return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use self.state == 'cancelled' and similar conditions instead of doing so long
| <!-- <record id="estate_property_offer_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 string="Property Offer"> | ||
| <group> | ||
| <field name="price"/> | ||
| <field name="partner_id"/> | ||
| <field name="status" readonly=True/> | ||
| <field name="validity"/> | ||
| <field name="date_deadline"/> | ||
| </group> | ||
| </form> | ||
| </field> | ||
| </record> --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the unnecessary code
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <button name="action_accept_offer" title="Accept Offer" type="object" icon="fa-check"/> | ||
| <button name="action_refuse_offer" title="Refuse Offer" type="object" icon="fa-times"/> | ||
| <field name="status"/> | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-Understood the core Odoo MVC architecture. -Created a Real Estate module with a structured folder hierarchy. -Defined the estate.property model with essential fields. -Registered the model in the manifest and initialization files.
-Explored different field types and their usage in models. -Configured security access rights using ACL rules. -Designed List, Form, and Search views to manage property records. -Created menu items and actions for easy navigation.
-Established model relationships using Many2one , One2many and many2many. -Implemented computed fields with @api.depends. -Used domain filters to restrict dropdown selections dynamically.
-Developed action buttons to manage property status. -Applied SQL constraints for data integrity. -Implemented Python constraints to enforce business rules. -Used float_utils.float_compare() for numerical validations.
-Implemented Inline Views: Enabled direct data entry within list views for improved usability. -Added Widgets: Integrated 'statusbar' for better property state visualization. -Enhanced List View Ordering: Enabled manual drag-and-drop reordering for better organization. -Optimized View Attributes: Applied readonly, invisible, and conditional attributes for dynamic field behavior. -Configured Default Filters: Pre-selected filters for streamlined record navigation. -Introduced Stat Buttons: Added quick-access buttons in property type forms to view related offers instantly.
056a514 to
c904c7b
Compare
-create demo xml files for all models -add image to each property demo entry -change manifest file accordingly
c904c7b to
2caa795
Compare
- Prevent deletion of properties unless state is 'New' or 'Cancelled' using `@api.ondelete` - Update property state to 'Offer Received' upon offer creation - Restrict offer creation if the amount is lower than an existing offer - Add `property_ids` field to `res.users` as a One2many relation to `estate.property` - Apply a domain to `property_ids` to show only available properties - Modify `base.view_users_form` to display `property_ids` in a new notebook page - Create `estate_account` module dependent on `estate` and `account` modules - Add `estate_property.py` in `estate_account` with `_inherit` of `estate.property` - Override `action_sold` method to return the super call and ensure proper inheritance - Implement invoice creation (`account.move`) upon property sale with: - `partner_id` set from the property - `move_type` as 'Customer Invoice' - Add invoice lines to include: - 6% of the selling price - Additional administrative fee of 100.00
dhrs-odoo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello
I have added some comments have a look at it and implement it
estate/__manifest__.py
Outdated
| 'depends': ['base'], | ||
| 'license':'LGPL-3', | ||
| 'data': [ | ||
| # Add your XML/CSV files if any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can now remove this comment as it was for the understanding purpose
estate/__manifest__.py
Outdated
| 'views/estate_property_type_views.xml', | ||
| 'views/estate_property_tag_views.xml', | ||
| 'views/estate_property_views.xml', | ||
| 'views/estate_reUser_views.xml', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 'views/estate_reUser_views.xml', | |
| 'views/estate_res_user_views.xml', |
estate/models/__init__.py
Outdated
| from . import estatePropertyType | ||
| from . import estatePropertyTag | ||
| from . import estatePropertyOffer | ||
| from . import estateReUser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from . import estateReUser | |
| from . import estateResUser |
estate/models/estateProperty.py
Outdated
| @@ -0,0 +1,137 @@ | |||
| from odoo import models, fields, api, exceptions | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import should be in the alphabetical order
| return True | ||
|
|
||
| # action for property cancelled button | ||
| def action_do_cencelled(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def action_do_cencelled(self): | |
| def action_do_cancelled(self): |
estate/models/estatePropertyOffer.py
Outdated
| for offer_id in property_obj.offer_ids: | ||
| current_price = self.env["estate.property.offer"].browse(offer_id.id).price | ||
| if current_price > max_price: | ||
| max_price = current_price |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of looping with browse() to get the max offer price. you can use .mappped
estate/models/estatePropertyOffer.py
Outdated
| if max_price > offer_price: | ||
| raise exceptions.UserError("You cannot create an offer lower than an existing offer.") | ||
|
|
||
| property_obj.state = 'offer_received' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| property_obj.state = 'offer_received' | |
| property_obj.write({"state": "offer_received"}) |
estate/models/estatePropertyOffer.py
Outdated
| raise exceptions.UserError("You cannot create an offer lower than an existing offer.") | ||
|
|
||
| property_obj.state = 'offer_received' | ||
| return super(EstatePropertyOffer, self).create(vals) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return super(EstatePropertyOffer, self).create(vals) | |
| return super().create(vals_list) |
estate/models/estatePropertyOffer.py
Outdated
| current_price = self.env["estate.property.offer"].browse(offer_id.id).price | ||
| if current_price > max_price: | ||
| max_price = current_price | ||
| if max_price > offer_price: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if max_price > offer_price: | |
| if offer_price < max_price |
estate/models/estatePropertyTag.py
Outdated
| _sql_constraints = [ | ||
| ("unique_tag_name", "UNIQUE(name)", "The property tag name must be unique.") | ||
| ] | ||
|
No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an empty line at the end of every file
2caa795 to
74938f0
Compare
…perties - Added a minimal Kanban view displaying only the property name. - Enhanced the Kanban view to display: - Expected price - Best price (only when an offer is received) - Selling price (only when an offer is accepted) - Tags - Status - Enabled default grouping of properties by type. - Prevented drag and drop in the Kanban view. - Updated `ir.actions.act_window` to include `kanban` in `view_mode`.
| elif record.state != "offer_accepted": | ||
| raise UserError("Accept any offer before sold!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure an offer exists condition before marking the offer as sold
| for record in self: | ||
| if record.state == "sold": | ||
| raise UserError("A sold property cannot be canceled!") | ||
| record.state = "cancelled" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an check to refuse all existing offers before canceling
estate/models/estateProperty.py
Outdated
| # record.state = "new" | ||
|
|
||
|
|
||
| @api.ondelete(at_uninstall=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use def unlink
| </list> | ||
| </field> | ||
| </record> | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
estate/views/estate_reUser_views.xml
Outdated
| <?xml version="1.0" encoding="utf-8"?> | ||
| <odoo> | ||
| <data> | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
estate/views/estate_reUser_views.xml
Outdated
| @@ -0,0 +1,19 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <odoo> | |||
| <data> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <data> | |
| <data> |
estate/views/estate_reUser_views.xml
Outdated
| </record> | ||
|
|
||
| </data> | ||
| </odoo> No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure there is an extra line at the end of every file
estate_account/models/__init__.py
Outdated
| @@ -0,0 +1 @@ | |||
| from . import estate_property No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure there is an extra line at the end of every file
74938f0 to
f9fa52a
Compare
-Added Property Offers Report Template -Created estate_property_offers_report_table_template for listing property offers in reports. -Displays offer price, partner, validity, deadline, and status. -Created Full Report for Estate Properties -Added estate_property_offers_report_template to generate PDF reports for properties. -Includes property name, salesperson, expected price, and state. -Added Salesman-wise Offer Report -Created res_user_offer_report_template to generate reports for salesmen. -Displays properties assigned to each salesman along with offer details. -Extended Property Offer Report for Sold Properties -Inherited estate_property_offers_report_template to display a message if the property is sold. -Applied the same extension to res_user_offer_report_template. -Registered Report Actions in ir.actions.report -Registered estate_property_offers_report_template for estate.property model. -Registered res_user_offer_report_template for res.users model.
f9fa52a to
b15316e
Compare
…espective controllers - Implemented `/properties` route for listing properties with pagination. - Created property list template with a card-based UI. - Added property detail page with an overview, description, offer table and offer creation form. - Displayed offers dynamically, handling the case when no offers are available. - Integrated a 'properties' menu item in the website navbar for easy navigation.
d352cf5 to
e75f8cc
Compare
…tate Module -Added security.xml and updated manifest.py -Created user groups: Agent & Manager -Updated access rights file -Implemented record rule for agents -Tested agent user access via web interface -Bypassed access rights in estate_account for invoice creation -Added company_id to estate.property with default value -Created a multi-company setup -Restricted agents to only see properties from their current company -Ensured agents cannot modify property types or tags -Hid the Settings menu for agents
9190639 to
3510900
Compare
215b9f2 to
c9945b1
Compare
-add property type auction or regular -set time for auction period and also display remaining time on website property detail page -buyer can create offer through website -after auction time end, automaticlly highest offer is selected
c9945b1 to
cea43bb
Compare

Odoo Development Progress
Day 1: Odoo Architecture & Module Initialization
Understood the core Odoo MVC architecture.
Created a Real Estate module with a structured folder hierarchy.
Defined the estate.property model with essential fields.
Registered the model in the manifest and initialization files.
Day 2: Models, Security & Views
Explored different field types and their usage in models.
Configured security access rights using ACL rules.
Designed List, Form, and Search views to manage property records.
Created menu items and actions for easy navigation.
Day 3: Relationships & Computed Fields
Established model relationships using Many2one , One2many and many2many.
Implemented computed fields with @api.depends.
Used domain filters to restrict dropdown selections dynamically.
Day 4: Action Buttons & Constraints
Developed action buttons to manage property status.
Applied SQL constraints for data integrity.
Implemented Python constraints to enforce business rules.
Day 5: Enhanced Views, Widgets & Stat Buttons
Implemented Inline Views to enable direct data entry within list views.
Added 'statusbar' widgets for better visualization of property states.
Enhanced List View Ordering with manual drag-and-drop reordering.
Applied readonly, invisible, and conditional view attributes for dynamic behavior.
Configured Default Filters to streamline record navigation.
Introduced Stat Buttons in property type forms for quick access to related offers.
Day 6: Demo Data & Image Field
Created demo data aligned with the real_estate models.
Added an image field to properties for better visual representation.
Day 7: User Model Inheritance
Learned about Python inheritance in Odoo.
Inherited and extended the res.users model to integrate custom fields or behaviors.
Day 8: Module Linking & Invoice Creation
Created a new module named estate_account.
Linked estate_account to the real_estate module through inheritance.
Enabled automatic invoice creation when a property is sold.
Made minor tweaks and improvements for better workflow integration.
Day 9: Kanban View & UI Enhancements
Designed and implemented a Kanban view for properties.
Added a banner to property cards and an image to the app interface.
Made minor functional improvements to enhance user experience.
Day 10: Downloadable Reports
Created a detailed report of offers linked to properties, available for download.
Made minor adjustments in views to improve usability and layout.
Day 11: Website Controller Integration
Created a website controller to serve property details on the public website.
Implemented dynamic routing for individual property pages.
Ensured property details include price, type, description, and offers.
Day 12: Website Offer Submission
Added an offer submission form to the property detail page.
Enabled users to submit offers directly from the website.
Implemented frontend validation for offer price and deadline dates.
Enhanced website UI for a more intuitive user experience.
Day 13: Access Rights, Chatter, Wizard & Unit Testing
Defined access rights for Agent and Manager roles with tailored permissions.
Enabled chatter to track communications and activity on properties.
Implemented a wizard to allow adding a single offer to multiple properties at once.
Day 14: Unit Testing, Owl Components & Reactivity
Developed unit tests to ensure:
Offers can’t be created on sold properties.
Properties can’t be sold without an accepted offer.
Garden area and orientation reset correctly on form changes.
Improved UI layout for better property detail readability.
Owl Components & Reactivity:
Implemented Owl components with reactivity, props handling, and lifecycle hooks.
Created Counter component using useState and extracted it from Playground.
Developed Card component with validated title and content props.
Enabled safe HTML rendering using t-out in the Card component.
Integrated sum calculation feature using onChange callback in Counter.
Built TodoList and TodoItem components with dynamic rendering via t-foreach.
Applied conditional styling for completed todos using t-att-class.