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

10.0 #3963 partner relation in tab port #459

Closed

Conversation

daramousk
Copy link
Member

Port of module partner_relation_in_tab to v10

@hbrunn hbrunn added this to the 10.0 milestone Aug 16, 2017
@hbrunn
Copy link
Member

hbrunn commented Aug 16, 2017

before I do an in-depth review:

@NL66278
Copy link
Contributor

NL66278 commented Sep 4, 2017

I would propose a new name for the module, as it is an extension of partner_multi_relation (that was renamed from partner_relations). So to keep the link with partner_multi_relation, of which this is an extension, I would propose partner_multi_relation_tabs.

return self.env.cr.fetchall()

def _create_relation_type_tab(self, rel_type, inverse, field_names):
'''Create an xml node containing the relation's tab to be added to the
Copy link
Contributor

Choose a reason for hiding this comment

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

Double quotes for function docstring!!

view.append(etree.Element('field', name='id',
invisible='True'))
field_names.append('id')
for rel_type in own_tab_types:
Copy link
Contributor

Choose a reason for hiding this comment

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

Code can be mutch simplified if you just pass rel_type to underlying methods. No need then for separate function calls with inverse = True of inverse = False. inverse is translated back to left or right in underlying methods anyway, which just confuses things. (I know you just migrated the old code, and I think this was there as well, but now a good opportunity to clean up).

own_tab_left = fields.Boolean('Show in own tab', default=False)
own_tab_right = fields.Boolean('Show in own tab', default=False)

def _update_res_partner_fields(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking about performance I really do not like the way this is implemented. With any tab added or deleted, all the tabfields, also those not touched at all, are created from scratch. I should not be to difficult (and probably even less code) to just check for changes in the own_tab_left field or the own_tab_right field, and create/delete the tabfields accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

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

@NL66278 How can this be done? Keep in mind that that self here is a recordset not the model so it does not search on all the records, only on those who had their own_tab_left and/or own_tab_right changed.

class ResPartner(Model):
_inherit = 'res.partner'

def _get_relation_ids_select(self, field_name, arg):
Copy link
Contributor

Choose a reason for hiding this comment

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

This function is not needed anymore. In the old version of partner_relations, all relations where shown in a tab. This override was to exclude the relations from the main tab, that were shown in their own tab.

@NL66278
Copy link
Contributor

NL66278 commented Sep 4, 2017

Somehow the names for the relations in the tab are shown including their ID. The id (and comma separator) should not be shown. I tried a screenprint, but github fails in the upload.

@NL66278
Copy link
Contributor

NL66278 commented Sep 4, 2017

If I add a relation on a tab, the inverse relation is somehow not created or never shown, on the connected relation.

@daramousk daramousk force-pushed the 10.0-#3963-partner-relation-in-tab-port branch from dde2489 to 8960d7d Compare September 5, 2017 13:10
@daramousk
Copy link
Member Author

@NL66278 The inverse relation is not shown probably because the following domain assembled and in place:

			<page string="name" attrs="{'invisible': ['|', ('id', '=', False), ('is_company', '=', False)]}" modifiers="{'invisible': ['|', ['id', '=', false], ['is_company', '=', false]]}">
				<field context="{'default_type_id': 1, 'default_left_partner_id': id, 'active_test': False}" name="relation_ids_own_tab_1_left" modifiers="{}"/>
			</page>

@NL66278
Copy link
Contributor

NL66278 commented Sep 11, 2017

@daramousk I found the problem with the inverse relation not showing up. The problem was limited to symmetrical relations. When a relation is symmetrical, some fields have to be the same for left and right. In the main module this is done here: https://github.com/OCA/partner-contact/blob/10.0/partner_multi_relation/models/res_partner_relation_type.py#L88 You have to override this method and fill own_tab_right with the value of own_tab_left.

@NL66278
Copy link
Contributor

NL66278 commented Sep 11, 2017

@daramousk One more thing: in the past we often had directories like model (singular), view (singular). This should really be models (plural) and views (plural).

@daramousk
Copy link
Member Author

@NL66278 Both implemented

def onchange_is_symmetric(self):
"""Set right side to left side if symmetric."""
if self.is_symmetric:
self.update({
Copy link
Contributor

Choose a reason for hiding this comment

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

Like always, first call super, then add just the update for own_tab_right. Who knows what other modules will add symmetrical fields?

@NL66278
Copy link
Contributor

NL66278 commented Sep 12, 2017

@daramousk So we are left with:

  • Rename of the module
  • Solving the issue of relations shown with not only their name, but also their id
  • The comment just made on symmetrical fields and calling super method

@daramousk
Copy link
Member Author

@NL66278 Implemented all of three points

@NL66278
Copy link
Contributor

NL66278 commented Sep 12, 2017

@daramousk On testing the symmetrical stuff still does not work. (Did you test it?) The error is already in the existing module partner_multi_relation:
When the field is_symmetric is changed, values are copied from left to right fields. Great. But after that the *_right fields should be kept synchronized with the *_left fields. This can most easily be done by a routine called from the create and write methods. If is_symmetric is in vals (and True), or if symmetric is not in vals, but true in the existing record, go through all the keys in vals ending in _left, and copy their values to _right.
As long as other modules keep the convention (maybe put a comment in the code) of putting _left and _right at the end of the field-names, this will work, and the onchange handler for is_symmetric want be needed any more.

@daramousk daramousk force-pushed the 10.0-#3963-partner-relation-in-tab-port branch 2 times, most recently from f84e871 to bd357c3 Compare September 13, 2017 15:10
@NL66278
Copy link
Contributor

NL66278 commented Sep 13, 2017

@daramousk The synchronization between left and right will in many cases not be done. If you have an existing record and just change the is_symmetric flag, the *_right fields will not be updated, because the *-left fields are not in vals. The easiest way to do this is to do the update after the super.write or second create. Normally I am a bit allergic for extra database actions, because this will result in a second update, or an update right after insert, but the frequency of these actions should be very low, and in programming it is much simpler.

This is a very good thing to put in a test case.

By the way the test_person_to_person_relation method contains also tests for company to person relations. Make separate test cases and give them appropiate names.

Succes!

@daramousk
Copy link
Member Author

@NL66278 Everything pushed here as well, with new changes to increase code coverage

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2014-2016 Therp BV <http://therp.nl>
# © 2017 Therp BV <http://therp.nl>
Copy link
Contributor

Choose a reason for hiding this comment

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

All the copyrights for existing files should be 2014-2017. Only the really new files should be 2017. Please check this everywhere.

res_partner_relation_type_model = self.env['res.partner.relation.type']
res_partner_relation_type_selection_model = self.env[
'res.partner.relation.type.selection']
p2p_rel = res_partner_relation_type_model.create(
Copy link
Contributor

Choose a reason for hiding this comment

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

Please for all create and write calls with multiple fields do:

some_model.create({
    'first_field': 'first_value',
    'second_field': 'second_value',
})

So put ( and { on one line,
then indent four spaces on all subsequent lines
then }) on last line.

@NL66278
Copy link
Contributor

NL66278 commented Sep 21, 2017

In the test for multiple relations in tabs I miss:

  1. A test to see if the new relation is in the special One2many field created
  2. A test to see if an existing type where you have own tab for the left and not for the right, if this changes after you change to is_symmetric.
    And please use the assertSomething methods to test if everything OK. If need be just assertTrue or assert False. Compare with existing unit tests.

@NL66278
Copy link
Contributor

NL66278 commented Sep 28, 2017

Copyright, now you changed the copyright date in a lot of files that do not have any other change. Please revert those, so the files do not show up in the Pull Request for nothing.

@NL66278
Copy link
Contributor

NL66278 commented Sep 28, 2017

And the test in the ..._tabs module fail. Please check and correct

@daramousk
Copy link
Member Author

@NL66278 Tests fixed. As for the changed files, all of them have been changed not only because of the dates but because they had long headers, see Holger's first comment.

@NL66278
Copy link
Contributor

NL66278 commented Sep 29, 2017

@daramousk Thanks a lot. Now squash all the commits into one and it would be ready to merge.

@daramousk daramousk force-pushed the 10.0-#3963-partner-relation-in-tab-port branch from 36b9450 to 3e9e327 Compare September 29, 2017 12:15
@daramousk
Copy link
Member Author

@NL66278 Squashed everything

Copy link
Contributor

@NL66278 NL66278 left a comment

Choose a reason for hiding this comment

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

👍 Tested and LGTM

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2013-2016 Therp BV <http://therp.nl>

Choose a reason for hiding this comment

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

Atomize these MRs make one for partner_multi_relation v10 and one for partner_multi_relation_in_tab v10.
Put on your second MR the note that it depends on partner_multi_relation being merged.

Copy link
Contributor

Choose a reason for hiding this comment

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

@gfcapalbo I do not see the need for this, as it is all part of one functional package.

Choose a reason for hiding this comment

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

ok.

'contact_type_right': self.contact_type_left,
'partner_category_right': self.partner_category_left,
})

Choose a reason for hiding this comment

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

What where the reasons to remove the onchange and replace it with a write/create overwrite ?

Copy link
Contributor

Choose a reason for hiding this comment

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

@gfcapalbo Using write/create means that values will be computed the correct way, even if relations inserted/modified through back-end. For instance on import.

name = vals.get('name')
if name:
right_vals['name_inverse'] = name
left_keys = filter(lambda key: key.endswith('_left'), vals.keys())
Copy link

@gfcapalbo gfcapalbo Oct 5, 2017

Choose a reason for hiding this comment

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

Obsessive check , but possible scenario
will cause problems if somebody has a field that ends with _left in vals other than the ones we want. filtering explicitly contact_type_left and partner_category_left looks safer.

Copy link
Contributor

Choose a reason for hiding this comment

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

@gfcapalbo Doing this in a generic way is needed to make sure that when extention modules add extra _left and _right fields, thses will be covered automatically. So this is quit intentional.

Choose a reason for hiding this comment

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

ok. i had forwarned it was obsessive,
Second proposal. modularize this in a function "_get_left_keys" where the extending modules can add their left keys and protect against my . albeit , rare scenario.

@api.multi
def write(self, vals):
"""Handle existing relations if conditions change."""
self.check_existing(vals)
is_symmetric = vals.get('is_symmetric')
if is_symmetric or self.is_symmetric and is_symmetric is not False:

Choose a reason for hiding this comment

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

this covers is_symmetric True or None in vals, Ok.

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-

Choose a reason for hiding this comment

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

Every MR should be for a single module, increases probability of merge. Divide it in two for the two modules

Choose a reason for hiding this comment

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

ignore. one functional package

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2013-2016 Therp BV <http://therp.nl>

Choose a reason for hiding this comment

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

ok.

name = vals.get('name')
if name:
right_vals['name_inverse'] = name
left_keys = filter(lambda key: key.endswith('_left'), vals.keys())

Choose a reason for hiding this comment

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

ok. i had forwarned it was obsessive,
Second proposal. modularize this in a function "_get_left_keys" where the extending modules can add their left keys and protect against my . albeit , rare scenario.

@NL66278
Copy link
Contributor

NL66278 commented Oct 6, 2017

I found a nasty bug in the override of fields_view_get of res_partner. You will need to cherrypick the commit added to this branch: https://github.com/nl66278/partner-contact/tree/10.0-partner_multi_relation_tabs-apimodel For some reason I cannot make a PR to your branch, The commit basically puts @api.model before the method declaration.

@daramousk daramousk force-pushed the 10.0-#3963-partner-relation-in-tab-port branch from 6127c35 to a343225 Compare October 6, 2017 14:43
@daramousk
Copy link
Member Author

@NL66278 Rebased and squashed

@NL66278
Copy link
Contributor

NL66278 commented Apr 13, 2018

@daramousk You might want to close this PR in favour of this one (building on your work): #498. Please review also.

@daramousk daramousk closed this Apr 18, 2018
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.

4 participants