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.

149 lines
5.0 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.Model.write
  95. original_create = models.Model.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. # When updating a partner in the frontend of the POS
  102. # Odoo generate a write() with the ID of the country as unicode !!!
  103. # example : vals = {u'country_id': u'9'}
  104. # So we have to convert it to an integer before browsing
  105. if vals['country_id']:
  106. vals['country_id'] = int(vals['country_id'])
  107. loc_vals = convert_all_phone_fields(
  108. record, vals, fields_to_convert)
  109. original_write(record, loc_vals)
  110. return True
  111. else:
  112. return original_write(self, vals)
  113. @api.model
  114. @api.returns('self', lambda value: value.id)
  115. def create(self, vals):
  116. fields_to_convert = get_phone_fields(self, vals)
  117. if fields_to_convert:
  118. # When creating a partner in the frontend of the POS
  119. # Odoo generate a create() with the ID of the country as unicode !!!
  120. # example : vals = {u'country_id': u'9'}
  121. # So we have to convert it to an integer before browsing
  122. if vals['country_id']:
  123. vals['country_id'] = int(vals['country_id'])
  124. vals = convert_all_phone_fields(self, vals, fields_to_convert)
  125. return original_create(self, vals)
  126. models.Model.write = write
  127. models.Model.create = create