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.

210 lines
8.4 KiB

  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Partner External Maps module for Odoo
  5. # Copyright (C) 2015 Akretion (http://www.akretion.com/)
  6. # @author: Alexis de Lattre <alexis.delattre@akretion.com>
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Affero General Public License as
  10. # published by the Free Software Foundation, either version 3 of the
  11. # License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Affero General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ##############################################################################
  22. from openerp import models, fields, api, _
  23. from openerp.exceptions import Warning
  24. import logging
  25. logger = logging.getLogger(__name__)
  26. class MapWebsite(models.Model):
  27. _name = 'map.website'
  28. _description = 'Map Website'
  29. name = fields.Char(string='Map Website Name', required=True)
  30. address_url = fields.Char(
  31. string='URL that uses the address',
  32. help="In this URL, {ADDRESS} will be replaced by the address.")
  33. lat_lon_url = fields.Char(
  34. string='URL that uses latitude and longitude',
  35. help="In this URL, {LATITUDE} and {LONGITUDE} will be replaced by "
  36. "the latitude and longitude (requires the module 'base_geolocalize')")
  37. route_address_url = fields.Char(
  38. string='Route URL that uses the addresses',
  39. help="In this URL, {START_ADDRESS} and {DEST_ADDRESS} will be "
  40. "replaced by the start and destination addresses.")
  41. route_lat_lon_url = fields.Char(
  42. string='Route URL that uses latitude and longitude',
  43. help="In this URL, {START_LATITUDE}, {START_LONGITUDE}, "
  44. "{DEST_LATITUDE} and {DEST_LONGITUDE} will be replaced by the "
  45. "latitude and longitude of the start and destination adresses "
  46. "(requires the module 'base_geolocalize').")
  47. class ResUsers(models.Model):
  48. _inherit = 'res.users'
  49. @api.model
  50. def _default_map_website(self):
  51. map_website = self.env['map.website'].search([
  52. '|', ('address_url', '!=', False), ('lat_lon_url', '!=', False)],
  53. limit=1)
  54. return map_website
  55. @api.model
  56. def _default_route_map_website(self):
  57. map_route_website = self.env['map.website'].search([
  58. '|',
  59. ('route_address_url', '!=', False),
  60. ('route_lat_lon_url', '!=', False)], limit=1)
  61. return map_route_website
  62. # begin with context_ to allow user to change it by himself
  63. context_map_website_id = fields.Many2one(
  64. 'map.website', string='Map Website',
  65. domain=[
  66. '|', ('address_url', '!=', False), ('lat_lon_url', '!=', False)],
  67. default=_default_map_website)
  68. # We want to give the possibility to the user to have one map provider for
  69. # regular maps and another one for routing
  70. context_route_map_website_id = fields.Many2one(
  71. 'map.website', string='Route Map Website',
  72. domain=[
  73. '|',
  74. ('route_address_url', '!=', False),
  75. ('route_lat_lon_url', '!=', False)],
  76. default=_default_route_map_website,
  77. help="Map provided used when you click on the car icon on the partner "
  78. "form to display an itinerary.")
  79. context_route_start_partner_id = fields.Many2one(
  80. 'res.partner', string='Start Address for Route Map')
  81. @api.model
  82. def _default_map_settings(self):
  83. """Method called from post-install script
  84. I can't use a default method on the field, because it would be executed
  85. before loading map_website_data.xml, so it would not be able to set a
  86. value"""
  87. users = self.env['res.users'].search([])
  88. map_website = self._default_map_website()
  89. map_route_website = self._default_route_map_website()
  90. logger.info('Updating user settings for maps...')
  91. for user in users:
  92. user.write({
  93. 'context_map_website_id': map_website.id or False,
  94. 'context_route_map_website_id': map_route_website.id or False,
  95. 'context_route_start_partner_id': user.partner_id.id or False,
  96. })
  97. class ResPartner(models.Model):
  98. _inherit = 'res.partner'
  99. @api.model
  100. def _address_as_string(self):
  101. addr = []
  102. if self.street:
  103. addr.append(self.street)
  104. if self.street2:
  105. addr.append(self.street2)
  106. if self.city:
  107. addr.append(self.city)
  108. if self.state_id:
  109. addr.append(self.state_id.name)
  110. if self.country_id:
  111. addr.append(self.country_id.name)
  112. if not addr:
  113. raise Warning(
  114. _("Address missing on partner '%s'.") % self.name)
  115. address = ' '.join(addr)
  116. return address
  117. @api.model
  118. def _prepare_url(self, url, replace):
  119. assert url, 'Missing URL'
  120. for key, value in replace.iteritems():
  121. if not isinstance(value, (str, unicode)):
  122. # for latitude and longitude which are floats
  123. value = unicode(value)
  124. url = url.replace(key, value)
  125. logger.debug('Final URL: %s', url)
  126. return url
  127. @api.multi
  128. def open_map(self):
  129. if not self.env.user.context_map_website_id:
  130. raise Warning(
  131. _('Missing map provider: '
  132. 'you should set it in your preferences.'))
  133. map_website = self.env.user.context_map_website_id
  134. if (
  135. map_website.lat_lon_url and
  136. hasattr(self, 'partner_latitude') and
  137. self.partner_latitude and self.partner_longitude):
  138. url = self._prepare_url(
  139. map_website.lat_lon_url, {
  140. '{LATITUDE}': self.partner_latitude,
  141. '{LONGITUDE}': self.partner_longitude})
  142. else:
  143. if not map_website.address_url:
  144. raise Warning(
  145. _("Missing parameter 'URL that uses the address' "
  146. "for map website '%s'.") % map_website.name)
  147. url = self._prepare_url(
  148. map_website.address_url,
  149. {'{ADDRESS}': self._address_as_string()})
  150. return {
  151. 'type': 'ir.actions.act_url',
  152. 'url': url,
  153. 'target': 'new',
  154. }
  155. @api.multi
  156. def open_route_map(self):
  157. if not self.env.user.context_route_map_website_id:
  158. raise Warning(
  159. _('Missing route map website: '
  160. 'you should set it in your preferences.'))
  161. map_website = self.env.user.context_route_map_website_id
  162. if not self.env.user.context_route_start_partner_id:
  163. raise Warning(
  164. _('Missing start address for route map: '
  165. 'you should set it in your preferences.'))
  166. start_partner = self.env.user.context_route_start_partner_id
  167. if (
  168. map_website.route_lat_lon_url and
  169. hasattr(self, 'partner_latitude') and
  170. self.partner_latitude and
  171. self.partner_longitude and
  172. start_partner.partner_latitude and
  173. start_partner.partner_longitude):
  174. url = self._prepare_url(
  175. map_website.route_lat_lon_url, {
  176. '{START_LATITUDE}': start_partner.partner_latitude,
  177. '{START_LONGITUDE}': start_partner.partner_longitude,
  178. '{DEST_LATITUDE}': self.partner_latitude,
  179. '{DEST_LONGITUDE}': self.partner_longitude})
  180. else:
  181. if not map_website.route_address_url:
  182. raise Warning(
  183. _("Missing route URL that uses the addresses "
  184. "for the map website '%s'") % map_website.name)
  185. url = self._prepare_url(
  186. map_website.route_address_url, {
  187. '{START_ADDRESS}': start_partner._address_as_string(),
  188. '{DEST_ADDRESS}': self._address_as_string()})
  189. return {
  190. 'type': 'ir.actions.act_url',
  191. 'url': url,
  192. 'target': 'new',
  193. }