Skip to content
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

[MIG] base_location_nuts: Migration to 10.0 #432

Merged
merged 10 commits into from Jul 6, 2017

Conversation

chienandalu
Copy link
Member

@api.depends('country_id')
def _labels_get(self):
self.lbl_region = _('Region')
self.lbl_substate = _('Substate')

@api.multi
def onchange_state(self, state_id):
Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure this kind of api is not available in v10. Please check that and use @api.onchange instead if possible.

<field name="nuts2_id"/>
<field name="nuts3_id"/>
<field name="nuts4_id"/>
<div width="1%" cell-class="oe_form_group_cell_label"
Copy link
Member

Choose a reason for hiding this comment

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

width=1% does something?

options="{'no_open': True, 'no_create': True}"
attrs="{'readonly': [('use_parent_address','=',True)]}"/>
</div>
<div width="1%" cell-class="oe_form_group_cell_label"
Copy link
Member

Choose a reason for hiding this comment

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

Same on width

<field name="nuts2_id"/>
<field name="nuts3_id"/>
<field name="nuts4_id"/>
<div width="1%" cell-class="oe_form_group_cell_label"
Copy link
Member

Choose a reason for hiding this comment

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

Same on width

options="{'no_open': True, 'no_create': True}"
attrs="{'readonly': [('use_parent_address','=',True)]}"/>
</div>
<div width="1%" cell-class="oe_form_group_cell_label"
Copy link
Member

Choose a reason for hiding this comment

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

Same on width.

</filter>
</field>
</record>

</data>
</openerp>
</odoo>
Copy link
Member

Choose a reason for hiding this comment

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

newline

from openerp import models, api, _
from openerp.exceptions import Warning as UserError
from odoo import _, api, models
from odoo.exceptions import Warning
Copy link
Member

Choose a reason for hiding this comment

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

Import it as UserError; Warning is deprecated.

return self._onchange_nuts(2)
region = fields.Many2one(comodel_name='res.partner.nuts',
string="Region")
substate = fields.Many2one(comodel_name='res.partner.nuts',
Copy link
Member

Choose a reason for hiding this comment

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

Don't you need oldname in these cols? Or any other migrations?

@rafaelbn rafaelbn added this to the 10.0 milestone May 31, 2017
@chienandalu chienandalu force-pushed the 10.0-mig-base_location_nuts branch 2 times, most recently from 36bf980 to e0a675b Compare May 31, 2017 16:30
@pedrobaeza
Copy link
Member

Please rebase to get a green branch

@pedrobaeza
Copy link
Member

Waiting fixes before reviewing

To contribute to this module, please visit http://odoo-community.org.
Copy link
Member

Choose a reason for hiding this comment

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

https

'views/res_partner_nuts_view.xml',
'views/res_partner_view.xml',
'wizard/nuts_import_view.xml',
'security/ir.model.access.csv',
],
'images': [
'images/new_fields.png',
],
'author': 'Antiun Ingeniería S.L., '
Copy link
Member

Choose a reason for hiding this comment

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

Remove Antiun

'author': 'Antiun Ingeniería S.L., '
'Tecnativa'
Copy link
Member

Choose a reason for hiding this comment

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

Comma at the end

'Odoo Community Association (OCA)',
'website': 'http://www.antiun.com',
'website': 'http://www.tecnativa.com',
Copy link
Member

Choose a reason for hiding this comment

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

https


@api.multi
def _onchange_nuts(self, level):
field = self["nuts%d_id" % level]
Copy link
Member

Choose a reason for hiding this comment

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

Please use getattr(self, "nuts%_id")

Copy link
Member

Choose a reason for hiding this comment

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

No, he is using the right thing. Attributes can get anything from the object, while keys can only get fields, so for security this is the recommended system to access fields with variable names, and even more when the variable comes from outside the method.

Please check slide 40 of https://www.odoo.com/es_ES/slides/slide/10-rules-for-safer-code-398

Copy link
Member

Choose a reason for hiding this comment

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

Well, this system can't be abused like the scenario of the slides. My fear is that this is not a documented way of accessing a field. The official way is with dot notation (and thus, getattr), but I see in the slides that is using this method, so go on...

Copy link
Member

Choose a reason for hiding this comment

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

Well, that presentation was given by @odony, so I guess that makes it somehow officially documented. Maybe a PR to docs would be good.

Copy link

Choose a reason for hiding this comment

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

👍 let's make it more official: odoo/odoo@464fe4a

Copy link
Member

Choose a reason for hiding this comment

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

Thank your very much for the update on the documentation, Olivier!

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, great little addition! 👏 👏

self.nuts1_id = nuts1.id
return {
'domain': domain,
}

@api.multi
def onchange_state(self, state_id):
Copy link
Member

Choose a reason for hiding this comment

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

This method is not used anymore. Please find the equivalent one or declare a new unique onchange (def onchange_state_id_base_location_nuts(self):.

'res.partner.nuts',
'parent_id',
"Children",
oldname="children")
Copy link
Member

Choose a reason for hiding this comment

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

There's no need of oldname in one2many fields, as they don't have a real column in the DB.

options="{'no_open': True, 'no_create': True}"
attrs="{'readonly': [('use_parent_address','=',True)]}"/>
</div>
<field name="nuts1_id"/>
Copy link
Member

Choose a reason for hiding this comment

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

Why do you remove the attrs attribute?

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't. That change comes from a previous commit (Tecnativa@eade50c)

from openerp import models, api, _
from openerp.exceptions import Warning
from odoo import _, api, models
from odoo.exceptions import Warning as UserError
Copy link
Member

Choose a reason for hiding this comment

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

Old alias. Now UserError is the valid one.

@@ -184,13 +181,14 @@ def run_import(self):
nuts_to_delete = nuts_model.search(
[('country_id', 'in', [x.id for x in self._countries.values()])])
# Download NUTS in english, create or update
logger.info('Import NUTS 2013 English')
logger.info('Importing NUTS 2013 English')
Copy link
Member

Choose a reason for hiding this comment

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

Put ... at the end to indicate that is an operation that requires time.

@pedrobaeza
Copy link
Member

Please increase test coverage for the onchanges and so on.

@chienandalu
Copy link
Member Author

I was doing some test and was getting 404 from the NUTS Eurostat server. There's some issue with Ramon not accepting https request. It does it right on http though.

@pedrobaeza
Copy link
Member

Well, change it then.

@chienandalu
Copy link
Member Author

@yajo @pedrobaeza It's all green now

Copy link
Member

@pedrobaeza pedrobaeza left a comment

Choose a reason for hiding this comment

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

Remember to squash your commits before merging

@chienandalu
Copy link
Member Author

Commits squashed

@chienandalu
Copy link
Member Author

Yes, @pedrobaeza, my fault for copy-pasting and not passing flake locally prior to commit 😬
Can you review again, @yajo ?

@pedrobaeza
Copy link
Member

Please put pre-commit linter in your git for avoiding these "surprises": https://github.com/OCA/maintainer-quality-tools/tree/master/git

@chienandalu
Copy link
Member Author

@pedrobaeza Thanks!

Copy link
Member

@yajo yajo left a comment

Choose a reason for hiding this comment

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

Humm complex module, some suggestions to simplify it in some parts 😊

BTW, there are some security good practices that it's good to follow, see below.

Thanks for the good job!

}
dict_recursive_update(result, changes)
def _onchange_nuts(self, level):
field = getattr(self, 'nuts%d_id' % level)
Copy link
Member

Choose a reason for hiding this comment

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

Do not use getattr, use self["nuts%d_id" % level] instead.

Se slides 40 and 41: https://www.odoo.com/es_ES/slides/slide/10-rules-for-safer-code-398

self.country_id = country_id
if state_id and self.state_id != state_id:
self.state_id = state_id
if (level - 1) > 0:
Copy link
Member

Choose a reason for hiding this comment

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

😕 Why not just if level > 1?

if state_id and self.state_id != state_id:
self.state_id = state_id
if (level - 1) > 0:
parent_id = getattr(field, 'parent_id')
Copy link
Member

Choose a reason for hiding this comment

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

Why not parent_id = field.parent_id?

parent_id = getattr(field, 'parent_id')
if parent_id:
nuts_parent_level = 'nuts%d_id' % (level - 1)
parent_field = getattr(self, nuts_parent_level)
Copy link
Member

Choose a reason for hiding this comment

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

no getattr for accessing fields.

def _onchange_nuts1_id(self):
return self._onchange_nuts(1)

@api.multi
Copy link
Member

Choose a reason for hiding this comment

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

All these api.multi can be dropped, now in v10 it's the default.

def onchange_state_id_base_location_nuts(self):
if self.state_id:
# state = self.env['res.country.state'].browse(self.state_id)
result = {'value': {'country_id': self.state_id.country_id.id}}
Copy link
Member

Choose a reason for hiding this comment

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

self.country_id = self.state_id.country_id

self[field] = nuts_state
result.setdefault("value", dict())
result['value'][field] = nuts_state.id
return result
Copy link
Member

Choose a reason for hiding this comment

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

Remove lines 117-119, they are redundant. If you edit self under an onchange in the new api, you don't need to return a dict with values.

parent_left = fields.Integer('Parent Left', select=True)
parent_right = fields.Integer('Parent Right', select=True)
child_ids = fields.One2many(comodel_name='res.partner.nuts',
inverse_name='parent_id', string='Children')
Copy link
Member

Choose a reason for hiding this comment

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

Add oldname='children'

logger.info('Reading level=%s, id=%s' %
(node.get('idLevel', 'N/A'),
node.get('id', 'N/A')))
logger.debug(
Copy link
Member

Choose a reason for hiding this comment

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

Wrong indentation here?

@@ -36,7 +35,7 @@
<menuitem action="nuts_import_action"
id="nuts_import_menu"
name="Import NUTS 2013"
parent="base.menu_localisation"
parent="sales_team.menu_localisation"
Copy link
Member

Choose a reason for hiding this comment

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

It's sad to have to add the sales_team dependency just for putting the menu somewhere. Do you think there's another place where we can put it and skip this big dependency just for that? 🤔 Or maybe we really need this for other reason?

Copy link
Member Author

Choose a reason for hiding this comment

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

This family of modules fall into that menu historically. It's no really needed at all for anything else. There aren't much options on base views anyway... Ideas are welcomed 😄

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, @pedrobaeza , but this module doesn't depend on that one 😕 It only depended on base before...

Copy link
Member

Choose a reason for hiding this comment

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

Uhm, OK, let's go this way then.

@chienandalu
Copy link
Member Author

@yajo Thanks for your comments :) I've tried to implement them all.

'Reading level=%s, id=%s',
node.get('idLevel', 'N/A'),
node.get('id', 'N/A'))
logger.debug('Reading level=%s, id=%s',
Copy link
Member

Choose a reason for hiding this comment

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

The indentation problem I was referring to is that these are 8 spaces instead of the usual 4. (I mean from the line 195 to 196).

@yajo
Copy link
Member

yajo commented Jul 6, 2017

@chienandalu this looks almost perfect now. Could you please fix that little comment and squash all the latest migration-related commits to proceed with merge?

yajo and others added 9 commits July 6, 2017 10:21
This makes NUTS labels and levels to be stored in the res.country object.
Now creating l10n submodules is a piece of cake!

Relational fields now follow guidelines on naming. Old name attribute used
for backwards compatibility wherever needed.

Also some methods have been renamed, and refactored to be smarter. Most cases
l10n modules will just need to fill the res.contry table, and regions and
substates domains will work out of the box. In case you still need to
overwrite any method, splitting in smaller methods makes it easier too.

Oh! And no need for recursive dictionary updates.
@chienandalu
Copy link
Member Author

@yajo Fixed and commits squashed

@yajo yajo merged commit 1a0000c into OCA:10.0 Jul 6, 2017
@yajo yajo deleted the 10.0-mig-base_location_nuts branch July 6, 2017 09:02
@pedrobaeza pedrobaeza mentioned this pull request Jul 6, 2017
38 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants