-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Technical Training (Ahnae) #1247
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: master
Are you sure you want to change the base?
Changes from 32 commits
b68a192
b7e18c9
781b590
bc75b91
703b451
2b46f88
2666fbd
a1c6e1e
1fb914a
afbfbba
80d74ce
37bbff7
39cd9c6
a930b33
b9b84e2
034623c
688ae48
f073812
a8f5d11
11467ce
29377d5
9713b4c
8e0f36c
c6546c2
4cec624
7df65a3
158a5e3
aafedb2
777efdb
8a51cf8
ed456c8
e406286
27dac19
40e8c45
6d7c4d4
02b6fb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| { | ||
| // Use IntelliSense to learn about possible attributes. | ||
| // Hover to view descriptions of existing attributes. | ||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "name": "Python Debugger: Current File", | ||
| "type": "debugpy", | ||
| "request": "launch", | ||
| "program": "${file}", | ||
| "console": "integratedTerminal" | ||
| }, | ||
|
|
||
| { | ||
| "name": "Odoo Server", | ||
| "type": "debugpy", | ||
| "request": "launch", | ||
| "python": "/home/odoo/odoo/venv/bin/python3", | ||
| "program": "/home/odoo/odoo/odoo-bin", | ||
| "args" : [ | ||
| "--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials", | ||
| "-d", "rd_demo", | ||
| "--dev", "all", | ||
| "--without-demo", "all", | ||
| "-p", "8069", | ||
| "--limit-time-cpu", "0", | ||
| "--limit-time-real", "0", | ||
| // "-i", "", | ||
| ], | ||
| "console": "integratedTerminal", | ||
| "variablePresentation": {} | ||
| }, | ||
| { | ||
| "name": "Test Odoo", | ||
| // "preLaunchTask": "drop_test_db", | ||
| "type": "debugpy", | ||
| "request": "launch", | ||
| "program": "/home/odoo/odoo/odoo-bin", | ||
| "args" : [ | ||
| "--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials", | ||
| "-d", "DB_NAMEtest", | ||
| "-p", "8071", | ||
| "--limit-time-cpu", "0", | ||
| "--limit-time-real", "0", | ||
| "--without-demo", "all", | ||
| "--stop-after-init", | ||
| //"-i", "", | ||
| "--test-tags", "", | ||
| //"--log-level", "error", | ||
| ], | ||
| "console": "integratedTerminal", | ||
| "variablePresentation": {} | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| { | ||
| "folders": [ | ||
| { | ||
| "path": "/home/odoo/odoo" | ||
| }, | ||
| { | ||
| "path": "/home/enterprise" | ||
| }, | ||
| { | ||
| "path": "/home/tutorials" | ||
| } | ||
| ], | ||
| "settings": { | ||
| "launch": { | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "name": "Odoo Server", | ||
| "type": "debugpy", | ||
| "request": "launch", | ||
| "program": "/home/odoo/odoo/odoo-bin", | ||
| "args" : [ | ||
| "--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials", | ||
| "-d", "rd_demo", | ||
| "--dev", "all", | ||
| "--without-demo", "all", | ||
| "-p", "8069", | ||
| "--limit-time-cpu", "0", | ||
| "--limit-time-real", "0", | ||
| // "-i", "", | ||
| ], | ||
| "console": "integratedTerminal", | ||
| "variablePresentation": {} | ||
| }, | ||
| { | ||
| "name": "Test Odoo", | ||
| // "preLaunchTask": "drop_test_db", | ||
| "type": "debugpy", | ||
| "request": "launch", | ||
| "program": "/home/odoo/odoo/odoo-bin", | ||
| "args" : [ | ||
| "--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials", | ||
| "-d", "DB_NAMEtest", | ||
| "-p", "8071", | ||
| "--limit-time-cpu", "0", | ||
| "--limit-time-real", "0", | ||
| "--without-demo", "all", | ||
| "--stop-after-init", | ||
| //"-i", "", | ||
| "--test-tags", "", | ||
| //"--log-level", "error", | ||
| ], | ||
| "console": "integratedTerminal", | ||
| "variablePresentation": {} | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from . import models |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||
| { | ||||||
| 'name': "Estate", | ||||||
| 'version': '1.0', | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Version should match the Odoo version, this way Odoo will not allow the module to be installed in other versions.
Suggested change
|
||||||
| 'depends': [ | ||||||
| 'base', | ||||||
| ], | ||||||
| 'category': 'Tutorials', | ||||||
| 'application': True, | ||||||
| 'data': [ | ||||||
| 'security/ir.model.access.csv', | ||||||
| 'views/res_users_views.xml', | ||||||
| 'views/estate_property_views.xml', | ||||||
| 'views/estate_property_offer_views.xml', | ||||||
| 'views/estate_property_type_views.xml', | ||||||
| 'views/estate_property_tag_views.xml', | ||||||
| 'views/estate_menus.xml', | ||||||
| ], | ||||||
| 'author': "Odoo", | ||||||
| 'license': 'AGPL-3' | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from . import estate_property | ||
| from . import estate_property_type | ||
| from . import estate_property_tag | ||
| from . import estate_property_offer | ||
| from . import res_user |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,131 @@ | ||||||||||||||||||||||||||||||||||||||
| from odoo import api, fields, models, exceptions | ||||||||||||||||||||||||||||||||||||||
| from odoo.exceptions import ValidationError, UserError | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please respect alphabetical order for imports |
||||||||||||||||||||||||||||||||||||||
| from odoo.tools import float_compare, float_is_zero | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| class EstatePropertytModel(models.Model): | ||||||||||||||||||||||||||||||||||||||
| _name = "estate.property" | ||||||||||||||||||||||||||||||||||||||
| _description = "Estate Property Model" | ||||||||||||||||||||||||||||||||||||||
| _order = "id desc" | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| 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( | ||||||||||||||||||||||||||||||||||||||
| string='Type', | ||||||||||||||||||||||||||||||||||||||
| selection=[ | ||||||||||||||||||||||||||||||||||||||
| ('north', 'North'), | ||||||||||||||||||||||||||||||||||||||
| ('south', 'South'), | ||||||||||||||||||||||||||||||||||||||
| ('east', 'East'), | ||||||||||||||||||||||||||||||||||||||
| ('west', 'West'), | ||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| active = fields.Boolean(default=True) | ||||||||||||||||||||||||||||||||||||||
| state = fields.Selection( | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation here as well |
||||||||||||||||||||||||||||||||||||||
| selection=[ | ||||||||||||||||||||||||||||||||||||||
| ('new', 'New'), | ||||||||||||||||||||||||||||||||||||||
| ('offer_received', 'Offer Received'), | ||||||||||||||||||||||||||||||||||||||
| ('offer_accepted', 'Offer Accepted'), | ||||||||||||||||||||||||||||||||||||||
| ('sold', 'Sold'), | ||||||||||||||||||||||||||||||||||||||
| ('cancelled', 'Cancelled'), | ||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||
| required=True, | ||||||||||||||||||||||||||||||||||||||
| copy=False, | ||||||||||||||||||||||||||||||||||||||
| default='new', | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| type_id = fields.Many2one( | ||||||||||||||||||||||||||||||||||||||
| "estate.property.type", | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to stay consistent with |
||||||||||||||||||||||||||||||||||||||
| string="Tag", | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| salesperson_id = fields.Many2one( | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation |
||||||||||||||||||||||||||||||||||||||
| "res.users", | ||||||||||||||||||||||||||||||||||||||
| string="Salesperson", | ||||||||||||||||||||||||||||||||||||||
| default=lambda self: self.env.user, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| buyer_id = fields.Many2one( | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation |
||||||||||||||||||||||||||||||||||||||
| "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") | ||||||||||||||||||||||||||||||||||||||
| best_price = fields.Float(compute="_compute_best_price") | ||||||||||||||||||||||||||||||||||||||
| _check_expected_price = models.Constraint( | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation is off, also constraints should be after computes (see doc) |
||||||||||||||||||||||||||||||||||||||
| 'CHECK(expected_price > 0)', | ||||||||||||||||||||||||||||||||||||||
| 'The Expected price of a property should be > 0', | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| _check_selling_price = models.Constraint( | ||||||||||||||||||||||||||||||||||||||
| 'CHECK(selling_price > 0)', | ||||||||||||||||||||||||||||||||||||||
| 'The selling price of a property should be > 0', | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| _check_name_unique = models.Constraint( | ||||||||||||||||||||||||||||||||||||||
| 'UNIQUE(name)', | ||||||||||||||||||||||||||||||||||||||
| 'The prop name must be unique!', | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @api.depends("living_area", "garden_area") | ||||||||||||||||||||||||||||||||||||||
| def _compute_total_area(self): | ||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| record.total_area = (record.living_area or 0) + (record.garden_area or 0) | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good use of short-circuiting 👍 |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @api.depends("offer_ids") | ||||||||||||||||||||||||||||||||||||||
| def _compute_best_price(self): | ||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| highest_price = 0 | ||||||||||||||||||||||||||||||||||||||
| for offer in record.offer_ids: | ||||||||||||||||||||||||||||||||||||||
| highest_price = max(highest_price, offer.price) | ||||||||||||||||||||||||||||||||||||||
| record.best_price = highest_price | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Max can take a default value, or you could use ternary assignation. Default value:
Suggested change
Ternary assignation
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @api.onchange("garden") | ||||||||||||||||||||||||||||||||||||||
| def _onchange_garden(self): | ||||||||||||||||||||||||||||||||||||||
| if self.garden: | ||||||||||||||||||||||||||||||||||||||
| self.garden_area = 10 | ||||||||||||||||||||||||||||||||||||||
| self.garden_orientation = 'north' | ||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||
| self.garden_area = 0 | ||||||||||||||||||||||||||||||||||||||
| self.garden_orientation = '' | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tricky (?) question time! At first glance, this method could also be an Answer
It doesn't make much sense to set arbitrary default values when programmatically updating records, so |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def action_sold(self): | ||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| if record.state == 'cancelled': | ||||||||||||||||||||||||||||||||||||||
| raise exceptions.UserError("cancelled prop can't be sold") | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Message could use a lifting, it is meant for user display
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| record.state = 'sold' | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def action_cancel(self): | ||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| if record.state == 'sold': | ||||||||||||||||||||||||||||||||||||||
| raise exceptions.UserError("Sold prop can't be cancelled") | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||||||||||||||||||||||||||||||||||||||
| record.state = 'cancelled' | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @api.constrains('selling_price') | ||||||||||||||||||||||||||||||||||||||
| def _check_price(self): | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This name is not very explicit in what it is meant to check. Also, you should define all of the fields required for the constraint.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| if float_is_zero(record.selling_price, precision_digits=2): | ||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is already checked by your constraint on |
||||||||||||||||||||||||||||||||||||||
| limit = record.expected_price * 0.9 | ||||||||||||||||||||||||||||||||||||||
| if float_compare(record.selling_price, limit, precision_digits=2) == -1: | ||||||||||||||||||||||||||||||||||||||
| raise ValidationError("The selling price cannot be lower than 90% of the expected price!") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @api.ondelete(at_uninstall=False) | ||||||||||||||||||||||||||||||||||||||
| def _check_property_state_on_delete(self): | ||||||||||||||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||||||||||||||
| if record.state not in ['new', 'canceled']: | ||||||||||||||||||||||||||||||||||||||
| raise UserError( | ||||||||||||||||||||||||||||||||||||||
| "You cannot delete a property that is not 'New' or 'Cancelled'!" | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to line break here 😉 |
||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,85 @@ | ||||||||||||||||||||||||||
| from odoo import api, fields, models, exceptions | ||||||||||||||||||||||||||
| from odoo.exceptions import ValidationError | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| class EstatePropertyOffer(models.Model): | ||||||||||||||||||||||||||
| _name = "estate.property.offer" | ||||||||||||||||||||||||||
| _description = "Real Estate Property Offer" | ||||||||||||||||||||||||||
| _order = "price desc" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| price = fields.Float() | ||||||||||||||||||||||||||
| status = fields.Selection( | ||||||||||||||||||||||||||
| selection=[ | ||||||||||||||||||||||||||
| ('accepted', 'Accepted'), | ||||||||||||||||||||||||||
| ('refused', 'Refused'), | ||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||
| copy=False, | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| partner_id = fields.Many2one( | ||||||||||||||||||||||||||
| "res.partner", | ||||||||||||||||||||||||||
| string="Partner", | ||||||||||||||||||||||||||
| required=True | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| property_id = fields.Many2one( | ||||||||||||||||||||||||||
| "estate.property", | ||||||||||||||||||||||||||
| string="Property", | ||||||||||||||||||||||||||
| required=True, | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| property_type_id = fields.Many2one( | ||||||||||||||||||||||||||
| related="property_id.type_id", | ||||||||||||||||||||||||||
| string="Property Type", | ||||||||||||||||||||||||||
| store=True | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| validity = fields.Integer(default=7) | ||||||||||||||||||||||||||
| date_deadline = fields.Date( | ||||||||||||||||||||||||||
| compute="_compute_date_deadline", | ||||||||||||||||||||||||||
| inverse="_inverse_date_deadline", | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| _check_price = models.Constraint( | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ordering |
||||||||||||||||||||||||||
| 'CHECK(price > 0)', | ||||||||||||||||||||||||||
| 'The offer price should be > 0', | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @api.depends("validity", "create_date") | ||||||||||||||||||||||||||
| def _compute_date_deadline(self): | ||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||
| record.date_deadline = fields.Date.add( | ||||||||||||||||||||||||||
| (fields.Date.to_date(record.create_date) or fields.Date.today()), | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can just do
Suggested change
|
||||||||||||||||||||||||||
| days=record.validity | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def _inverse_date_deadline(self): | ||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||
| record.validity = ( | ||||||||||||||||||||||||||
| record.date_deadline - (fields.Date.to_date(record.create_date) or fields.Date.today()) | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||||||||||||||||||||||||||
| ).days | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def action_accept_offer(self): | ||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||
| if record.property_id.state == 'sold': | ||||||||||||||||||||||||||
| raise exceptions.UserError("Prob is already sold") | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Message |
||||||||||||||||||||||||||
| if record.property_id.garden and record.property_id.garden_orientation == 'south': | ||||||||||||||||||||||||||
| if record.price < record.property_id.expected_price: | ||||||||||||||||||||||||||
| raise ValidationError("South facing house should have offer with >= tothe prop expected price") | ||||||||||||||||||||||||||
| record.property_id.state = 'offer_accepted' | ||||||||||||||||||||||||||
| record.property_id.selling_price = record.price | ||||||||||||||||||||||||||
| record.property_id.buyer_id = record.partner_id | ||||||||||||||||||||||||||
| record.status = 'accepted' | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to use
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def action_refuse_offer(self): | ||||||||||||||||||||||||||
| for record in self: | ||||||||||||||||||||||||||
| record.status = 'refused' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @api.model | ||||||||||||||||||||||||||
| def create(self, vals_list): | ||||||||||||||||||||||||||
| for vals in vals_list: | ||||||||||||||||||||||||||
| prop = self.env['estate.property'].browse(vals.get('property_id')) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if prop.best_price > 0 and vals.get('price') < prop.best_price: | ||||||||||||||||||||||||||
| raise exceptions.UserError( | ||||||||||||||||||||||||||
| f"The offer must be at least {prop.best_price}." | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| if prop.state == 'new': | ||||||||||||||||||||||||||
| prop.state = 'offer_received' | ||||||||||||||||||||||||||
|
Comment on lines
+83
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would make more sense as a |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return super().create(vals_list) | ||||||||||||||||||||||||||
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 should configure your global
.gitignoreto make sure such files don't get pushed to your PRs 😉