10 changed files with 318 additions and 0 deletions
-
73partner_contact_vat/README.rst
-
5partner_contact_vat/__init__.py
-
23partner_contact_vat/__openerp__.py
-
42partner_contact_vat/i18n/es.po
-
5partner_contact_vat/models/__init__.py
-
51partner_contact_vat/models/res_partner.py
-
BINpartner_contact_vat/static/description/icon.png
-
5partner_contact_vat/tests/__init__.py
-
54partner_contact_vat/tests/test_validation.py
-
60partner_contact_vat/view/res_partner.xml
@ -0,0 +1,73 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
======================= |
|||
VAT in contact partners |
|||
======================= |
|||
|
|||
This module was written to extend the functionality of contacts management to |
|||
support setting a VAT in contact partners (those partners that are not not |
|||
companies) and allow you to have separate VAT codes for contact and for their |
|||
company. |
|||
|
|||
Odoo by default only allows VAT in companies. When a contact belongs to a |
|||
company and you go to *accounting* page, it shows *Accounting is managed in the |
|||
parent company*. |
|||
|
|||
If you manage any kind of personal information of your clients (prevention of |
|||
occupational hazards, training, event assistants, legal stuff, etc.) you |
|||
probably need their VAT. |
|||
|
|||
Indeed the company VAT will still be used for invoices and other legal |
|||
documents, but for other things you need the person's. For that reason, instead |
|||
of overwriting the VAT field, this module just adds a new one that will be |
|||
hidden for companies. |
|||
|
|||
You will not be able to save a contact VAT with an invalid format. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module, you need to: |
|||
|
|||
* Go to any contact's form. |
|||
* Enter its *personal information* page. |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/134/8.0 |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/ |
|||
partner-contact/issues>`_. In case of trouble, please check there if your issue |
|||
has already been reported. If you spotted it first, help us smashing it by |
|||
providing a detailed and welcomed feedback `here <https://github.com/OCA/ |
|||
partner-contact/issues/new?body=module:%20 |
|||
partner_contact_vat%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
|||
|
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Jairo Llopis <j.llopis@grupoesoc.es> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use. |
|||
|
|||
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import models |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
{ |
|||
"name": "VAT in contact partners", |
|||
"summary": "Allow to set up VAT for contacts", |
|||
"version": "8.0.1.0.0", |
|||
"category": "Accounting & Finance", |
|||
"website": "https://grupoesoc.es", |
|||
"author": "Grupo ESOC Ingeniería de servicios, " |
|||
"Odoo Community Association (OCA)", |
|||
"license": "AGPL-3", |
|||
"application": False, |
|||
"installable": True, |
|||
"depends": [ |
|||
"base_vat", |
|||
"partner_contact_personal_information_page", |
|||
], |
|||
"data": [ |
|||
"view/res_partner.xml", |
|||
], |
|||
} |
@ -0,0 +1,42 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * partner_contact_vat |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 7.0-20140804-231303\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2014-08-08 09:55+0000\n" |
|||
"PO-Revision-Date: 2014-08-08 11:58+0100\n" |
|||
"Last-Translator: Jairo Llopis <yajo.sk8@gmail.com>\n" |
|||
"Language-Team: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"X-Generator: Poedit 1.5.4\n" |
|||
"Language: es\n" |
|||
|
|||
#. module: partner_contact_vat |
|||
#: model:ir.model,name:partner_contact_vat.model_res_partner |
|||
msgid "Partner" |
|||
msgstr "Empresa" |
|||
|
|||
#. module: partner_contact_vat |
|||
#: help:res.partner,contact_vat:0 |
|||
msgid "" |
|||
"Tax Identification Number of the contact. This will not be used for " |
|||
"commercial actions; instead, parent company's TIN will be used." |
|||
msgstr "" |
|||
"Número de Identificación Fiscal del contacto. Este código no se usará para " |
|||
"acciones comerciales; en su lugar, se usará el NIF de la empresa a la que " |
|||
"pertenece el contacto." |
|||
|
|||
#. module: partner_contact_vat |
|||
#: field:res.partner,contact_vat:0 |
|||
msgid "Contact TIN" |
|||
msgstr "NIF del contacto" |
|||
|
|||
#. module: partner_contact_vat |
|||
#: view:res.partner:0 |
|||
msgid "e.g. BE0477472701" |
|||
msgstr "Por ejemplo, ESA00000000" |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import res_partner |
@ -0,0 +1,51 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
import string |
|||
from openerp import _, api, exceptions, fields, models |
|||
from openerp.addons.base_vat.base_vat import _ref_vat |
|||
|
|||
|
|||
class PartnerVATInContacts(models.Model): |
|||
"""Allow to set up individual VAT for a company's contacts.""" |
|||
_inherit = "res.partner" |
|||
|
|||
contact_vat = fields.Char( |
|||
"Contact TIN", |
|||
size=32, |
|||
help="Tax Identification Number of the contact. " |
|||
"This will not be used for commercial actions; " |
|||
"instead, parent company's TIN will be used.") |
|||
|
|||
@api.multi |
|||
@api.constrains("is_company", "contact_vat") |
|||
def contact_vat_check(self): |
|||
"""Check validity of `contact_vat`. |
|||
|
|||
It does not use VIES because usually it would fail when checking |
|||
persons' VAT codes. |
|||
""" |
|||
for s in self.filtered(lambda r: not r.is_company and r.contact_vat): |
|||
country, code = s._split_vat(s.contact_vat) |
|||
values = { |
|||
"vat": s.contact_vat, |
|||
"name": s.display_name, |
|||
} |
|||
|
|||
# VAT should start with 2 letters |
|||
if any(char not in string.ascii_lowercase for char in country): |
|||
raise exceptions.ValidationError( |
|||
_("VAT %(vat)s of %(name)s should start with " |
|||
"2 letters that indicate the country code.") % values) |
|||
|
|||
# Use core methods for VAT checking |
|||
elif not s.simple_vat_check(country, code): |
|||
# Display a useful message to user |
|||
values["template"] = ( |
|||
_ref_vat.get(country) or |
|||
_("CCNNNNNNNNN (CC=Country Code of 2 letters, " |
|||
"NNN... Local VAT number).")) |
|||
raise exceptions.ValidationError( |
|||
_("VAT %(vat)s of %(name)s has a wrong format. " |
|||
"It should be similar to %(template)s") % values) |
After Width: 100 | Height: 100 | Size: 18 KiB |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import test_validation |
@ -0,0 +1,54 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from openerp.tests.common import TransactionCase |
|||
from openerp.addons.base_vat.base_vat import _ref_vat |
|||
from openerp import exceptions as ex |
|||
|
|||
|
|||
class CommonCase(TransactionCase): |
|||
"""Test common cases, independent to the country of the VAT code.""" |
|||
def setUp(self): |
|||
super(CommonCase, self).setUp() |
|||
|
|||
self.partner = self.env["res.partner"].create({ |
|||
"name": __file__, |
|||
"is_company": False, |
|||
}) |
|||
|
|||
def test_empty(self): |
|||
"""Remove a VAT from a contact.""" |
|||
# First, set a good VAT to have no errors |
|||
self.partner.contact_vat = "ES00000001R" |
|||
|
|||
# Then remove it |
|||
self.partner.contact_vat = False |
|||
|
|||
# Nothing special should happen |
|||
self.assertEqual(self.partner.contact_vat, False) |
|||
|
|||
def test_company_to_partner(self): |
|||
"""Set a wrong contact VAT to a company and convert it to person.""" |
|||
self.partner.is_company = True |
|||
|
|||
# Set a wrong contact_vat, but no errors because it is a company |
|||
self.partner.contact_vat = "ES00000001W" |
|||
|
|||
# Now say it's a person |
|||
with self.assertRaises(ex.ValidationError): |
|||
self.partner.is_company = False |
|||
|
|||
def test_vat_without_country_code(self): |
|||
"""Set a VAT without the country code prefix.""" |
|||
with self.assertRaises(ex.ValidationError): |
|||
self.partner.contact_vat = "00000001R" |
|||
|
|||
def test_wrong_format_hint(self): |
|||
"""Ensure the format hint is given to user.""" |
|||
try: |
|||
# Set a wrong VAT |
|||
self.partner.with_context(lang="en_US").contact_vat = "ES00000001W" |
|||
except ex.ValidationError as error: |
|||
self.assertIn(_ref_vat.get("es"), error.value) |
|||
self.assertEqual(error.value, error.args[1]) |
@ -0,0 +1,60 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- © 2015 Grupo ESOC Ingeniería de servicios, S.L. - Jairo Llopis |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> |
|||
|
|||
<openerp> |
|||
<data> |
|||
|
|||
<record id="partner_form" model="ir.ui.view"> |
|||
<field name="name">VAT for contacts</field> |
|||
<field name="model">res.partner</field> |
|||
<field name="inherit_id" ref="partner_contact_personal_information_page.personal_information"/> |
|||
<field name="arch" type="xml"> |
|||
<data> |
|||
<!-- Accounting page --> |
|||
<xpath expr="//group[@name='personal_information_group']"> |
|||
<group> |
|||
<label for="contact_vat"/> |
|||
<div name="contact_vat_main"> |
|||
<field |
|||
name="contact_vat" |
|||
placeholder="e.g. BE0477472701" |
|||
class="oe_inline"/> |
|||
<button |
|||
colspan="2" |
|||
name="contact_vat_check" |
|||
string="Check Validity" |
|||
type="object" |
|||
icon="gtk-execute" |
|||
class="oe_inline"/> |
|||
</div> |
|||
</group> |
|||
</xpath> |
|||
|
|||
<!-- Contacts subform --> |
|||
<xpath expr="//page[@string='Contacts'] |
|||
//form[@string='Contact'] |
|||
//field[@name='mobile']" |
|||
position="after"> |
|||
<label for="contact_vat"/> |
|||
<div name="contact_vat_subform"> |
|||
<field |
|||
name="contact_vat" |
|||
placeholder="e.g. BE0477472701" |
|||
class="oe_inline"/> |
|||
<button |
|||
colspan="2" |
|||
name="contact_vat_check" |
|||
string="Check Validity" |
|||
type="object" |
|||
icon="gtk-execute" |
|||
class="oe_inline"/> |
|||
</div> |
|||
</xpath> |
|||
</data> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue