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.

173 lines
6.9 KiB

  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Author: Guewen Baconnier
  5. # Copyright 2012 Camptocamp SA
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. import openerp.osv.orm
  22. # Check if we can remove the monkey-patching once the bug:
  23. # https://bugs.launchpad.net/bugs/1053970
  24. # is resolved.
  25. original_create = openerp.osv.orm.BaseModel.create
  26. def create(self, cr, uid, vals, context=None):
  27. """
  28. Monkey-patch the create of BaseModel in order to create translation lines
  29. on translatable fields.
  30. Actually, the original behavior is quite strange. Here it is:
  31. I'm logged in with en_US language.
  32. I create a record, with a (translatable) title 'My title'
  33. I check the source in database (table of the object), that's 'My title'
  34. I check the translation lines for the en_US language, no line
  35. I write on my record the title 'My title updated'
  36. I check the source in database, that's 'My title updated'
  37. I check the translation lines for the en_US language, no line
  38. I'm logged in with fr_FR language
  39. I create a record, with a (translatable) title 'Mon titre'
  40. I check the source in database (table of the object), that's 'Mon titre'
  41. I check the translation lines for the fr_FR language, no line
  42. I write on my record the title 'Mon titre mis à jour'
  43. I check the source in database, that's 'Mon titre' (unchanged)
  44. I check the translation lines for the fr_FR language, I have a line with 'Mon titre mis à jour'
  45. As you can see, the write method create translation lines for other
  46. languages than en_US, that's correct. The create method does not,
  47. and it has to do it.
  48. OpenERP seems to assume that the en_US should be the reference
  49. language, so lets assume it completely, and generate the french
  50. translation line directly when we enter the value.
  51. That's weird, because, if I create a record in french, the source
  52. will be the french value (of course), but programmatically, I do not
  53. have any means to know that someone entered a french translation.
  54. A simple scenario where the bug will occurs:
  55. User A is logged in with fr_FR
  56. User A creates a product with a name 'Marteau'
  57. User B is logged in with en_US
  58. User B modifies the product 'Marteau' to be 'Hammer'
  59. => The french translation is lost.
  60. It won't occurs in this slightly modified scenario:
  61. User A is logged in with fr_FR
  62. User A creates a product with a name 'Martea' (typo)
  63. User A modifies the product 'Martea' to be 'Marteau'
  64. User B is logged in with en_US
  65. User B modifies the product 'Marteau' to be 'Hammer'
  66. => The french translation isn't lost, because the write has
  67. correctly generated the french translation line
  68. Bug reported : https://bugs.launchpad.net/bugs/1053970
  69. """
  70. if context is None:
  71. context = {}
  72. record_id = original_create(self, cr, uid, vals, context=context)
  73. if context.get('lang') and context['lang'] != 'en_US':
  74. translate_fields = [field for field in vals if
  75. field in self._columns and
  76. self._columns[field].translate and
  77. self._columns[field]._classic_write and
  78. not hasattr(self._columns[field], '_fnct_inv')]
  79. for field in translate_fields:
  80. src_trans = self.read(cr, uid, record_id, [field])[field]
  81. if not src_trans:
  82. src_trans = vals[field]
  83. # Inserting value to DB
  84. self.write(cr, uid, record_id, {field: vals[field]})
  85. self.pool.get('ir.translation')._set_ids(
  86. cr, uid,
  87. self._name + ',' + field,
  88. 'model',
  89. context['lang'],
  90. [record_id],
  91. vals[field],
  92. src_trans)
  93. return record_id
  94. openerp.osv.orm.BaseModel.create = create
  95. # add the method in the orm so we can use it from the TranslateDialog of the
  96. # webclient
  97. def read_translations(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
  98. """ Read records with given ids with the given fields, if a field is not
  99. translated, its value will be False instead of the source language's value.
  100. :param fields: optional list of field names to return (default: all fields would be returned)
  101. :type fields: list (example ['field_name_1', ...])
  102. :return: list of dictionaries((dictionary per record asked)) with requested field values
  103. :rtype: [{name_of_the_field: value, ...}, ...]
  104. :raise AccessError: * if user has no read rights on the requested object
  105. * if user tries to bypass access rules for read on the requested object
  106. """
  107. if context is None:
  108. context = {}
  109. self.check_read(cr, user)
  110. if not fields:
  111. fields = list(set(self._columns.keys() + self._inherit_fields.keys()))
  112. if isinstance(ids, (int, long)):
  113. select = [ids]
  114. else:
  115. select = ids
  116. select = map(lambda x: isinstance(x, dict) and x['id'] or x, select)
  117. result = self._read_flat(cr, user, select, fields, context, load)
  118. if context.get('lang') and context['lang'] != 'en_US':
  119. fields_pre = [f for f in fields if
  120. (f in self._columns and
  121. getattr(self._columns[f], '_classic_write'))] + \
  122. self._inherits.values()
  123. for f in fields_pre:
  124. if self._columns[f].translate:
  125. res_ids = [x['id'] for x in result]
  126. res_trans = self.pool.get('ir.translation')._get_ids(
  127. cr, user,
  128. self._name + ',' + f,
  129. 'model',
  130. context['lang'],
  131. res_ids)
  132. for r in result:
  133. if not res_trans.get(r['id']):
  134. r[f] = None
  135. for r in result:
  136. for key, v in r.iteritems():
  137. if v is None:
  138. r[key] = False
  139. if isinstance(ids, (int, long, dict)):
  140. return result and result[0] or False
  141. return result
  142. openerp.osv.orm.BaseModel.read_translations = read_translations