Pedro M. Baeza
9 years ago
16 changed files with 3145 additions and 241 deletions
-
42partner_external_map/README.rst
-
4partner_external_map/__init__.py
-
16partner_external_map/__openerp__.py
-
14partner_external_map/data/map_website_data.xml
-
33partner_external_map/hooks.py
-
5partner_external_map/models/__init__.py
-
30partner_external_map/models/map_website.py
-
109partner_external_map/models/res_partner.py
-
42partner_external_map/models/res_users.py
-
193partner_external_map/partner_external_maps.py
-
11partner_external_map/post_install.py
-
BINpartner_external_map/static/description/icon.png
-
2887partner_external_map/static/description/icon.svg
-
0partner_external_map/views/map_website_view.xml
-
0partner_external_map/views/res_partner_view.xml
-
0partner_external_map/views/res_users_view.xml
@ -1,4 +1,4 @@ |
|||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||
|
|
||||
from . import partner_external_maps |
|
||||
from .post_install import set_default_map_settings |
|
||||
|
from . import models |
||||
|
from .hooks import set_default_map_settings |
@ -0,0 +1,33 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# © 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from openerp import api, SUPERUSER_ID |
||||
|
import logging |
||||
|
|
||||
|
|
||||
|
logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
def set_default_map_settings(cr, pool): |
||||
|
"""Method called as post-install script |
||||
|
The default method on the field can't be used, because it would be executed |
||||
|
before loading map_website_data.xml, so it would not be able to set a |
||||
|
value""" |
||||
|
with api.Environment.manage(): |
||||
|
env = api.Environment(cr, SUPERUSER_ID, {}) |
||||
|
user_model = env['res.users'] |
||||
|
users = user_model.search([]) |
||||
|
logger.info('Updating user settings for maps...') |
||||
|
users.write({ |
||||
|
'context_map_website_id': user_model._default_map_website().id, |
||||
|
'context_route_map_website_id': ( |
||||
|
user_model._default_route_map_website().id), |
||||
|
}) |
||||
|
# Update the starting partner this way that is faster |
||||
|
cr.execute(""" |
||||
|
UPDATE res_users |
||||
|
SET context_route_start_partner_id = partner_id |
||||
|
WHERE context_route_start_partner_id IS NULL; |
||||
|
""") |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import map_website |
||||
|
from . import res_partner |
||||
|
from . import res_users |
@ -0,0 +1,30 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# © 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from openerp import models, fields, api, _ |
||||
|
|
||||
|
|
||||
|
class MapWebsite(models.Model): |
||||
|
_name = 'map.website' |
||||
|
_description = 'Map Website' |
||||
|
|
||||
|
name = fields.Char(string='Map Website Name', required=True) |
||||
|
address_url = fields.Char( |
||||
|
string='URL that uses the address', |
||||
|
help="In this URL, {ADDRESS} will be replaced by the address.") |
||||
|
lat_lon_url = fields.Char( |
||||
|
string='URL that uses latitude and longitude', |
||||
|
help="In this URL, {LATITUDE} and {LONGITUDE} will be replaced by " |
||||
|
"the latitude and longitude (requires the module 'base_geolocalize')") |
||||
|
route_address_url = fields.Char( |
||||
|
string='Route URL that uses the addresses', |
||||
|
help="In this URL, {START_ADDRESS} and {DEST_ADDRESS} will be " |
||||
|
"replaced by the start and destination addresses.") |
||||
|
route_lat_lon_url = fields.Char( |
||||
|
string='Route URL that uses latitude and longitude', |
||||
|
help="In this URL, {START_LATITUDE}, {START_LONGITUDE}, " |
||||
|
"{DEST_LATITUDE} and {DEST_LONGITUDE} will be replaced by the " |
||||
|
"latitude and longitude of the start and destination adresses " |
||||
|
"(requires the module 'base_geolocalize').") |
@ -0,0 +1,109 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# © 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from openerp import models, fields, api, _ |
||||
|
from openerp.exceptions import Warning as UserError |
||||
|
import logging |
||||
|
|
||||
|
|
||||
|
logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
@api.multi |
||||
|
def _address_as_string(self): |
||||
|
self.ensure_one() |
||||
|
addr = [] |
||||
|
if self.street: |
||||
|
addr.append(self.street) |
||||
|
if self.street2: |
||||
|
addr.append(self.street2) |
||||
|
if self.city: |
||||
|
addr.append(self.city) |
||||
|
if self.state_id: |
||||
|
addr.append(self.state_id.name) |
||||
|
if self.country_id: |
||||
|
addr.append(self.country_id.name) |
||||
|
if not addr: |
||||
|
raise UserError(_("Address missing on partner '%s'.") % self.name) |
||||
|
return ' '.join(addr) |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_url(self, url, replace): |
||||
|
assert url, 'Missing URL' |
||||
|
for key, value in replace.iteritems(): |
||||
|
if not isinstance(value, (str, unicode)): |
||||
|
# for latitude and longitude which are floats |
||||
|
value = unicode(value) |
||||
|
url = url.replace(key, value) |
||||
|
logger.debug('Final URL: %s', url) |
||||
|
return url |
||||
|
|
||||
|
@api.multi |
||||
|
def open_map(self): |
||||
|
map_website = self.env.user.context_map_website_id |
||||
|
if not map_website: |
||||
|
raise UserError( |
||||
|
_('Missing map provider: ' |
||||
|
'you should set it in your preferences.')) |
||||
|
if (map_website.lat_lon_url and hasattr(self, 'partner_latitude') and |
||||
|
self.partner_latitude and self.partner_longitude): |
||||
|
url = self._prepare_url( |
||||
|
map_website.lat_lon_url, { |
||||
|
'{LATITUDE}': self.partner_latitude, |
||||
|
'{LONGITUDE}': self.partner_longitude}) |
||||
|
else: |
||||
|
if not map_website.address_url: |
||||
|
raise UserError( |
||||
|
_("Missing parameter 'URL that uses the address' " |
||||
|
"for map website '%s'.") % map_website.name) |
||||
|
url = self._prepare_url( |
||||
|
map_website.address_url, |
||||
|
{'{ADDRESS}': self._address_as_string()}) |
||||
|
return { |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': url, |
||||
|
'target': 'new', |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def open_route_map(self): |
||||
|
if not self.env.user.context_route_map_website_id: |
||||
|
raise UserError( |
||||
|
_('Missing route map website: ' |
||||
|
'you should set it in your preferences.')) |
||||
|
map_website = self.env.user.context_route_map_website_id |
||||
|
if not self.env.user.context_route_start_partner_id: |
||||
|
raise UserError( |
||||
|
_('Missing start address for route map: ' |
||||
|
'you should set it in your preferences.')) |
||||
|
start_partner = self.env.user.context_route_start_partner_id |
||||
|
if (map_website.route_lat_lon_url and |
||||
|
hasattr(self, 'partner_latitude') and |
||||
|
self.partner_latitude and self.partner_longitude and |
||||
|
start_partner.partner_latitude and |
||||
|
start_partner.partner_longitude): |
||||
|
url = self._prepare_url( |
||||
|
map_website.route_lat_lon_url, { |
||||
|
'{START_LATITUDE}': start_partner.partner_latitude, |
||||
|
'{START_LONGITUDE}': start_partner.partner_longitude, |
||||
|
'{DEST_LATITUDE}': self.partner_latitude, |
||||
|
'{DEST_LONGITUDE}': self.partner_longitude}) |
||||
|
else: |
||||
|
if not map_website.route_address_url: |
||||
|
raise UserError( |
||||
|
_("Missing route URL that uses the addresses " |
||||
|
"for the map website '%s'") % map_website.name) |
||||
|
url = self._prepare_url( |
||||
|
map_website.route_address_url, { |
||||
|
'{START_ADDRESS}': start_partner._address_as_string(), |
||||
|
'{DEST_ADDRESS}': self._address_as_string()}) |
||||
|
return { |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': url, |
||||
|
'target': 'new', |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# © 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from openerp import models, fields, api, _ |
||||
|
import logging |
||||
|
|
||||
|
logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class ResUsers(models.Model): |
||||
|
_inherit = 'res.users' |
||||
|
|
||||
|
@api.model |
||||
|
def _default_map_website(self): |
||||
|
return self.env['map.website'].search([ |
||||
|
'|', ('address_url', '!=', False), ('lat_lon_url', '!=', False)], |
||||
|
limit=1) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_route_map_website(self): |
||||
|
return self.env['map.website'].search([ |
||||
|
'|', ('route_address_url', '!=', False), |
||||
|
('route_lat_lon_url', '!=', False)], limit=1) |
||||
|
|
||||
|
# begin with context_ to allow user to change it by himself |
||||
|
context_map_website_id = fields.Many2one( |
||||
|
'map.website', string='Map Website', default=_default_map_website, |
||||
|
domain=['|', ('address_url', '!=', False), |
||||
|
('lat_lon_url', '!=', False)]) |
||||
|
# We want to give the possibility to the user to have one map provider for |
||||
|
# regular maps and another one for routing |
||||
|
context_route_map_website_id = fields.Many2one( |
||||
|
'map.website', string='Route Map Website', |
||||
|
domain=['|', ('route_address_url', '!=', False), |
||||
|
('route_lat_lon_url', '!=', False)], |
||||
|
default=_default_route_map_website, |
||||
|
help="Map provided used when you click on the car icon on the partner " |
||||
|
"form to display an itinerary.") |
||||
|
context_route_start_partner_id = fields.Many2one( |
||||
|
'res.partner', string='Start Address for Route Map') |
@ -1,193 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# © 2015 Akretion (http://www.akretion.com/) |
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com> |
|
||||
|
|
||||
from openerp import models, fields, api, _ |
|
||||
from openerp.exceptions import Warning |
|
||||
import logging |
|
||||
|
|
||||
logger = logging.getLogger(__name__) |
|
||||
|
|
||||
|
|
||||
class MapWebsite(models.Model): |
|
||||
_name = 'map.website' |
|
||||
_description = 'Map Website' |
|
||||
|
|
||||
name = fields.Char(string='Map Website Name', required=True) |
|
||||
address_url = fields.Char( |
|
||||
string='URL that uses the address', |
|
||||
help="In this URL, {ADDRESS} will be replaced by the address.") |
|
||||
lat_lon_url = fields.Char( |
|
||||
string='URL that uses latitude and longitude', |
|
||||
help="In this URL, {LATITUDE} and {LONGITUDE} will be replaced by " |
|
||||
"the latitude and longitude (requires the module 'base_geolocalize')") |
|
||||
route_address_url = fields.Char( |
|
||||
string='Route URL that uses the addresses', |
|
||||
help="In this URL, {START_ADDRESS} and {DEST_ADDRESS} will be " |
|
||||
"replaced by the start and destination addresses.") |
|
||||
route_lat_lon_url = fields.Char( |
|
||||
string='Route URL that uses latitude and longitude', |
|
||||
help="In this URL, {START_LATITUDE}, {START_LONGITUDE}, " |
|
||||
"{DEST_LATITUDE} and {DEST_LONGITUDE} will be replaced by the " |
|
||||
"latitude and longitude of the start and destination adresses " |
|
||||
"(requires the module 'base_geolocalize').") |
|
||||
|
|
||||
|
|
||||
class ResUsers(models.Model): |
|
||||
_inherit = 'res.users' |
|
||||
|
|
||||
@api.model |
|
||||
def _default_map_website(self): |
|
||||
map_website = self.env['map.website'].search([ |
|
||||
'|', ('address_url', '!=', False), ('lat_lon_url', '!=', False)], |
|
||||
limit=1) |
|
||||
return map_website |
|
||||
|
|
||||
@api.model |
|
||||
def _default_route_map_website(self): |
|
||||
map_route_website = self.env['map.website'].search([ |
|
||||
'|', |
|
||||
('route_address_url', '!=', False), |
|
||||
('route_lat_lon_url', '!=', False)], limit=1) |
|
||||
return map_route_website |
|
||||
|
|
||||
# begin with context_ to allow user to change it by himself |
|
||||
context_map_website_id = fields.Many2one( |
|
||||
'map.website', string='Map Website', |
|
||||
domain=[ |
|
||||
'|', ('address_url', '!=', False), ('lat_lon_url', '!=', False)], |
|
||||
default=_default_map_website) |
|
||||
# We want to give the possibility to the user to have one map provider for |
|
||||
# regular maps and another one for routing |
|
||||
context_route_map_website_id = fields.Many2one( |
|
||||
'map.website', string='Route Map Website', |
|
||||
domain=[ |
|
||||
'|', |
|
||||
('route_address_url', '!=', False), |
|
||||
('route_lat_lon_url', '!=', False)], |
|
||||
default=_default_route_map_website, |
|
||||
help="Map provided used when you click on the car icon on the partner " |
|
||||
"form to display an itinerary.") |
|
||||
context_route_start_partner_id = fields.Many2one( |
|
||||
'res.partner', string='Start Address for Route Map') |
|
||||
|
|
||||
@api.model |
|
||||
def _default_map_settings(self): |
|
||||
"""Method called from post-install script |
|
||||
I can't use a default method on the field, because it would be executed |
|
||||
before loading map_website_data.xml, so it would not be able to set a |
|
||||
value""" |
|
||||
users = self.env['res.users'].search([]) |
|
||||
map_website = self._default_map_website() |
|
||||
map_route_website = self._default_route_map_website() |
|
||||
logger.info('Updating user settings for maps...') |
|
||||
for user in users: |
|
||||
user.write({ |
|
||||
'context_map_website_id': map_website.id or False, |
|
||||
'context_route_map_website_id': map_route_website.id or False, |
|
||||
'context_route_start_partner_id': user.partner_id.id or False, |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
class ResPartner(models.Model): |
|
||||
_inherit = 'res.partner' |
|
||||
|
|
||||
@api.model |
|
||||
def _address_as_string(self): |
|
||||
addr = [] |
|
||||
if self.street: |
|
||||
addr.append(self.street) |
|
||||
if self.street2: |
|
||||
addr.append(self.street2) |
|
||||
if self.city: |
|
||||
addr.append(self.city) |
|
||||
if self.state_id: |
|
||||
addr.append(self.state_id.name) |
|
||||
if self.country_id: |
|
||||
addr.append(self.country_id.name) |
|
||||
if not addr: |
|
||||
raise Warning( |
|
||||
_("Address missing on partner '%s'.") % self.name) |
|
||||
address = ' '.join(addr) |
|
||||
return address |
|
||||
|
|
||||
@api.model |
|
||||
def _prepare_url(self, url, replace): |
|
||||
assert url, 'Missing URL' |
|
||||
for key, value in replace.iteritems(): |
|
||||
if not isinstance(value, (str, unicode)): |
|
||||
# for latitude and longitude which are floats |
|
||||
value = unicode(value) |
|
||||
url = url.replace(key, value) |
|
||||
logger.debug('Final URL: %s', url) |
|
||||
return url |
|
||||
|
|
||||
@api.multi |
|
||||
def open_map(self): |
|
||||
if not self.env.user.context_map_website_id: |
|
||||
raise Warning( |
|
||||
_('Missing map provider: ' |
|
||||
'you should set it in your preferences.')) |
|
||||
map_website = self.env.user.context_map_website_id |
|
||||
if ( |
|
||||
map_website.lat_lon_url and |
|
||||
hasattr(self, 'partner_latitude') and |
|
||||
self.partner_latitude and self.partner_longitude): |
|
||||
url = self._prepare_url( |
|
||||
map_website.lat_lon_url, { |
|
||||
'{LATITUDE}': self.partner_latitude, |
|
||||
'{LONGITUDE}': self.partner_longitude}) |
|
||||
else: |
|
||||
if not map_website.address_url: |
|
||||
raise Warning( |
|
||||
_("Missing parameter 'URL that uses the address' " |
|
||||
"for map website '%s'.") % map_website.name) |
|
||||
url = self._prepare_url( |
|
||||
map_website.address_url, |
|
||||
{'{ADDRESS}': self._address_as_string()}) |
|
||||
return { |
|
||||
'type': 'ir.actions.act_url', |
|
||||
'url': url, |
|
||||
'target': 'new', |
|
||||
} |
|
||||
|
|
||||
@api.multi |
|
||||
def open_route_map(self): |
|
||||
if not self.env.user.context_route_map_website_id: |
|
||||
raise Warning( |
|
||||
_('Missing route map website: ' |
|
||||
'you should set it in your preferences.')) |
|
||||
map_website = self.env.user.context_route_map_website_id |
|
||||
if not self.env.user.context_route_start_partner_id: |
|
||||
raise Warning( |
|
||||
_('Missing start address for route map: ' |
|
||||
'you should set it in your preferences.')) |
|
||||
start_partner = self.env.user.context_route_start_partner_id |
|
||||
if ( |
|
||||
map_website.route_lat_lon_url and |
|
||||
hasattr(self, 'partner_latitude') and |
|
||||
self.partner_latitude and |
|
||||
self.partner_longitude and |
|
||||
start_partner.partner_latitude and |
|
||||
start_partner.partner_longitude): |
|
||||
url = self._prepare_url( |
|
||||
map_website.route_lat_lon_url, { |
|
||||
'{START_LATITUDE}': start_partner.partner_latitude, |
|
||||
'{START_LONGITUDE}': start_partner.partner_longitude, |
|
||||
'{DEST_LATITUDE}': self.partner_latitude, |
|
||||
'{DEST_LONGITUDE}': self.partner_longitude}) |
|
||||
else: |
|
||||
if not map_website.route_address_url: |
|
||||
raise Warning( |
|
||||
_("Missing route URL that uses the addresses " |
|
||||
"for the map website '%s'") % map_website.name) |
|
||||
url = self._prepare_url( |
|
||||
map_website.route_address_url, { |
|
||||
'{START_ADDRESS}': start_partner._address_as_string(), |
|
||||
'{DEST_ADDRESS}': self._address_as_string()}) |
|
||||
return { |
|
||||
'type': 'ir.actions.act_url', |
|
||||
'url': url, |
|
||||
'target': 'new', |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# © 2015 Akretion (http://www.akretion.com) |
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com> |
|
||||
|
|
||||
from openerp import SUPERUSER_ID |
|
||||
|
|
||||
|
|
||||
def set_default_map_settings(cr, pool): |
|
||||
pool['res.users']._default_map_settings(cr, SUPERUSER_ID) |
|
||||
return |
|
Before Width: 128 | Height: 128 | Size: 9.2 KiB After Width: 128 | Height: 128 | Size: 16 KiB |
2887
partner_external_map/static/description/icon.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue