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.

143 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 logging
  9. _logger = logging.getLogger(__name__)
  10. try:
  11. import phonenumbers
  12. except (ImportError, IOError) as err:
  13. _logger.debug(err)
  14. class Phone(fields.Char):
  15. _slots = {
  16. 'country_field': None,
  17. 'partner_field': None,
  18. }
  19. def __init__(
  20. self, string=None, country_field=None, partner_field=None,
  21. **kwargs):
  22. super(Phone, self).__init__(
  23. string=string, country_field=country_field,
  24. partner_field=partner_field, **kwargs)
  25. _related_country_field = property(attrgetter('country_field'))
  26. _related_partner_field = property(attrgetter('partner_field'))
  27. def _setup_regular_full(self, model):
  28. super(Phone, self)._setup_regular_full(model)
  29. assert self.country_field in model._fields or \
  30. self.partner_field in model._fields, \
  31. "field %s with unknown country_field and partner_field" % self
  32. def convert_to_cache(self, value, record, validate=True):
  33. res = super(Phone, self).convert_to_cache(
  34. value, record, validate=validate)
  35. # print 'db value', res
  36. if res:
  37. try:
  38. res_parse = phonenumbers.parse(res)
  39. res = phonenumbers.format_number(
  40. res_parse, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
  41. no_break_space = u'\u00A0'
  42. res = res.replace(' ', no_break_space)
  43. except:
  44. pass
  45. # print 'cache value', res
  46. return res
  47. def convert_phone_field(value, country_code):
  48. _logger.debug(
  49. 'convert_phone_field value=%s country=%s', value, country_code)
  50. try:
  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.BaseModel.write
  98. original_create = models.BaseModel.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.BaseModel.write = write
  118. models.BaseModel.create = create