Skip to content

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

Open
wants to merge 22 commits into
base: 18.0
Choose a base branch
from

Conversation

frva-odoo
Copy link

No description provided.

@robodoo
Copy link

robodoo commented Apr 23, 2025

Pull request status dashboard

Copy link

@naja628 naja628 left a 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.

@@ -0,0 +1,3 @@
from . import models

from odoo import api, SUPERUSER_ID
Copy link

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?

Copy link
Author

@frva-odoo frva-odoo Apr 23, 2025

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

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))
Copy link

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

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

descriptive names please

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')])
Copy link

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

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())
Copy link

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>

@naja628
Copy link

naja628 commented Apr 24, 2025

@vava-odoo I'll let you take over here :)

Copy link

@vava-odoo vava-odoo left a 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!

@@ -0,0 +1,3 @@
from . import estate_property
from . import estate_property_type, estate_property_tag, estate_property_offer

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

Comment on lines 1 to 3
from odoo import fields, models
from odoo import api
from odoo import exceptions

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

Suggested change
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

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')])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit long... Suggestion:

Suggested change
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'),
],
)

'The selling price must be positive.')
]

@api.onchange("selling_price", "expected_price")

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?

Copy link
Author

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


@api.depends("living_area", "garden_area")
def _compute_total_area(self):
self.total_area = self.living_area + self.garden_area

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,

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()

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

Suggested change
super().action_sell_property()
res = super().action_sell_property()
for record in self:
...
return res

})
]
}
self.env["account.move"].create(invoice_dictionary)

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'
],
'data': [],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty, can be dropped

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 🙂

@frva-odoo frva-odoo force-pushed the 18.0-server-tutorial-frva branch from f9b9613 to 0475bd5 Compare April 28, 2025 11:47
@frva-odoo frva-odoo force-pushed the 18.0-server-tutorial-frva branch from 265d728 to dda9737 Compare April 29, 2025 06:49
Comment on lines 28 to 29
for val in invoice_values:
self.env["account.move"].create(val)

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

Suggested change
for val in invoice_values:
self.env["account.move"].create(val)
self.env["account.move"].create(invoice_values)

Copy link

@naja628 naja628 left a 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

static template = "Card";
static props = {
title: String,
slots: Object
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
slots: Object
slots: Object,

Also: could you make the slots optional so that something like below doesn't give an error?

<Card title='...'/> 

};

setup(){
this.state = useState( {open: true});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: inconsistent spacing

Suggested change
this.state = useState( {open: true});
this.state = useState({ open: true });

Comment on lines 15 to 17
if (this.props.onChange){
this.props.onChange()
}
Copy link

@naja628 naja628 May 2, 2025

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)

Suggested change
if (this.props.onChange){
this.props.onChange()
}
this.props.onChange?.();

increment(){
this.state.value++;
if (this.props.onChange){
this.props.onChange()
Copy link

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)

Suggested change
this.props.onChange()
this.props.onChange();

<Counter onChange.bind="incrementSum"/>
</Card>
<Card title="'boring title'">
Some text egjpojges
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

segjopjge

Comment on lines 30 to 32
if (todoIdInArray >= 0) {
this.todos.splice(todoIdInArray, 1);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation

Suggested change
if (todoIdInArray >= 0) {
this.todos.splice(todoIdInArray, 1);
}
if (todoIdInArray >= 0) {
this.todos.splice(todoIdInArray, 1);
}

export function UseAutofocus(refString){
var myRef = useRef(refString);
onMounted(() => {
console.log(myRef.el)
Copy link

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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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



export function UseAutofocus(refString){
var myRef = useRef(refString);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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']],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
views: [[false, 'list'],[false, 'form']],
views: [[false, 'list'], [false, 'form']],

or evn

Suggested change
views: [[false, 'list'],[false, 'form']],
views: [
[false, 'list'],
[false, 'form'],
],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants