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.

137 lines
4.4 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. no_break_space = u'\u00A0'
  39. res = res.replace(' ', 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. res_parse = phonenumbers.parse(
  49. value, country_code)
  50. _logger.debug('res_parse=%s', res_parse)
  51. new_value = phonenumbers.format_number(
  52. res_parse, phonenumbers.PhoneNumberFormat.E164)
  53. _logger.debug('new_value=%s', new_value)
  54. except:
  55. _logger.error(
  56. "Cannot reformat the phone number '%s' to "
  57. "international format with region=%s",
  58. value, country_code)
  59. new_value = value
  60. return new_value
  61. def convert_all_phone_fields(self, vals, fields_to_convert):
  62. loc_vals = vals.copy()
  63. for field in fields_to_convert:
  64. country_key = self._fields[field].country_field
  65. partner_key = self._fields[field].partner_field
  66. country = False
  67. if country_key:
  68. if country_key in loc_vals:
  69. country = self.env['res.country'].browse(vals[country_key])
  70. else:
  71. country = self[country_key]
  72. if partner_key and not country:
  73. if partner_key in loc_vals:
  74. partner = self.env['res.partner'].browse(vals[partner_key])
  75. else:
  76. partner = self[partner_key]
  77. if partner:
  78. country = partner.country_id
  79. if not country:
  80. country = self.env.user.company_id.country_id
  81. country_code = False
  82. if country:
  83. country_code = country.code.upper()
  84. if loc_vals[field]:
  85. loc_vals[field] = convert_phone_field(
  86. loc_vals[field], country_code)
  87. return loc_vals
  88. def get_phone_fields(self, vals):
  89. fields_to_convert = []
  90. for key in vals:
  91. if isinstance(self._fields.get(key), Phone):
  92. fields_to_convert.append(key)
  93. return fields_to_convert
  94. original_write = models.BaseModel.write
  95. original_create = models.BaseModel.create
  96. @api.multi
  97. def write(self, vals):
  98. fields_to_convert = get_phone_fields(self, vals)
  99. if fields_to_convert:
  100. for record in self:
  101. loc_vals = convert_all_phone_fields(
  102. record, vals, fields_to_convert)
  103. original_write(record, loc_vals)
  104. return True
  105. else:
  106. return original_write(self, vals)
  107. @api.model
  108. @api.returns('self', lambda value: value.id)
  109. def create(self, vals):
  110. fields_to_convert = get_phone_fields(self, vals)
  111. if fields_to_convert:
  112. vals = convert_all_phone_fields(self, vals, fields_to_convert)
  113. return original_create(self, vals)
  114. models.BaseModel.write = write
  115. models.BaseModel.create = create