[MOV] partner_autocomplete: move pot from base_vat_autocomplete
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -1,20 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'VAT Number Autocomplete',
|
||||
'version': '1.0',
|
||||
'category': 'Accounting',
|
||||
'description': """
|
||||
Auto-Complete Addresses based on VAT numbers
|
||||
============================================
|
||||
|
||||
This module requires the python library stdnum to work.
|
||||
""",
|
||||
'depends': ['base_vat'],
|
||||
'data': [
|
||||
'views/res_partner_views.xml',
|
||||
'views/res_company_view.xml',
|
||||
],
|
||||
'auto_install': True
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import res_partner
|
||||
@@ -1,136 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
from suds.client import Client
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import stdnum.eu.vat as stdnum_vat
|
||||
if not hasattr(stdnum_vat, "country_codes"):
|
||||
# stdnum version >= 1.9
|
||||
stdnum_vat.country_codes = stdnum_vat._country_codes
|
||||
except ImportError:
|
||||
_logger.warning('Python `stdnum` library not found, unable to call VIES service to detect address based on VAT number.')
|
||||
stdnum_vat = None
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
@api.model
|
||||
def _get_partner_vals(self, vat):
|
||||
def _check_city(lines, country='BE'):
|
||||
if country == 'GB':
|
||||
ukzip = '[A-Z]{1,2}[0-9][0-9A-Z]?\s?[0-9][A-Z]{2}'
|
||||
if re.match(ukzip, lines[-1]):
|
||||
cp = lines.pop()
|
||||
city = lines.pop()
|
||||
return (cp, city)
|
||||
elif country == 'SE':
|
||||
result = re.match('([0-9]{3}\s?[0-9]{2})\s?([A-Z]+)', lines[-1])
|
||||
if result:
|
||||
lines.pop()
|
||||
return (result.group(1), result.group(2))
|
||||
else:
|
||||
result = re.match('((?:L-|AT-)?[0-9\-]+[A-Z]{,2}) (.+)', lines[-1])
|
||||
if result:
|
||||
lines.pop()
|
||||
return (result.group(1), result.group(2))
|
||||
return False
|
||||
|
||||
# Equivalent to stdnum_vat.check_vies(partner.vat).
|
||||
# However, we want to add a custom timeout to the suds.client
|
||||
# because by default, it's 120 seconds and this is to long.
|
||||
try:
|
||||
client = Client(stdnum_vat.vies_wsdl, timeout=5)
|
||||
partner_vat = stdnum_vat.compact(vat)
|
||||
result = client.service.checkVat(partner_vat[:2], partner_vat[2:])
|
||||
except:
|
||||
# Avoid blocking the client when the service is unreachable/unavailable
|
||||
return False, {}
|
||||
|
||||
if not result['valid']:
|
||||
return False, {}
|
||||
|
||||
partner_name = False
|
||||
partner_address = {}
|
||||
if result['name'] != '---':
|
||||
partner_name = result['name']
|
||||
|
||||
#parse the address from VIES and fill the partner's data
|
||||
if result['address'] == '---': return partner_name, {}
|
||||
|
||||
lines = [x for x in result['address'].split("\n") if x]
|
||||
if len(lines) == 1:
|
||||
lines = [x.strip() for x in lines[0].split(',') if x]
|
||||
if len(lines) == 1:
|
||||
lines = [x.strip() for x in lines[0].split(' ') if x]
|
||||
|
||||
vals = self._split_street_with_params(', '.join(lines.pop(0).rsplit(' ', 1)), '%(street_name)s, %(street_number)s/%(street_number2)s')
|
||||
partner_address.update(vals)
|
||||
|
||||
if len(lines) > 0:
|
||||
res = _check_city(lines, result['countryCode'])
|
||||
if res:
|
||||
partner_address['zip'] = res[0]
|
||||
partner_address['city'] = res[1]
|
||||
#_set_address_field(partner, 'zip', res[0])
|
||||
#_set_address_field(partner, 'city', res[1])
|
||||
if len(lines) > 0:
|
||||
partner_address['street2'] = lines.pop(0)
|
||||
#_set_address_field(partner, 'street2', lines.pop(0))
|
||||
|
||||
country = self.env['res.country'].search([('code', '=', result['countryCode'])], limit=1)
|
||||
|
||||
#_set_address_field(partner, 'country_id', country and country.id or False)
|
||||
partner_address['country_id'] = country and country.id or False
|
||||
return partner_name, partner_address
|
||||
|
||||
@api.onchange('vat')
|
||||
def vies_vat_change(self):
|
||||
if stdnum_vat is None:
|
||||
return {}
|
||||
|
||||
for partner in self:
|
||||
if not partner.vat:
|
||||
continue
|
||||
# If a field is not set in the response, wipe it anyway
|
||||
non_set_address_fields = set(['street', 'street2', 'city', 'zip', 'state_id', 'country_id'])
|
||||
if len(partner.vat) > 5 and partner.vat[:2].lower() in stdnum_vat.country_codes:
|
||||
partner_name, partner_address = self._get_partner_vals(partner.vat)
|
||||
|
||||
if not partner.name and partner_name:
|
||||
partner.name = partner_name
|
||||
|
||||
#set the address fields
|
||||
for field, value in partner_address.items():
|
||||
partner[field] = value
|
||||
non_set_address_fields.remove(field)
|
||||
for field in non_set_address_fields:
|
||||
if partner[field]:
|
||||
partner[field] = False
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
@api.onchange('vat')
|
||||
def vies_vat_change(self):
|
||||
self.ensure_one()
|
||||
company_address_fields = set(['street', 'street2', 'city', 'zip', 'state_id', 'country_id'])
|
||||
company_name, company_address = self.env['res.partner']._get_partner_vals(self.vat)
|
||||
if not self.name and company_name:
|
||||
self.name = company_name
|
||||
#set the address fields
|
||||
for field, value in company_address.items():
|
||||
self[field] = value
|
||||
company_address_fields.remove(field)
|
||||
for field in company_address_fields:
|
||||
if self[field]:
|
||||
self[field] = False
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
The purpose of this view is to move the VAT field at the top of the
|
||||
company form. That way, the user will fill it first
|
||||
-->
|
||||
<odoo>
|
||||
<record id="res_company_view_form" model="ir.ui.view">
|
||||
<field name="name">res.company.view.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='vat']" position="replace" />
|
||||
<field name="partner_id" position="after">
|
||||
<field name="vat" string="VAT"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_partner_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.vat.inherit</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='vat']" position="replace">
|
||||
</xpath>
|
||||
<xpath expr="//label[@for='street']" position="before">
|
||||
<field name="vat" string="VAT" placeholder="e.g. BE0477472701"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_partner_short_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.short.vat.inherit</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_short_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='vat']" position="replace">
|
||||
</xpath>
|
||||
<xpath expr="//label[@for='street']" position="before">
|
||||
<field name="vat" string="VAT" placeholder="e.g. BE0477472701"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user