Browse Source

Merge pull request #14 from eLBati/8.0

[ADD] partner_firstname for v8
pull/25/head
Holger Brunn 10 years ago
parent
commit
332ca70624
  1. 113
      __unported__/partner_firstname/tests/test_partner_firstname.py
  2. 19
      base_location/better_zip.py
  3. 16
      base_location/company.py
  4. 10
      base_location/partner.py
  5. 7
      base_location/state.py
  6. 4
      base_partner_merge/__openerp__.py
  7. 55
      base_partner_merge/validate_email.py
  8. 0
      partner_firstname/__init__.py
  9. 6
      partner_firstname/__openerp__.py
  10. 0
      partner_firstname/i18n/de.po
  11. 0
      partner_firstname/i18n/en.po
  12. 0
      partner_firstname/i18n/fr.po
  13. 0
      partner_firstname/i18n/nl.po
  14. 0
      partner_firstname/i18n/partner_firstname.pot
  15. 63
      partner_firstname/partner.py
  16. 0
      partner_firstname/partner_view.xml
  17. 7
      partner_firstname/res_user.py
  18. 0
      partner_firstname/res_user_view.xml
  19. 0
      partner_firstname/tests/__init__.py
  20. 153
      partner_firstname/tests/test_partner_firstname.py
  21. 30
      passport/tests/test_passport.py

113
__unported__/partner_firstname/tests/test_partner_firstname.py

@ -1,113 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Authors: Nemry Jonathan
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
# All Rights Reserved
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs.
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contact a Free Software
# Service Company.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import openerp.tests.common as common
from openerp.tools.translate import _
class test_partner_firstname(common.TransactionCase):
def setUp(self):
super(test_partner_firstname, self).setUp()
self.registry('ir.model').clear_caches()
self.registry('ir.model.data').clear_caches()
self.user_model = self.registry("res.users")
self.partner_model = self.registry("res.partner")
self.fields_partner = {'lastname': 'lastname', 'firstname': 'firstname'}
self.fields_user = {'name': 'lastname', 'login': 'v5Ue4Tql0Pm67KX05g25A'}
self.context = self.user_model.context_get(self.cr, self.uid)
def test_copy_partner(self):
cr, uid, context = self.cr, self.uid, self.context
res_id = self.partner_model.create(cr, uid, self.fields_partner, context=context)
res_id = self.partner_model.copy(cr, uid, res_id, default={}, context=context)
vals = self.partner_model.read(cr, uid, [res_id], ['name', 'lastname', 'firstname'], context=context)[0]
self.assertEqual(
vals['name'],
_('%s (copy)') % 'lastname' + " firstname",
'Copy of the partner failed with wrong name'
)
self.assertEqual(
vals['lastname'],
_('%s (copy)') % 'lastname',
'Copy of the partner failed with wrong lastname'
)
self.assertEqual(vals['firstname'], 'firstname', 'Copy of the partner failed with wrong firstname')
def test_copy_user(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(cr, uid, flds['partner_id'][0], {'firstname': 'firstname'}, context=context)
# copy the user and compare result
res_id = self.user_model.copy(cr, uid, res_id, default={}, context=context)
vals = self.user_model.read(cr, uid, [res_id], ['name', 'lastname', 'firstname'], context=context)[0]
self.assertEqual(
vals['name'],
_('%s (copy)') % 'lastname' + ' firstname',
'Copy of the user failed with wrong name'
)
self.assertEqual(vals['lastname'], _('%s (copy)') % 'lastname', 'Copy of the user failed with wrong lastname')
self.assertEqual(vals['firstname'], 'firstname', 'Copy of the user failed with wrong firstname')
def test_update_user_lastname(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(cr, uid, flds['partner_id'][0], {'firstname': 'firstname'}, context=context)
self.user_model.write(cr, uid, res_id, {'name': 'change firstname'}, context=context)
vals = self.user_model.read(cr, uid, [res_id], ['name', 'lastname', 'firstname'], context=context)[0]
self.assertEqual(vals['name'], 'change firstname', 'Update of the user lastname failed with wrong name')
self.assertEqual(vals['lastname'], 'change', 'Update of the user lastname failed with wrong lastname')
self.assertEqual(vals['firstname'], 'firstname', 'Update of the user lastname failed with wrong firstname')
def test_update_user_firstname(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(cr, uid, flds['partner_id'][0], {'firstname': 'firstname'}, context=context)
self.user_model.write(cr, uid, res_id, {'name': 'lastname other'}, context=context)
vals = self.user_model.read(cr, uid, [res_id], ['name', 'lastname', 'firstname'], context=context)[0]
self.assertEqual(vals['name'], 'lastname other', 'Update of the user firstname failed with wrong name')
self.assertEqual(vals['lastname'], 'lastname other', 'Update of the user firstname failed with wrong lastname')
self.assertFalse(vals['firstname'], 'Update of the user firstname failed with wrong firstname')

19
base_location/better_zip.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##############################################################################
#
# #
# Author: Nicolas Bessi. Copyright Camptocamp SA # Author: Nicolas Bessi. Copyright Camptocamp SA
# Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com> # Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com>
@ -18,11 +18,12 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
##############################################################################
#
from openerp.osv import orm, fields from openerp.osv import orm, fields
class BetterZip(orm.Model): class BetterZip(orm.Model):
" City/locations completion object" " City/locations completion object"
_name = "res.better.zip" _name = "res.better.zip"
@ -57,19 +58,25 @@ class BetterZip(orm.Model):
def onchange_state_id(self, cr, uid, ids, state_id=False, context=None): def onchange_state_id(self, cr, uid, ids, state_id=False, context=None):
result = {} result = {}
if state_id: if state_id:
state = self.pool['res.country.state'].browse(cr, uid, state_id, context=context)
state = self.pool['res.country.state'].browse(
cr, uid, state_id, context=context)
if state: if state:
result['value'] = {'country_id': state.country_id.id} result['value'] = {'country_id': state.country_id.id}
return result return result
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
def name_search(
self, cr, uid, name, args=None, operator='ilike', context=None,
limit=100
):
if args is None: if args is None:
args = [] args = []
if context is None: if context is None:
context = {} context = {}
ids = [] ids = []
if name: if name:
ids = self.search(cr, uid, [('name', 'ilike', name)] + args, limit=limit)
ids = self.search(
cr, uid, [('name', 'ilike', name)] + args, limit=limit)
if not ids: if not ids:
ids = self.search(cr, uid, [('city', operator, name)] + args, limit=limit)
ids = self.search(
cr, uid, [('city', operator, name)] + args, limit=limit)
return self.name_get(cr, uid, ids, context=context) return self.name_get(cr, uid, ids, context=context)

16
base_location/company.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##############################################################################
#
# #
# Author: Nicolas Bessi. Copyright Camptocamp SA # Author: Nicolas Bessi. Copyright Camptocamp SA
# Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com> # Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com>
@ -18,7 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
##############################################################################
#
from openerp.osv import orm, fields from openerp.osv import orm, fields
@ -31,8 +31,10 @@ class ResCompany(orm.Model):
if context is None: if context is None:
context = {} context = {}
if zip_id: if zip_id:
bzip = self.pool['res.better.zip'].browse(cr, uid, zip_id, context=context)
result = {'value': {'zip': bzip.name,
bzip = self.pool['res.better.zip'].browse(
cr, uid, zip_id, context=context)
result = {'value': {
'zip': bzip.name,
'country_id': bzip.country_id.id if bzip.country_id else False, 'country_id': bzip.country_id.id if bzip.country_id else False,
'city': bzip.city, 'city': bzip.city,
'state_id': bzip.state_id.id if bzip.state_id else False 'state_id': bzip.state_id.id if bzip.state_id else False
@ -41,7 +43,7 @@ class ResCompany(orm.Model):
return result return result
_columns = { _columns = {
'better_zip_id': fields.many2one('res.better.zip', 'Location', select=1,
help=('Use the city name or the zip code'
' to search the location')),
'better_zip_id': fields.many2one(
'res.better.zip', 'Location', select=1,
help=('Use the city name or the zip code to search the location')),
} }

10
base_location/partner.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##############################################################################
#
# #
# Author: Nicolas Bessi. Copyright Camptocamp SA # Author: Nicolas Bessi. Copyright Camptocamp SA
# Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com> # Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com>
@ -18,7 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
##############################################################################
#
from openerp.osv import orm, fields from openerp.osv import orm, fields
@ -31,8 +31,10 @@ class ResPartner(orm.Model):
return {} return {}
if isinstance(zip_id, list): if isinstance(zip_id, list):
zip_id = zip_id[0] zip_id = zip_id[0]
bzip = self.pool['res.better.zip'].browse(cursor, uid, zip_id, context=context)
return {'value': {'zip': bzip.name,
bzip = self.pool['res.better.zip'].browse(
cursor, uid, zip_id, context=context)
return {'value': {
'zip': bzip.name,
'city': bzip.city, 'city': bzip.city,
'country_id': bzip.country_id.id if bzip.country_id else False, 'country_id': bzip.country_id.id if bzip.country_id else False,
'state_id': bzip.state_id.id if bzip.state_id else False, 'state_id': bzip.state_id.id if bzip.state_id else False,

7
base_location/state.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##############################################################################
#
# #
# Author: Nicolas Bessi. Copyright Camptocamp SA # Author: Nicolas Bessi. Copyright Camptocamp SA
# Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com> # Contributor: Pedro Manuel Baeza <pedro.baeza@serviciosbaeza.com>
@ -18,7 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
##############################################################################
#
from openerp.osv import orm, fields from openerp.osv import orm, fields
@ -26,4 +26,5 @@ class ResCountryState(orm.Model):
_inherit = 'res.country.state' _inherit = 'res.country.state'
_columns = {'better_zip_ids': fields.one2many('res.better.zip', 'state_id', 'Cities')}
_columns = {'better_zip_ids': fields.one2many(
'res.better.zip', 'state_id', 'Cities')}

4
base_partner_merge/__openerp__.py

@ -3,7 +3,9 @@
'author': 'OpenERP S.A.', 'author': 'OpenERP S.A.',
'category': 'Generic Modules/Base', 'category': 'Generic Modules/Base',
'version': '0.1', 'version': '0.1',
'description': """backport module, to be removed when we switch to saas2 on the private servers""",
'description': """
backport module, to be removed when we switch to saas2 on the private servers
""",
'depends': [ 'depends': [
'base', 'base',
], ],

55
base_partner_merge/validate_email.py

@ -46,32 +46,47 @@ WSP = r'[ \t]' # see
CRLF = r'(?:\r\n)' # see 2.2.3. Long Header Fields CRLF = r'(?:\r\n)' # see 2.2.3. Long Header Fields
NO_WS_CTL = r'\x01-\x08\x0b\x0c\x0f-\x1f\x7f' # see 3.2.1. Primitive Tokens NO_WS_CTL = r'\x01-\x08\x0b\x0c\x0f-\x1f\x7f' # see 3.2.1. Primitive Tokens
QUOTED_PAIR = r'(?:\\.)' # see 3.2.2. Quoted characters QUOTED_PAIR = r'(?:\\.)' # see 3.2.2. Quoted characters
FWS = r'(?:(?:{0}*{1})?{0}+)'.format(WSP, CRLF) # see 3.2.3. Folding white space and comments
CTEXT = r'[{0}\x21-\x27\x2a-\x5b\x5d-\x7e]'.format(NO_WS_CTL) # see 3.2.3
# see 3.2.3 (NB: The RFC includes COMMENT here as well, but that would be circular.)
FWS = r'(?:(?:{0}*{1})?{0}+)'.format(WSP, CRLF)
# see 3.2.3. Folding white space and comments
CTEXT = r'[{0}\x21-\x27\x2a-\x5b\x5d-\x7e]'.format(
NO_WS_CTL) # see 3.2.3
# see 3.2.3 (NB: The RFC includes COMMENT here as well, but that would be
# circular.)
CCONTENT = r'(?:{0}|{1})'.format(CTEXT, QUOTED_PAIR) CCONTENT = r'(?:{0}|{1})'.format(CTEXT, QUOTED_PAIR)
COMMENT = r'\((?:{0}?{1})*{0}?\)'.format(FWS, CCONTENT) # see 3.2.3
CFWS = r'(?:{0}?{1})*(?:{0}?{1}|{0})'.format(FWS, COMMENT) # see 3.2.3
COMMENT = r'\((?:{0}?{1})*{0}?\)'.format(
FWS, CCONTENT) # see 3.2.3
CFWS = r'(?:{0}?{1})*(?:{0}?{1}|{0})'.format(
FWS, COMMENT) # see 3.2.3
ATEXT = r'[\w!#$%&\'\*\+\-/=\?\^`\{\|\}~]' # see 3.2.4. Atom ATEXT = r'[\w!#$%&\'\*\+\-/=\?\^`\{\|\}~]' # see 3.2.4. Atom
ATOM = r'{0}?{1}+{0}?'.format(CFWS, ATEXT) # see 3.2.4
DOT_ATOM_TEXT = r'{0}+(?:\.{0}+)*'.format(ATEXT) # see 3.2.4
DOT_ATOM = r'{0}?{1}{0}?'.format(CFWS, DOT_ATOM_TEXT) # see 3.2.4
QTEXT = r'[{0}\x21\x23-\x5b\x5d-\x7e]'.format(NO_WS_CTL) # see 3.2.5. Quoted strings
QCONTENT = r'(?:{0}|{1})'.format(QTEXT, QUOTED_PAIR) # see 3.2.5
ATOM = r'{0}?{1}+{0}?'.format(CFWS, ATEXT)
# see 3.2.4
DOT_ATOM_TEXT = r'{0}+(?:\.{0}+)*'.format(
ATEXT) # see 3.2.4
DOT_ATOM = r'{0}?{1}{0}?'.format(
CFWS, DOT_ATOM_TEXT) # see 3.2.4
QTEXT = r'[{0}\x21\x23-\x5b\x5d-\x7e]'.format(
NO_WS_CTL) # see 3.2.5. Quoted strings
QCONTENT = r'(?:{0}|{1})'.format(QTEXT, QUOTED_PAIR)
# see 3.2.5
QUOTED_STRING = r'{0}?"(?:{1}?{2})*{1}?"{0}?'.format(CFWS, FWS, QCONTENT) QUOTED_STRING = r'{0}?"(?:{1}?{2})*{1}?"{0}?'.format(CFWS, FWS, QCONTENT)
LOCAL_PART = r'(?:{0}|{1})'.format(DOT_ATOM, QUOTED_STRING) # see 3.4.1. Addr-spec specification
DTEXT = r'[{0}\x21-\x5a\x5e-\x7e]'.format(NO_WS_CTL) # see 3.4.1
DCONTENT = r'(?:{0}|{1})'.format(DTEXT, QUOTED_PAIR) # see 3.4.1
DOMAIN_LITERAL = r'{0}?\[(?:{1}?{2})*{1}?\]{0}?'.format(CFWS, FWS, DCONTENT) # see 3.4.1
DOMAIN = r'(?:{0}|{1})'.format(DOT_ATOM, DOMAIN_LITERAL) # see 3.4.1
ADDR_SPEC = r'{0}@{1}'.format(LOCAL_PART, DOMAIN) # see 3.4.1
LOCAL_PART = r'(?:{0}|{1})'.format(DOT_ATOM, QUOTED_STRING)
# see 3.4.1. Addr-spec specification
DTEXT = r'[{0}\x21-\x5a\x5e-\x7e]'.format(
NO_WS_CTL) # see 3.4.1
DCONTENT = r'(?:{0}|{1})'.format(DTEXT, QUOTED_PAIR)
# see 3.4.1
DOMAIN_LITERAL = r'{0}?\[(?:{1}?{2})*{1}?\]{0}?'.format(
CFWS, FWS, DCONTENT) # see 3.4.1
DOMAIN = r'(?:{0}|{1})'.format(DOT_ATOM, DOMAIN_LITERAL)
# see 3.4.1
ADDR_SPEC = r'{0}@{1}'.format(
LOCAL_PART, DOMAIN) # see 3.4.1
# A valid address will match exactly the 3.4.1 addr-spec. # A valid address will match exactly the 3.4.1 addr-spec.
VALID_ADDRESS_REGEXP = '^' + ADDR_SPEC + '$' VALID_ADDRESS_REGEXP = '^' + ADDR_SPEC + '$'
def validate_email(email, check_mx=False, verify=False): def validate_email(email, check_mx=False, verify=False):
"""Indicate whether the given string is a valid email address """Indicate whether the given string is a valid email address
according to the 'addr-spec' portion of RFC 2822 (see section according to the 'addr-spec' portion of RFC 2822 (see section
3.4.1). Parts of the spec that are marked obsolete are *not* 3.4.1). Parts of the spec that are marked obsolete are *not*
@ -104,7 +119,8 @@ def validate_email(email, check_mx=False, verify=False):
if status != 250: if status != 250:
return False return False
break break
except smtplib.SMTPServerDisconnected: # Server not permits verify user
except smtplib.SMTPServerDisconnected:
# Server not permits verify user
break break
except smtplib.SMTPConnectError: except smtplib.SMTPConnectError:
continue continue
@ -114,5 +130,6 @@ def validate_email(email, check_mx=False, verify=False):
# import sys # import sys
# sys.modules[__name__], sys.modules['validate_email_module'] = validate_email, sys.modules[__name__]
# sys.modules[__name__], sys.modules['validate_email_module'] = validate_email,
# sys.modules[__name__]
# from validate_email_module import * # from validate_email_module import *

0
__unported__/partner_firstname/__init__.py → partner_firstname/__init__.py

6
__unported__/partner_firstname/__openerp__.py → partner_firstname/__openerp__.py

@ -24,8 +24,10 @@
This module splits first name and last name for non company partners This module splits first name and last name for non company partners
==================================================================== ====================================================================
The field 'name' becomes a stored function field concatenating lastname and firstname
Note: in version 7.0, installing this module invalidates a yaml test in the 'edi' module
The field 'name' becomes a stored function field concatenating lastname and
firstname
Note: in version 7.0, installing this module invalidates a yaml test in the
'edi' module
Contributors Contributors
============ ============

0
__unported__/partner_firstname/i18n/de.po → partner_firstname/i18n/de.po

0
__unported__/partner_firstname/i18n/en.po → partner_firstname/i18n/en.po

0
__unported__/partner_firstname/i18n/fr.po → partner_firstname/i18n/fr.po

0
__unported__/partner_firstname/i18n/nl.po → partner_firstname/i18n/nl.po

0
__unported__/partner_firstname/i18n/partner_firstname.pot → partner_firstname/i18n/partner_firstname.pot

63
__unported__/partner_firstname/partner.py → partner_firstname/partner.py

@ -2,6 +2,7 @@
############################################################################## ##############################################################################
# #
# Author: Nicolas Bessi. Copyright Camptocamp SA # Author: Nicolas Bessi. Copyright Camptocamp SA
# Copyright (C) 2014 Agile Business Group (<http://www.agilebg.com>)
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -19,6 +20,9 @@
############################################################################## ##############################################################################
from openerp.osv import orm, fields from openerp.osv import orm, fields
from openerp.tools.translate import _ from openerp.tools.translate import _
import logging
_logger = logging.getLogger(__name__)
class ResPartner(orm.Model): class ResPartner(orm.Model):
@ -26,14 +30,17 @@ class ResPartner(orm.Model):
_inherit = 'res.partner' _inherit = 'res.partner'
def init(self, cursor):
cursor.execute('SELECT id FROM res_partner WHERE lastname IS NOT NULL Limit 1')
if not cursor.fetchone():
cursor.execute('UPDATE res_partner set lastname = name WHERE name IS NOT NULL')
# Create Sql constraint if table is not empty
cursor.execute('SELECT id FROM res_partner Limit 1')
if cursor.fetchone():
cursor.execute('ALTER TABLE res_partner ALTER COLUMN lastname SET NOT NULL')
def _set_default_value_on_column(self, cr, column_name, context=None):
res = super(ResPartner, self)._set_default_value_on_column(
cr, column_name, context=context)
if column_name == 'lastname':
cr.execute('UPDATE res_partner SET lastname = name WHERE name '
'IS NOT NULL AND lastname IS NULL')
cr.execute('ALTER TABLE res_partner ALTER COLUMN lastname '
'SET NOT NULL')
_logger.info("NOT NULL constraint for "
"res_partner.lastname correctly set")
return res
def _prepare_name_custom(self, cursor, uid, partner, context=None): def _prepare_name_custom(self, cursor, uid, partner, context=None):
""" """
@ -50,18 +57,26 @@ class ResPartner(orm.Model):
cursor, uid, partner, context=context) cursor, uid, partner, context=context)
return res return res
def _write_name(self, cursor, uid, partner_id, field_name, field_value, arg, context=None):
def _write_name(
self, cursor, uid, partner_id, field_name, field_value, arg,
context=None
):
""" """
Try to reverse the effect of _compute_name_custom: Try to reverse the effect of _compute_name_custom:
* if the partner is not a company and the firstname does not change in the new name
then firstname remains untouched and lastname is updated accordingly
* if the partner is not a company and the firstname does not change in
the new name then firstname remains untouched and lastname is updated
accordingly
* otherwise lastname=new name and firstname=False * otherwise lastname=new name and firstname=False
In addition an heuristic avoids to keep a firstname without a non-blank lastname
In addition an heuristic avoids to keep a firstname without a non-blank
lastname
""" """
field_value = field_value and not field_value.isspace() and field_value or False
field_value = (
field_value and not field_value.isspace() and field_value or False)
vals = {'lastname': field_value, 'firstname': False} vals = {'lastname': field_value, 'firstname': False}
if field_value: if field_value:
flds = self.read(cursor, uid, [partner_id], ['firstname', 'is_company'], context=context)[0]
flds = self.read(
cursor, uid, [partner_id], ['firstname', 'is_company'],
context=context)[0]
if not flds['is_company']: if not flds['is_company']:
to_check = ' %s' % flds['firstname'] to_check = ' %s' % flds['firstname']
if field_value.endswith(to_check): if field_value.endswith(to_check):
@ -78,31 +93,37 @@ class ResPartner(orm.Model):
def copy_data(self, cr, uid, _id, default=None, context=None): def copy_data(self, cr, uid, _id, default=None, context=None):
""" """
Avoid to replicate the firstname into the name when duplicating a partner
Avoid to replicate the firstname into the name when duplicating a
partner
""" """
default = default or {} default = default or {}
if not default.get('lastname'): if not default.get('lastname'):
default = default.copy() default = default.copy()
default['lastname'] = ( default['lastname'] = (
_('%s (copy)') % self.read(cr, uid, [_id], ['lastname'], context=context)[0]['lastname']
_('%s (copy)') % self.read(
cr, uid, [_id], ['lastname'], context=context
)[0]['lastname']
) )
if default.get('name'): if default.get('name'):
del(default['name']) del(default['name'])
return super(ResPartner, self).copy_data(cr, uid, _id, default, context=context)
return super(ResPartner, self).copy_data(
cr, uid, _id, default, context=context)
def create(self, cursor, uid, vals, context=None): def create(self, cursor, uid, vals, context=None):
""" """
To support data backward compatibility we have to keep this overwrite even if we
use fnct_inv: otherwise we can't create entry because lastname is mandatory and module
will not install if there is demo data
To support data backward compatibility we have to keep this overwrite
even if we use fnct_inv: otherwise we can't create entry because
lastname is mandatory and module will not install if there is demo data
""" """
to_use = vals to_use = vals
if 'name' in vals: if 'name' in vals:
corr_vals = vals.copy() corr_vals = vals.copy()
if vals.get('name'):
corr_vals['lastname'] = corr_vals['name'] corr_vals['lastname'] = corr_vals['name']
del(corr_vals['name']) del(corr_vals['name'])
to_use = corr_vals to_use = corr_vals
return super(ResPartner, self).create(cursor, uid, to_use, context=context)
return super(ResPartner, self).create(
cursor, uid, to_use, context=context)
_columns = {'name': fields.function(_compute_name_custom, string="Name", _columns = {'name': fields.function(_compute_name_custom, string="Name",
type="char", store=True, type="char", store=True,

0
__unported__/partner_firstname/partner_view.xml → partner_firstname/partner_view.xml

7
__unported__/partner_firstname/res_user.py → partner_firstname/res_user.py

@ -33,8 +33,11 @@ class ResUsers(orm.Model):
if not default.get('lastname'): if not default.get('lastname'):
default = default.copy() default = default.copy()
default['lastname'] = ( default['lastname'] = (
_('%s (copy)') % self.read(cr, uid, [_id], ['lastname'], context=context)[0]['lastname']
_('%s (copy)') % self.read(
cr, uid, [_id], ['lastname'], context=context
)[0]['lastname']
) )
if default.get('name'): if default.get('name'):
del(default['name']) del(default['name'])
return super(ResUsers, self).copy_data(cr, uid, _id, default, context=context)
return super(ResUsers, self).copy_data(
cr, uid, _id, default, context=context)

0
__unported__/partner_firstname/res_user_view.xml → partner_firstname/res_user_view.xml

0
__unported__/partner_firstname/tests/__init__.py → partner_firstname/tests/__init__.py

153
partner_firstname/tests/test_partner_firstname.py

@ -0,0 +1,153 @@
# -*- coding: utf-8 -*-
#
#
# Authors: Nemry Jonathan
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
# All Rights Reserved
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs.
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contact a Free Software
# Service Company.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
import openerp.tests.common as common
from openerp.tools.translate import _
class test_partner_firstname(common.TransactionCase):
def setUp(self):
super(test_partner_firstname, self).setUp()
self.registry('ir.model').clear_caches()
self.registry('ir.model.data').clear_caches()
self.user_model = self.registry("res.users")
self.partner_model = self.registry("res.partner")
self.fields_partner = {
'lastname': 'lastname', 'firstname': 'firstname'}
self.fields_user = {
'name': 'lastname', 'login': 'v5Ue4Tql0Pm67KX05g25A'}
self.context = self.user_model.context_get(self.cr, self.uid)
def test_copy_partner(self):
cr, uid, context = self.cr, self.uid, self.context
res_id = self.partner_model.create(
cr, uid, self.fields_partner, context=context)
res_id = self.partner_model.copy(
cr, uid, res_id, default={}, context=context)
vals = self.partner_model.read(cr, uid, [res_id], [
'name', 'lastname', 'firstname'], context=context)[0]
self.assertEqual(
vals['name'],
_('%s (copy)') % 'lastname' + " firstname",
'Copy of the partner failed with wrong name'
)
self.assertEqual(
vals['lastname'],
_('%s (copy)') % 'lastname',
'Copy of the partner failed with wrong lastname'
)
self.assertEqual(vals['firstname'], 'firstname',
'Copy of the partner failed with wrong firstname')
def test_copy_user(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(
cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(
cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(cr, uid, flds['partner_id'][
0], {'firstname': 'firstname'}, context=context)
# copy the user and compare result
res_id = self.user_model.copy(
cr, uid, res_id, default={}, context=context)
vals = self.user_model.read(
cr, uid, [res_id], ['name', 'lastname', 'firstname'],
context=context)[0]
self.assertEqual(
vals['name'],
_('%s (copy)') % 'lastname' + ' firstname',
'Copy of the user failed with wrong name'
)
self.assertEqual(
vals['lastname'], _('%s (copy)') %
'lastname', 'Copy of the user failed with wrong lastname')
self.assertEqual(vals['firstname'], 'firstname',
'Copy of the user failed with wrong firstname')
def test_update_user_lastname(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(
cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(
cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(
cr, uid, flds['partner_id'][0], {'firstname': 'firstname'},
context=context)
self.user_model.write(
cr, uid, res_id, {'name': 'change firstname'}, context=context)
vals = self.user_model.read(
cr, uid, [res_id], ['name', 'lastname', 'firstname'],
context=context)[0]
self.assertEqual(vals['name'], 'change firstname',
'Update of the user lastname failed with wrong name')
self.assertEqual(
vals['lastname'], 'change',
'Update of the user lastname failed with wrong lastname')
self.assertEqual(
vals['firstname'], 'firstname',
'Update of the user lastname failed with wrong firstname')
def test_update_user_firstname(self):
cr, uid, context = self.cr, self.uid, self.context
# create a user
res_id = self.user_model.create(
cr, uid, self.fields_user, context=context)
# get the related partner id and add it a firstname
flds = self.user_model.read(
cr, uid, [res_id], ['partner_id'], context=context)[0]
self.partner_model.write(
cr, uid, flds['partner_id'][0], {'firstname': 'firstname'},
context=context)
self.user_model.write(
cr, uid, res_id, {'name': 'lastname other'}, context=context)
vals = self.user_model.read(
cr, uid, [res_id], ['name', 'lastname', 'firstname'],
context=context)[0]
self.assertEqual(
vals['name'], 'lastname other',
'Update of the user firstname failed with wrong name')
self.assertEqual(
vals['lastname'], 'lastname other',
'Update of the user firstname failed with wrong lastname')
self.assertFalse(
vals['firstname'],
'Update of the user firstname failed with wrong firstname')

30
passport/tests/test_passport.py

@ -1,5 +1,5 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
##############################################################################
#
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
# This module copyright (C) 2013 Savoir-faire Linux # This module copyright (C) 2013 Savoir-faire Linux
@ -18,7 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
##############################################################################
#
from openerp.tests.common import TransactionCase from openerp.tests.common import TransactionCase
from openerp.models import BaseModel from openerp.models import BaseModel
@ -26,6 +26,7 @@ from datetime import date
class Base_Test_passport(TransactionCase): class Base_Test_passport(TransactionCase):
""" """
Simple test creating a passport Simple test creating a passport
This is a base class for passport test cases. This is a base class for passport test cases.
@ -49,14 +50,16 @@ class Base_Test_passport(TransactionCase):
self.vals = dict(self.vals.items() + vals.items()) self.vals = dict(self.vals.items() + vals.items())
# Create the passport object; we will be testing this, so store in self # Create the passport object; we will be testing this, so store in self
res_passport = self.registry('res.passport') res_passport = self.registry('res.passport')
self.passport_id = res_passport.create(self.cr, self.uid, self.vals, context=None)
self.passport_id = res_passport.create(
self.cr, self.uid, self.vals, context=None)
def test_passport(self): def test_passport(self):
""" """
Checking the passport creation. Checking the passport creation.
""" """
res_passport = self.registry('res.passport') res_passport = self.registry('res.passport')
passport_obj = res_passport.browse(self.cr, self.uid, self.passport_id, context=None)
passport_obj = res_passport.browse(
self.cr, self.uid, self.passport_id, context=None)
for field in self.vals: for field in self.vals:
val = passport_obj[field] val = passport_obj[field]
if isinstance(val, BaseModel): if isinstance(val, BaseModel):
@ -70,9 +73,11 @@ class Base_Test_passport(TransactionCase):
class Test_passport_bad(Base_Test_passport): class Test_passport_bad(Base_Test_passport):
""" """
Simple test creating a passport, test against bad values Simple test creating a passport, test against bad values
""" """
def setUp(self): def setUp(self):
""" """
Setting up passport, then changing the values to test against. Setting up passport, then changing the values to test against.
@ -93,7 +98,8 @@ class Test_passport_bad(Base_Test_passport):
Checking the passport creation, assertions should all be false. Checking the passport creation, assertions should all be false.
""" """
res_passport = self.registry('res.passport') res_passport = self.registry('res.passport')
passport_obj = res_passport.browse(self.cr, self.uid, self.passport_id, context=None)
passport_obj = res_passport.browse(
self.cr, self.uid, self.passport_id, context=None)
for field in self.vals: for field in self.vals:
val = passport_obj[field] val = passport_obj[field]
if isinstance(val, BaseModel): if isinstance(val, BaseModel):
@ -107,9 +113,11 @@ class Test_passport_bad(Base_Test_passport):
class Test_passport_name_get(TransactionCase): class Test_passport_name_get(TransactionCase):
""" """
Test name_get Test name_get
""" """
def setUp(self): def setUp(self):
""" """
Setting up passport with name, country, either and none. Setting up passport with name, country, either and none.
@ -139,10 +147,14 @@ class Test_passport_name_get(TransactionCase):
Checking the passport creation, assertions should all be false. Checking the passport creation, assertions should all be false.
""" """
res_passport = self.registry('res.passport') res_passport = self.registry('res.passport')
both_obj = res_passport.browse(self.cr, self.uid, self.both, context=None)
name_only = res_passport.browse(self.cr, self.uid, self.name_only, context=None)
country_only = res_passport.browse(self.cr, self.uid, self.country_only, context=None)
neither = res_passport.browse(self.cr, self.uid, self.neither, context=None)
both_obj = res_passport.browse(
self.cr, self.uid, self.both, context=None)
name_only = res_passport.browse(
self.cr, self.uid, self.name_only, context=None)
country_only = res_passport.browse(
self.cr, self.uid, self.country_only, context=None)
neither = res_passport.browse(
self.cr, self.uid, self.neither, context=None)
self.assertEquals( self.assertEquals(
both_obj.name_get()[0][1], both_obj.name_get()[0][1],
' | '.join((self.country_name, self.name_on_passport)), ' | '.join((self.country_name, self.name_on_passport)),

Loading…
Cancel
Save