Files
odoo_source/addons/base_address_extended/models/res_partner.py
T
Martin Trigaux ba244cef01 [IMP] *: replace to new _() syntax
Using a few regex like
\((_\(.*%s.*)(\) % )([\w\[\]][\w .\[\]\(\)'"]*)\)
($1, $3))

Old syntax is still compatible but starts the migration to the new
syntax that catches error.
2020-06-18 13:03:34 +02:00

132 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class Partner(models.Model):
_inherit = ['res.partner']
street_name = fields.Char(
'Street Name', compute='_compute_street_data', inverse='_inverse_street_data', store=True)
street_number = fields.Char(
'House', compute='_compute_street_data', inverse='_inverse_street_data', store=True)
street_number2 = fields.Char(
'Door', compute='_compute_street_data', inverse='_inverse_street_data', store=True)
def _inverse_street_data(self):
"""Updates the street field.
Writes the `street` field on the partners when one of the sub-fields in STREET_FIELDS
has been touched"""
street_fields = self._get_street_fields()
for partner in self:
street_format = (partner.country_id.street_format or
'%(street_number)s/%(street_number2)s %(street_name)s')
previous_field = None
previous_pos = 0
street_value = ""
separator = ""
# iter on fields in street_format, detected as '%(<field_name>)s'
for re_match in re.finditer(r'%\(\w+\)s', street_format):
# [2:-2] is used to remove the extra chars '%(' and ')s'
field_name = re_match.group()[2:-2]
field_pos = re_match.start()
if field_name not in street_fields:
raise UserError(_("Unrecognized field %s in street format.", field_name))
if not previous_field:
# first iteration: add heading chars in street_format
if partner[field_name]:
street_value += street_format[0:field_pos] + partner[field_name]
else:
# get the substring between 2 fields, to be used as separator
separator = street_format[previous_pos:field_pos]
if street_value and partner[field_name]:
street_value += separator
if partner[field_name]:
street_value += partner[field_name]
previous_field = field_name
previous_pos = re_match.end()
# add trailing chars in street_format
street_value += street_format[previous_pos:]
partner.street = street_value
@api.depends('street')
def _compute_street_data(self):
"""Splits street value into sub-fields.
Recomputes the fields of STREET_FIELDS when `street` of a partner is updated"""
street_fields = self._get_street_fields()
for partner in self:
if not partner.street:
for field in street_fields:
partner[field] = None
continue
street_format = (partner.country_id.street_format or
'%(street_number)s/%(street_number2)s %(street_name)s')
street_raw = partner.street
vals = self._split_street_with_params(street_raw, street_format)
# assign the values to the fields
for k, v in vals.items():
partner[k] = v
for k in set(street_fields) - set(vals):
partner[k] = None
def _split_street_with_params(self, street_raw, street_format):
street_fields = self._get_street_fields()
vals = {}
previous_pos = 0
field_name = None
# iter on fields in street_format, detected as '%(<field_name>)s'
for re_match in re.finditer(r'%\(\w+\)s', street_format):
field_pos = re_match.start()
if not field_name:
#first iteration: remove the heading chars
street_raw = street_raw[field_pos:]
# get the substring between 2 fields, to be used as separator
separator = street_format[previous_pos:field_pos]
field_value = None
if separator and field_name:
#maxsplit set to 1 to unpack only the first element and let the rest untouched
tmp = street_raw.split(separator, 1)
if len(tmp) == 2:
field_value, street_raw = tmp
vals[field_name] = field_value
if field_value or not field_name:
# select next field to find (first pass OR field found)
# [2:-2] is used to remove the extra chars '%(' and ')s'
field_name = re_match.group()[2:-2]
else:
# value not found: keep looking for the same field
pass
if field_name not in street_fields:
raise UserError(_("Unrecognized field %s in street format.", field_name))
previous_pos = re_match.end()
# last field value is what remains in street_raw minus trailing chars in street_format
trailing_chars = street_format[previous_pos:]
if trailing_chars and street_raw.endswith(trailing_chars):
vals[field_name] = street_raw[:-len(trailing_chars)]
else:
vals[field_name] = street_raw
return vals
def write(self, vals):
res = super(Partner, self).write(vals)
if 'country_id' in vals and 'street' not in vals:
self._inverse_street_data()
return res
def _formatting_address_fields(self):
"""Returns the list of address fields usable to format addresses."""
return super(Partner, self)._formatting_address_fields() + self._get_street_fields()
def _get_street_fields(self):
"""Returns the fields that can be used in a street format.
Overwrite this function if you want to add your own fields."""
return ['street_name', 'street_number', 'street_number2']