Files
2026-03-14 09:42:12 +00:00

136 lines
4.8 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from stdnum import get_cc_module
try:
import phonenumbers
from phonenumbers import NumberParseException, PhoneNumberFormat
except ImportError:
phonenumbers = None
from trytond.i18n import gettext
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.tools import remove_forbidden_chars
from .exceptions import BadRequest
from .web import join_name, split_name
class Address(metaclass=PoolMeta):
__name__ = 'party.address'
vsf_telephone = fields.Many2One(
'party.contact_mechanism', "Telephone",
domain=[
('party', '=', Eval('party', -1)),
('type', 'in', ['phone', 'mobile']),
])
def get_vsf(self, for_party=None):
if for_party and for_party != self.party:
firstname, lastname = split_name(
self.party_name or for_party.name)
else:
firstname, lastname = split_name(
self.party_name or self.party.name)
address = {
'id': self.id,
'firstname': firstname,
'lastname': lastname,
'street': self.street.splitlines(),
'city': self.city,
'country_id': self.country.code if self.country else None,
'postcode': self.postal_code,
}
if self.subdivision:
address['region'] = {
'region': self.subdivision.name,
}
if self.vsf_telephone:
address['telephone'] = self.vsf_telephone.value
if for_party:
address['company'] = self.party.name
address['vat_id'] = (
self.party.tax_identifier.code
if self.party.tax_identifier else None)
return address
def set_vsf(self, data, for_party=None):
pool = Pool()
Country = pool.get('country.country')
Subdivision = pool.get('country.subdivision')
ContactMechanism = pool.get('party.contact_mechanism')
name = remove_forbidden_chars(
join_name(data['firstname'], data['lastname']))
party = for_party or self.party
if name != party.name:
self.party_name = name
self.street = '\n'.join(map(str, data['street']))
self.city = remove_forbidden_chars(data['city'])
if data['country_id']:
try:
self.country, = Country.search([
('code', '=', data['country_id']),
], limit=1)
except ValueError:
raise BadRequest(gettext(
'web_shop_vue_storefront.msg_unknown_country_code',
code=data['country_id']))
self.postal_code = data['postcode']
if data.get('region') and data['region']['region']:
domain = [
('name', '=', data['region']['region']),
]
if self.country:
domain.append(('country', '=', self.country.id))
subdivisions = Subdivision.search(domain, limit=1)
if subdivisions:
self.subdivision, = subdivisions
if data.get('telephone'):
value = remove_forbidden_chars(data['telephone'])
if phonenumbers:
try:
phonenumber = phonenumbers.parse(
data['telephone'], data['country_id'])
value = phonenumbers.format_number(
phonenumber, PhoneNumberFormat.INTERNATIONAL)
except NumberParseException:
pass
contacts = ContactMechanism.search([
('party', '=', self.party.id),
('type', 'in', ['phone', 'mobile']),
('value', '=', value),
], limit=1)
if contacts:
self.vsf_telephone, = contacts
else:
contact = ContactMechanism(
party=self.party,
type='phone',
value=value)
contact.save()
self.vsf_telephone = contact
class Identifier(metaclass=PoolMeta):
__name__ = 'party.identifier'
def set_vsf_tax_identifier(self, code):
pool = Pool()
Party = pool.get('party.party')
for type in Party.tax_identifier_types():
module = get_cc_module(*type.split('_', 1))
if module and module.is_valid(code):
self.type = type
self.code = code
break
else:
raise BadRequest(gettext(
'web_shop_vue_storefront.msg_invalid_tax_identifier',
code=code))