You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Akretion (http://www.akretion.com)
  3. # Sébastien BEAU <sebastien.beau@akretion.com>
  4. # Alexis de Lattre <alexis.delattre@akretion.com>
  5. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  6. from openerp import api, fields, models
  7. from operator import attrgetter
  8. import phonenumbers
  9. import logging
  10. _logger = logging.getLogger(__name__)
  11. class Phone(fields.Char):
  12. _slots = {
  13. 'country_field': None,
  14. 'partner_field': None,
  15. }
  16. def __init__(
  17. self, string=None, country_field=None, partner_field=None,
  18. **kwargs):
  19. super(Phone, self).__init__(
  20. string=string, country_field=country_field,
  21. partner_field=partner_field, **kwargs)
  22. _related_country_field = property(attrgetter('country_field'))
  23. _related_partner_field = property(attrgetter('partner_field'))
  24. def _setup_regular_full(self, model):
  25. super(Phone, self)._setup_regular_full(model)
  26. assert self.country_field in model._fields or \
  27. self.partner_field in model._fields, \
  28. "field %s with unknown country_field and partner_field" % self
  29. def convert_to_cache(self, value, record, validate=True):
  30. res = super(Phone, self).convert_to_cache(
  31. value, record, validate=validate)
  32. # print 'db value', res
  33. if res:
  34. try:
  35. res_parse = phonenumbers.parse(res)
  36. res = phonenumbers.format_number(
  37. res_parse, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
  38. narrow_no_break_space = u'\u202f'
  39. res = res.replace(' ', narrow_no_break_space)
  40. except:
  41. pass
  42. # print 'cache value', res
  43. return res
  44. def convert_phone_field(value, country_code):
  45. _logger.debug(
  46. 'convert_phone_field value=%s country=%s', value, country_code)
  47. try:
  48. narrow_no_break_space = u'\u202f'
  49. # phonenumbers.parse fails with narrow_no_break_space
  50. value = value.replace(narrow_no_break_space, '')
  51. res_parse = phonenumbers.parse(
  52. value, country_code)
  53. _logger.debug('res_parse=%s', res_parse)
  54. new_value = phonenumbers.format_number(
  55. res_parse, phonenumbers.PhoneNumberFormat.E164)
  56. _logger.debug('new_value=%s', new_value)
  57. except:
  58. _logger.error(
  59. "Cannot reformat the phone number '%s' to "
  60. "international format with region=%s",
  61. value, country_code)
  62. new_value = value
  63. return new_value
  64. def convert_all_phone_fields(self, vals, fields_to_convert):
  65. loc_vals = vals.copy()
  66. for field in fields_to_convert:
  67. country_key = self._fields[field].country_field
  68. partner_key = self._fields[field].partner_field
  69. country = False
  70. if country_key:
  71. if country_key in loc_vals:
  72. country = self.env['res.country'].browse(vals[country_key])
  73. else:
  74. country = self[country_key]
  75. if partner_key and not country:
  76. if partner_key in loc_vals:
  77. partner = self.env['res.partner'].browse(vals[partner_key])
  78. else:
  79. partner = self[partner_key]
  80. if partner:
  81. country = partner.country_id
  82. if not country:
  83. country = self.env.user.company_id.country_id
  84. country_code = False
  85. if country:
  86. country_code = country.code.upper()
  87. if loc_vals[field]:
  88. loc_vals[field] = convert_phone_field(
  89. loc_vals[field], country_code)
  90. return loc_vals
  91. def get_phone_fields(self, vals):
  92. fields_to_convert = []
  93. for key in vals:
  94. if isinstance(self._fields.get(key), Phone):
  95. fields_to_convert.append(key)
  96. return fields_to_convert
  97. original_write = models.Model.write
  98. original_create = models.Model.create
  99. @api.multi
  100. def write(self, vals):
  101. fields_to_convert = get_phone_fields(self, vals)
  102. if fields_to_convert:
  103. for record in self:
  104. loc_vals = convert_all_phone_fields(
  105. record, vals, fields_to_convert)
  106. original_write(record, loc_vals)
  107. return True
  108. else:
  109. return original_write(self, vals)
  110. @api.model
  111. @api.returns('self', lambda value: value.id)
  112. def create(self, vals):
  113. fields_to_convert = get_phone_fields(self, vals)
  114. if fields_to_convert:
  115. vals = convert_all_phone_fields(self, vals, fields_to_convert)
  116. return original_create(self, vals)
  117. models.Model.write = write
  118. models.Model.create = create