first commit
This commit is contained in:
187
modules/web_shop_shopify/party.py
Normal file
187
modules/web_shop_shopify/party.py
Normal file
@@ -0,0 +1,187 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import logging
|
||||
|
||||
from trytond.model import sequence_reorder
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.tools import remove_forbidden_chars
|
||||
from trytond.tools.email_ import EmailNotValidError, validate_email
|
||||
|
||||
from .common import IdentifiersMixin, gid2id, setattr_changed
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Party(IdentifiersMixin, metaclass=PoolMeta):
|
||||
__name__ = 'party.party'
|
||||
|
||||
@classmethod
|
||||
def shopify_fields(cls):
|
||||
return {
|
||||
'id': None,
|
||||
'displayName': None,
|
||||
'email': None,
|
||||
'phone': None,
|
||||
'locale': None,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_from_shopify(cls, shop, customer):
|
||||
pool = Pool()
|
||||
ContactMechanism = pool.get('party.contact_mechanism')
|
||||
Lang = pool.get('ir.lang')
|
||||
party = cls.search_shopify_identifier(
|
||||
shop, gid2id(customer['id']))
|
||||
if not party:
|
||||
party = cls()
|
||||
setattr_changed(party, 'name', remove_forbidden_chars(
|
||||
customer['displayName']))
|
||||
if customer['locale']:
|
||||
lang = Lang.get(customer['locale'])
|
||||
else:
|
||||
lang = None
|
||||
setattr_changed(party, 'lang', lang)
|
||||
contact_mechanisms = list(getattr(party, 'contact_mechanisms', []))
|
||||
for types, value in [
|
||||
(['email'], customer['email']),
|
||||
(['phone', 'mobile'], customer['phone']),
|
||||
]:
|
||||
value = remove_forbidden_chars(value)
|
||||
if not value:
|
||||
continue
|
||||
index = len(contact_mechanisms)
|
||||
for i, contact_mechanism in enumerate(contact_mechanisms):
|
||||
if (contact_mechanism.type in types
|
||||
and not contact_mechanism.address):
|
||||
index = min(i, index)
|
||||
if (contact_mechanism.value_compact
|
||||
== contact_mechanism.format_value_compact(
|
||||
value, contact_mechanism.type)):
|
||||
contact_mechanisms.insert(
|
||||
index,
|
||||
contact_mechanisms.pop(i))
|
||||
break
|
||||
else:
|
||||
if types[0] == 'email':
|
||||
try:
|
||||
validate_email(value)
|
||||
except EmailNotValidError as e:
|
||||
logger.info("Skip email %s", value, exc_info=e)
|
||||
continue
|
||||
contact_mechanisms.insert(index, ContactMechanism(
|
||||
type=types[0], value=value))
|
||||
party.contact_mechanisms = sequence_reorder(contact_mechanisms)
|
||||
# TODO tax_exempt
|
||||
return party
|
||||
|
||||
def get_address_from_shopify(self, shopify_address):
|
||||
pool = Pool()
|
||||
Address = pool.get('party.address')
|
||||
ContactMechanism = pool.get('party.contact_mechanism')
|
||||
shopify_values = Address.get_shopify_values(shopify_address)
|
||||
for address in self.addresses:
|
||||
if address.shopify_values() == shopify_values:
|
||||
break
|
||||
else:
|
||||
address = Address(**shopify_values)
|
||||
address.party = self
|
||||
address.save()
|
||||
|
||||
contact_mechanisms = list(self.contact_mechanisms)
|
||||
if phone := remove_forbidden_chars(shopify_address['phone']):
|
||||
index = len(contact_mechanisms)
|
||||
for i, contact_mechanism in enumerate(contact_mechanisms):
|
||||
if (contact_mechanism.type in ['phone', 'mobile']
|
||||
and contact_mechanism.address == address):
|
||||
index = min(i, index)
|
||||
if (contact_mechanism.value_compact
|
||||
== contact_mechanism.format_value_compact(
|
||||
phone, contact_mechanism.type)):
|
||||
contact_mechanisms.insert(
|
||||
index,
|
||||
contact_mechanisms.pop(i))
|
||||
break
|
||||
else:
|
||||
contact_mechanisms.insert(index, ContactMechanism(
|
||||
party=self, address=address,
|
||||
type='phone', value=phone))
|
||||
ContactMechanism.save(sequence_reorder(
|
||||
contact_mechanisms))
|
||||
return address
|
||||
|
||||
|
||||
class Address(metaclass=PoolMeta):
|
||||
__name__ = 'party.address'
|
||||
|
||||
@classmethod
|
||||
def shopify_fields(cls):
|
||||
return {
|
||||
'name': None,
|
||||
'company': None,
|
||||
'address1': None,
|
||||
'address2': None,
|
||||
'city': None,
|
||||
'zip': None,
|
||||
'countryCodeV2': None,
|
||||
'provinceCode': None,
|
||||
'phone': None,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_shopify_values(self, address):
|
||||
pool = Pool()
|
||||
Country = pool.get('country.country')
|
||||
Subdivision = pool.get('country.subdivision')
|
||||
SubdivisionType = pool.get('party.address.subdivision_type')
|
||||
|
||||
values = {}
|
||||
values['party_name'] = remove_forbidden_chars(address['name'] or '')
|
||||
if address['company']:
|
||||
values['party_name'] += (
|
||||
f"({remove_forbidden_chars(address['company'])})")
|
||||
values['street'] = '\n'.join(filter(None, [
|
||||
address['address1'], address['address2']]))
|
||||
values['city'] = remove_forbidden_chars(address['city'] or '')
|
||||
values['postal_code'] = address['zip'] or ''
|
||||
if address['countryCodeV2']:
|
||||
country, = Country.search([
|
||||
('code', '=', address['countryCodeV2']),
|
||||
], limit=1)
|
||||
values['country'] = country.id
|
||||
if address['provinceCode']:
|
||||
subdivision_code = '-'.join(
|
||||
[address['countryCodeV2'], address['provinceCode']])
|
||||
subdivision_domain = [
|
||||
('country', '=', country.id),
|
||||
('code', 'like', subdivision_code + '%'),
|
||||
]
|
||||
types = SubdivisionType.get_types(country)
|
||||
if types:
|
||||
subdivision_domain.append(('type', 'in', types))
|
||||
subdivisions = Subdivision.search(subdivision_domain, limit=1)
|
||||
if subdivisions:
|
||||
subdivision, = subdivisions
|
||||
values['subdivision'] = subdivision.id
|
||||
return values
|
||||
|
||||
def shopify_values(self):
|
||||
values = {}
|
||||
values['party_name'] = self.party_name or ''
|
||||
values['street'] = self.street or ''
|
||||
values['city'] = self.city or ''
|
||||
values['postal_code'] = self.postal_code or ''
|
||||
if self.country:
|
||||
values['country'] = self.country.id
|
||||
if self.subdivision:
|
||||
values['subdivision'] = self.subdivision.id
|
||||
return values
|
||||
|
||||
|
||||
class Replace(metaclass=PoolMeta):
|
||||
__name__ = 'party.replace'
|
||||
|
||||
@classmethod
|
||||
def fields_to_replace(cls):
|
||||
return super().fields_to_replace() + [
|
||||
('web.shop.shopify_identifier', 'record'),
|
||||
]
|
||||
Reference in New Issue
Block a user