diff --git a/partner_identification/README.rst b/partner_identification/README.rst index 3e896f647..680628d1f 100644 --- a/partner_identification/README.rst +++ b/partner_identification/README.rst @@ -7,11 +7,11 @@ Partner Identification Numbers ============================== This module allows to manage all sort of identification numbers -and certificates which are assigned to a partner and vary from country -to country. +and certificates which are assigned to a partner (company or individual) +and vary from country to country. * Commercial register -* VAT ID (eventually) +* VAT ID * Fiscal ID's * Membership numbers * Driver license @@ -21,7 +21,7 @@ to country. Installation ============ -Install this addon from Settings > Local Modules, as usual. +No specific installation step required Configuration @@ -30,9 +30,13 @@ Configuration Configure all ID types you need in Sales > Configuration > Address Book > Partner ID Categories. For example, we create a category 'Driver License': -* Name : Name of this ID type. For example, 'Driver License' -* Code : Code, abbreviation or acronym of this ID type. For example, 'driver_license' -* Python validation code: Optional python code called to validate ID numbers of this ID type. +Name: + Name of this ID type. For example, 'Driver License' +Code: + Code, abbreviation or acronym of this ID type. For example, 'driver_license' +Python validation code: + Optional python code called to validate ID numbers of this ID type. + Usage ===== @@ -40,12 +44,22 @@ Usage In partner form you will see another tab called 'ID Numbers'. You can add any IDs to this partner, defining: -* Category : ID type defined in configuration. For example, Driver License -* ID Number : The ID itself. For example, Driver License number of this person -* Issued by : Another partner, who issued this ID. For example, Traffic National Institution -* Valid from : Issued date. For example, date when person approved his driving exam, 21/10/2009 -* Valid until : Expiration date. For example, date when person needs to renew his driver license, 21/10/2019 -* Notes : Any further information related with this ID. For example, vehicle types this person can drive +Category: + ID type defined in configuration. For example, Driver License +ID Number: + The ID itself. For example, Driver License number of this person +Issued by: + Another partner, who issued this ID. For example, Traffic National Institution +Place of Issuance: + The place where the ID has been issued. For example the country for passports and visa +Valid from: + Issued date. For example, date when person approved his driving exam, 21/10/2009 +Valid until: + Expiration date. For example, date when person needs to renew his driver license, 21/10/2019 +Status: + ID status. For example new/to renew/expired +Notes: + Any further information related with this ID. For example, vehicle types this person can drive .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot @@ -55,8 +69,8 @@ any IDs to this partner, defining: Known issues / Roadmap ====================== -If you want to search a partner by ID you will use advance search form. -You can't search by issuer, valid dates, category or notes. +* If you want to search a partner by ID you will use advance search form. + You can't search by issuer, valid dates, category or notes. Bug Tracker @@ -71,6 +85,7 @@ partner_contact/issues/new?body=module:%20 partner_identifiers%0Aversion:%20 9.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. + Credits ======= @@ -98,4 +113,3 @@ promote its widespread use. To contribute to this module, please visit https://odoo-community.org. - diff --git a/partner_identification/__openerp__.py b/partner_identification/__openerp__.py index c4d588074..11c0f0d9e 100644 --- a/partner_identification/__openerp__.py +++ b/partner_identification/__openerp__.py @@ -9,18 +9,15 @@ # © 2016 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - # Addon information 'name': 'Partner Identification Numbers', 'category': 'Customer Relationship Management', 'version': '9.0.1.0.0', - # Views templates, pages, menus, options and snippets 'data': [ 'views/res_partner_id_category_view.xml', 'views/res_partner_id_number_view.xml', 'views/res_partner_view.xml', 'security/ir.model.access.csv', ], - # Your information 'author': 'ChriCar Beteiligungs- und Beratungs- GmbH, ' 'Antiun Ingeniería S.L.', 'Camptocamp,' @@ -29,5 +26,4 @@ 'website': 'https://odoo-community.org/', 'license': 'AGPL-3', 'installable': True, - } diff --git a/partner_identification/models/res_partner_id_category.py b/partner_identification/models/res_partner_id_category.py index 5804c3828..71508512e 100644 --- a/partner_identification/models/res_partner_id_category.py +++ b/partner_identification/models/res_partner_id_category.py @@ -20,19 +20,26 @@ class ResPartnerIdCategory(models.Model): _name = "res.partner.id_category" _order = "name" - code = fields.Char(string="Code", size=16, required=True) - name = fields.Char(string="ID name", required=True, translate=True) + def _default_validation_code(self): + return _("\n# Python code. Use failed = True to specify that the id " + "number is not valid.\n" + "# You can use the following variables :\n" + "# - self: browse_record of the current ID Category " + "browse_record\n" + "# - id_number: browse_record of ID number to validate") + + code = fields.Char( + string="Code", size=16, required=True, + help="Abbreviation or acronym of this ID type. For example, " + "'driver_license'") + name = fields.Char( + string="ID name", required=True, translate=True, + help="Name of this ID type. For example, 'Driver License'") active = fields.Boolean(string="Active", default=True) validation_code = fields.Text( 'Python validation code', help="Python code called to validate an id number.", - default=""" -# Python code. Use failed = True to . -# You can use the following variables : -# - self: browse_record of the current ID Category browse_record -# - id_number: browse_record of ID number to validte -""" - ) + default=_default_validation_code) @api.multi def _validation_eval_context(self, id_number): diff --git a/partner_identification/models/res_partner_id_number.py b/partner_identification/models/res_partner_id_number.py index bedc5f78e..2f0c621aa 100644 --- a/partner_identification/models/res_partner_id_number.py +++ b/partner_identification/models/res_partner_id_number.py @@ -16,20 +16,43 @@ class ResPartnerIdNumber(models.Model): _name = "res.partner.id_number" _order = "name" - @api.constrains('name') + @api.constrains('name', 'category_id') def validate_id_number(self): self.category_id.validate_id_number(self) - name = fields.Char(string="ID Number", required=True) - category_id = fields.Many2one(string="Category", required=True, - comodel_name='res.partner.id_category') + name = fields.Char( + string="ID Number", required=True, + help="The ID itself. For example, Driver License number of this " + "person") + category_id = fields.Many2one( + string="Category", required=True, + comodel_name='res.partner.id_category', + help="ID type defined in configuration. For example, Driver License") partner_id = fields.Many2one(string="Partner", required=True, comodel_name='res.partner') - partner_issued_id = fields.Many2one(string="Issued by", - comodel_name='res.partner') - date_issued = fields.Date(string="Issued on") - valid_from = fields.Date(string="Valid from") - valid_until = fields.Date(string="Valid until") + partner_issued_id = fields.Many2one( + string="Issued by", comodel_name='res.partner', + help="Another partner, who issued this ID. For example, Traffic " + "National Institution") + place_issuance = fields.Char( + string="Place of Issuance", + help="The place where the ID has been issued. For example the country " + "for passports and visa") + date_issued = fields.Date( + string="Issued on", + help="Issued date. For example, date when person approved his driving " + "exam, 21/10/2009") + valid_from = fields.Date( + string="Valid from", + help="Validation period stating date.") + valid_until = fields.Date( + string="Valid until", + help="Expiration date. For example, date when person needs to renew " + "his driver license, 21/10/2019") comment = fields.Text(string="Notes") - state = fields.Char(string="State", size=16) + status = fields.Selection( + [('draft', 'New'), + ('open', 'Running'), + ('pending', 'To Renew'), + ('close', 'Expired')]) active = fields.Boolean(string="Active", default=True) diff --git a/partner_identification/tests/test_partner_identification.py b/partner_identification/tests/test_partner_identification.py index 48d8dde40..d46a243c4 100644 --- a/partner_identification/tests/test_partner_identification.py +++ b/partner_identification/tests/test_partner_identification.py @@ -21,13 +21,13 @@ class TestPartnerIdentificationBase(common.TransactionCase): partner_1 = self.env.ref('base.res_partner_1') self.assertEquals(len(partner_1.id_numbers), 0) with self.assertRaises(IntegrityError), self.cr.savepoint(): - partner_1.id_numbers = [(0, 0, { + partner_1.write({'id_numbers': [(0, 0, { 'name': '1234', - })] - partner_1.id_numbers = [(0, 0, { + })]}) + partner_1.write({'id_numbers': [(0, 0, { 'name': '1234', - 'category_id': partner_id_category - })] + 'category_id': partner_id_category.id + })]}) self.assertEquals(len(partner_1.id_numbers), 1) self.assertEquals(partner_1.id_numbers.name, '1234') @@ -45,17 +45,31 @@ if id_number.name != '1234': }) partner_1 = self.env.ref('base.res_partner_1') with self.assertRaises(ValidationError), self.cr.savepoint(): - partner_1.id_numbers = [(0, 0, { + partner_1.write({'id_numbers': [(0, 0, { 'name': '01234', - 'category_id': partner_id_category - })] - partner_1.id_numbers = [(0, 0, { + 'category_id': partner_id_category.id + })]}) + partner_1.write({'id_numbers': [(0, 0, { 'name': '1234', - 'category_id': partner_id_category - })] + 'category_id': partner_id_category.id + })]}) self.assertEquals(len(partner_1.id_numbers), 1) self.assertEquals(partner_1.id_numbers.name, '1234') + partner_id_category2 = self.env['res.partner.id_category'].create({ + 'code': 'id_code2', + 'name': 'id_name2', + 'validation_code': """ +if id_number.name != '1235': + failed = True +"""}) + # check that the constrains is also checked when we change the + # associated category + with self.assertRaises(ValidationError), self.cr.savepoint(): + partner_1.id_numbers.write({ + 'category_id': partner_id_category2.id + }) + def test_bad_calidation_code(self): partner_id_category = self.env['res.partner.id_category'].create({ 'code': 'id_code', @@ -67,7 +81,7 @@ if id_number.name != '1234' # missing : }) partner_1 = self.env.ref('base.res_partner_1') with self.assertRaises(ValidationError): - partner_1.id_numbers = [(0, 0, { + partner_1.write({'id_numbers': [(0, 0, { 'name': '1234', - 'category_id': partner_id_category - })] + 'category_id': partner_id_category.id + })]}) diff --git a/partner_identification/views/res_partner_id_number_view.xml b/partner_identification/views/res_partner_id_number_view.xml index d3d0996ed..00f325ff8 100644 --- a/partner_identification/views/res_partner_id_number_view.xml +++ b/partner_identification/views/res_partner_id_number_view.xml @@ -13,8 +13,10 @@ + + @@ -34,6 +36,7 @@ +