-
Notifications
You must be signed in to change notification settings - Fork 2k
18.0 server tutorial frva #737
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
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 :) good work !
I left some comments on the code.
The little red things at the end of your files in the github ui are probably because you're missing end of line characters at the end of the last line. Your editor can probably be configured so it doesn't do that.
estate/__init__.py
Outdated
@@ -0,0 +1,3 @@ | |||
from . import models | |||
|
|||
from odoo import api, SUPERUSER_ID |
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.
What are you trying to do with this line?
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.
I pasted it from somewhere I found and forgot to see what it does ... I erased it for the next commit since it doesn't look mandatory
estate/models/estate_property.py
Outdated
name = fields.Char('Estate Name',required=True, translate=True) | ||
description = fields.Text('Description') | ||
postcode = fields.Char('Postcode') | ||
date_availability = fields.Date('Date Availability', copy=False, default=fields.Date.add(fields.Date.today(),months=3)) |
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.
Be careful for the default, if you do it this way fields.Date.today()
will get evaled at the time where the class is evaled (so when odoo is started) instead of when we create a new record. default
accepts lambda functions as well for this reason.
nitpick: for the label i think something like 'Date Available' or 'Availability Date' which is more natural-language-y would be better
estate/views/estate_menus.xml
Outdated
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.
descriptive names please
estate/models/estate_property.py
Outdated
garden_area = fields.Integer('Garden Area') | ||
garden_orientation = fields.Selection(string='Type', selection=[('north', 'North'), ('south', 'South'),('west', 'West'), ('east', 'East')]) | ||
active = fields.Boolean(default=True) | ||
state = fields.Selection(required=True, copy=False, default='New', selection=[('New', 'New'), ('Offer Received', 'Offer Received'),('Offer Accepted', 'Offer Accepted'), ('Sold', 'Sold'), ('Cancelled', '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.
nitpick: usually we like the technical names of a selection to feel more code-like, so lower_snake_case
estate/models/estate_property.py
Outdated
name = fields.Char('Title', required=True, translate=True) | ||
description = fields.Text('Description') | ||
postcode = fields.Char('Postcode') | ||
date_availability = fields.Date('Date Available', copy=False, default=lambda self: self._get_day_in_3_months()) |
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 -- your answer to this #737 (comment) here is a bit redundant because you're both using a lambda
and defining a fuction
You could either inline the functions return in the lambda or define the function above the fields and do default=_get_day_in_3_months
.
By convention when we do the latter we usually name the function something like _default_<fieldname>
@vava-odoo I'll let you take over here :) |
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.
Good job! Just a few ( 👀 ) comments. Don't hesitate to ask if you have questions!
estate/models/__init__.py
Outdated
@@ -0,0 +1,3 @@ | |||
from . import estate_property | |||
from . import estate_property_type, estate_property_tag, estate_property_offer |
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.
Convention is one file imported at a time
estate/models/estate_property.py
Outdated
from odoo import fields, models | ||
from odoo import api | ||
from odoo import 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.
But nor here 😇
Also, we usually import UserError and ValidationError direclty
from odoo import fields, models | |
from odoo import api | |
from odoo import exceptions | |
from odoo import api, fields, models | |
from odoo.exceptions import UserError, ValidationError |
estate/models/estate_property.py
Outdated
garden_area = fields.Integer('Garden Area') | ||
garden_orientation = fields.Selection(string='Orientation Type', selection=[('north', 'North'), ('south', 'South'), ('west', 'West'), ('east', 'East')]) | ||
active = fields.Boolean(default=True) | ||
state = fields.Selection(required=True, copy=False, default='new', selection=[('new', 'New'), ('offer_received', 'Offer Received'), ('offer_accepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', '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.
A bit long... Suggestion:
state = fields.Selection(required=True, copy=False, default='new', selection=[('new', 'New'), ('offer_received', 'Offer Received'), ('offer_accepted', 'Offer Accepted'), ('sold', 'Sold'), ('cancelled', 'Cancelled')]) | |
state = fields.Selection( | |
required=True, copy=False, default='new', | |
selection=[ | |
('new', 'New'), | |
('offer_received', 'Offer Received'), | |
('offer_accepted', 'Offer Accepted'), | |
('sold', 'Sold'), | |
('cancelled', 'Cancelled'), | |
], | |
) |
estate/models/estate_property.py
Outdated
'The selling price must be positive.') | ||
] | ||
|
||
@api.onchange("selling_price", "expected_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.
Why this onchange? You only want to constrain, don't you?
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.
I thought it was necessary to be executed at each time the selling or expected price changes but I guess it's not then
estate/models/estate_property.py
Outdated
|
||
@api.depends("living_area", "garden_area") | ||
def _compute_total_area(self): | ||
self.total_area = self.living_area + self.garden_area |
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.
What if you edit several records at once?
invoice_dictionary = { | ||
"partner_id": record.buyer_id.id, | ||
"move_type": "out_invoice", | ||
"journal_id": self.env['account.journal'].search([("code", "=", "INV")]).id, |
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.
Why do you need a journal? What happen if there is none?
You could also add limit=1
to improve the perf
] | ||
} | ||
self.env["account.move"].create(invoice_dictionary) | ||
super().action_sell_property() |
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 need to return super(), outside of the loop
Also, it would be interesting to call super first, to trigger the validation error if there is one before creating the invoice. It would be something like
super().action_sell_property() | |
res = super().action_sell_property() | |
for record in self: | |
... | |
return res |
}) | ||
] | ||
} | ||
self.env["account.move"].create(invoice_dictionary) |
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.
It would be best to batch create with a list of invoice values, outside of the loop on self.
estate_account/__manifest__.py
Outdated
'estate', | ||
'account' | ||
], | ||
'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.
Empty, can be dropped
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.
Empty, not in manifest... Can be removed 🙂
f9b9613
to
0475bd5
Compare
265d728
to
dda9737
Compare
for val in invoice_values: | ||
self.env["account.move"].create(val) |
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.
The purpose of my previous comment was to be able to create multiple invoices at once
for val in invoice_values: | |
self.env["account.move"].create(val) | |
self.env["account.move"].create(invoice_values) |
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 :) -- Good work !
I left some comments on the js tutorial
awesome_owl/static/src/card/card.js
Outdated
static template = "Card"; | ||
static props = { | ||
title: String, | ||
slots: Object |
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.
slots: Object | |
slots: Object, |
Also: could you make the slots optional so that something like below doesn't give an error?
<Card title='...'/>
awesome_owl/static/src/card/card.js
Outdated
}; | ||
|
||
setup(){ | ||
this.state = useState( {open: 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.
nitpick: inconsistent spacing
this.state = useState( {open: true}); | |
this.state = useState({ open: true }); |
if (this.props.onChange){ | ||
this.props.onChange() | ||
} |
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.
tip: js syntactic sugar 🌈 (subjective -- it's ok to not like/use it)
if (this.props.onChange){ | |
this.props.onChange() | |
} | |
this.props.onChange?.(); |
increment(){ | ||
this.state.value++; | ||
if (this.props.onChange){ | ||
this.props.onChange() |
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.
nitpick: inconsistent ;
usage (do either always or never)
this.props.onChange() | |
this.props.onChange(); |
<Counter onChange.bind="incrementSum"/> | ||
</Card> | ||
<Card title="'boring title'"> | ||
Some text egjpojges |
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.
segjopjge
if (todoIdInArray >= 0) { | ||
this.todos.splice(todoIdInArray, 1); | ||
} |
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.
indentation
if (todoIdInArray >= 0) { | |
this.todos.splice(todoIdInArray, 1); | |
} | |
if (todoIdInArray >= 0) { | |
this.todos.splice(todoIdInArray, 1); | |
} |
awesome_owl/static/src/utils.js
Outdated
export function UseAutofocus(refString){ | ||
var myRef = useRef(refString); | ||
onMounted(() => { | ||
console.log(myRef.el) |
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.
left-over debug code
} | ||
|
||
removeTodo(todoId){ | ||
var todoIdInArray = this.todos.findIndex((todo) => todo.id == todoId); |
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.
var todoIdInArray = this.todos.findIndex((todo) => todo.id == todoId); | |
const todoIdInArray = this.todos.findIndex((todo) => todo.id == todoId); |
never use var
; prefer const
over let
when possible
awesome_owl/static/src/utils.js
Outdated
|
||
|
||
export function UseAutofocus(refString){ | ||
var myRef = useRef(refString); |
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.
var myRef = useRef(refString); | |
const myRef = useRef(refString); |
also myRef
could use a better name
type: 'ir.actions.act_window', | ||
name: 'All leads', | ||
res_model: 'crm.lead', | ||
views: [[false, 'list'],[false, 'form']], |
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: [[false, 'list'],[false, 'form']], | |
views: [[false, 'list'], [false, 'form']], |
or evn
views: [[false, 'list'],[false, 'form']], | |
views: [ | |
[false, 'list'], | |
[false, 'form'], | |
], |
No description provided.