@ -0,0 +1,25 @@ |
|||||
|
==================== |
||||
|
User Weather Map v10 |
||||
|
==================== |
||||
|
|
||||
|
This module provides a weather notification for every users. |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
Make sure you have ``pytemperature`` Python module installed:: |
||||
|
|
||||
|
$ pip install pytemperature |
||||
|
|
||||
|
Make an account in "openweathermap.org", generate a API Key. |
||||
|
|
||||
|
Features |
||||
|
======== |
||||
|
|
||||
|
* User can get the weather notification. |
||||
|
* User can configure there weather notification. |
||||
|
* User's place can set by address or coordinates. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
Nikhil Krishnan @ cybrosys, nikhil@cybrosys.in |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Nikhil krishnan(<https://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import models |
@ -0,0 +1,48 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Nikhil krishnan(<https://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
{ |
||||
|
'name': 'User Weather Map', |
||||
|
'version': '10.0.1.0', |
||||
|
'summary': """Get User's Weather From OpenWeatherMap Automatically.""", |
||||
|
'description': """Get User's Weather and Temperature From OpenWeatherMap Automatically.""", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'website': 'http://www.cybrosys.com', |
||||
|
'category': 'Tools', |
||||
|
'depends': ['base'], |
||||
|
'external_dependencies': {'python': ['pytemperature']}, |
||||
|
'license': 'LGPL-3', |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'views/weather_template.xml', |
||||
|
'views/weather_conf.xml', |
||||
|
], |
||||
|
'demo': [], |
||||
|
'qweb': [ |
||||
|
"static/src/xml/weather_topbar.xml", |
||||
|
], |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Nikhil krishnan(<https://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import weather |
@ -0,0 +1,413 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>). |
||||
|
# Author: Nikhil krishnan(<http://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
import pytz |
||||
|
from pytz import timezone |
||||
|
from dateutil.relativedelta import relativedelta |
||||
|
from datetime import datetime |
||||
|
|
||||
|
try: |
||||
|
import pytemperature |
||||
|
except ImportError: |
||||
|
print 'pytemperature, this python package is not available. please install by using ' \ |
||||
|
'==> pip install pytemperature' |
||||
|
pass |
||||
|
|
||||
|
try: |
||||
|
import simplejson as json |
||||
|
except ImportError: |
||||
|
import json # noqa |
||||
|
import urllib |
||||
|
|
||||
|
import odoo |
||||
|
from odoo import models, fields, api |
||||
|
from odoo import tools |
||||
|
from odoo.tools.translate import _ |
||||
|
|
||||
|
|
||||
|
class UserWeatherMap(models.Model): |
||||
|
_name = 'user.weather.map' |
||||
|
|
||||
|
date_weather_update = fields.Datetime(string='Last update') |
||||
|
name = fields.Char(string='City Name') |
||||
|
city = fields.Char(string='Original City') |
||||
|
user_id = fields.Many2one('res.users', string='User Name') |
||||
|
weather = fields.Char(string='Weather') |
||||
|
description = fields.Char(string='Description') |
||||
|
temp = fields.Char(string='Temperature') |
||||
|
pressure = fields.Char(string='Pressure') |
||||
|
humidity = fields.Char(string='Humidity') |
||||
|
min_temp = fields.Char(string='Minimum') |
||||
|
max_temp = fields.Char(string='Maximum') |
||||
|
sunset = fields.Char(string='Sunset') |
||||
|
sunrise = fields.Char(string='Sunrise') |
||||
|
|
||||
|
def get_weather_data(self, user_id): |
||||
|
user_list = self.env['res.users'].search([('id', '=', user_id)]) |
||||
|
if user_list.partner_id.tz: |
||||
|
rec = self.search([('user_id', '=', user_id)], limit=1) |
||||
|
tz = pytz.timezone(user_list.partner_id.tz) |
||||
|
now_utc = datetime.now(timezone('UTC')) |
||||
|
now_pacific = now_utc.astimezone(timezone(str(tz))) |
||||
|
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p') |
||||
|
current_date = now_pacific.strftime('%d %B %Y') |
||||
|
if rec: |
||||
|
current_date_time = datetime.strptime(current_time, '%d %B %Y, %I:%M%p') |
||||
|
last_update = datetime.strptime(rec.date_weather_update, '%Y-%m-%d %H:%M:%S') |
||||
|
new_update_allowed_time = last_update + relativedelta(minutes=1) |
||||
|
if current_date_time > new_update_allowed_time: |
||||
|
get_weather = self.get_weather(user_id) |
||||
|
if get_weather: |
||||
|
if get_weather['issue'] == 'bad_request': |
||||
|
return { |
||||
|
'issue': 'Bad Request' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'internet': |
||||
|
return { |
||||
|
'issue': 'Connection ERROR.!' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'localization': |
||||
|
return { |
||||
|
'issue': 'longitude and latitude or address issue.' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'config': |
||||
|
return { |
||||
|
'issue': 'Weather configuration not set yet.' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'timezone': |
||||
|
return { |
||||
|
'issue': 'Timezone is not available' |
||||
|
} |
||||
|
else: |
||||
|
rec = self.search([('user_id', '=', user_id)], limit=1) |
||||
|
else: |
||||
|
pass |
||||
|
|
||||
|
if rec: |
||||
|
vals = { |
||||
|
'date_now': current_date, |
||||
|
'date_weather_update': rec.date_weather_update, |
||||
|
'name': rec.name, |
||||
|
'city': rec.city, |
||||
|
'user_id': rec.user_id.id, |
||||
|
'weather': rec.weather, |
||||
|
'description': rec.description, |
||||
|
'temp': rec.temp, |
||||
|
'pressure': rec.pressure, |
||||
|
'humidity': rec.humidity, |
||||
|
'min_temp': rec.min_temp, |
||||
|
'max_temp': rec.max_temp, |
||||
|
'issue': '', |
||||
|
} |
||||
|
return vals |
||||
|
else: |
||||
|
get_weather = self.get_weather(user_id) |
||||
|
if get_weather['issue'] == 'bad_request': |
||||
|
return { |
||||
|
'issue': 'Bad Request' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'internet': |
||||
|
return { |
||||
|
'issue': 'Connection ERROR.!' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'localization': |
||||
|
return { |
||||
|
'issue': 'Set correct Location' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'config': |
||||
|
return { |
||||
|
'issue': 'Weather configuration not set yet.' |
||||
|
} |
||||
|
elif get_weather['issue'] == 'timezone': |
||||
|
return { |
||||
|
'issue': 'Timezone is not available' |
||||
|
} |
||||
|
else: |
||||
|
rec = self.search([('user_id', '=', user_id)], limit=1) |
||||
|
if rec: |
||||
|
vals = { |
||||
|
'date_now': current_date, |
||||
|
'date_weather_update': rec.date_weather_update, |
||||
|
'name': rec.name, |
||||
|
'city': rec.city, |
||||
|
'user_id': rec.user_id.id, |
||||
|
'weather': rec.weather, |
||||
|
'description': rec.description, |
||||
|
'temp': rec.temp, |
||||
|
'pressure': rec.pressure, |
||||
|
'humidity': rec.humidity, |
||||
|
'min_temp': rec.min_temp, |
||||
|
'max_temp': rec.max_temp, |
||||
|
'issue': '', |
||||
|
} |
||||
|
return vals |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'Bad request' |
||||
|
} |
||||
|
|
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'Timezone is not available' |
||||
|
} |
||||
|
|
||||
|
def get_weather(self, user_id): |
||||
|
rec = self.env['user.weather.map.config'].search([('user_id', '=', user_id)], limit=1) |
||||
|
if rec: |
||||
|
weather_path = 'http://api.openweathermap.org/data/2.5/weather?' |
||||
|
if rec.u_longitude and rec.u_latitude: |
||||
|
params = urllib.urlencode( |
||||
|
{'lat': rec.u_latitude, 'lon': rec.u_longitude, 'APPID': rec.appid}) |
||||
|
elif rec.city: |
||||
|
params = urllib.urlencode( |
||||
|
{'q': rec.city, 'APPID': rec.appid}) |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'localization' |
||||
|
} |
||||
|
|
||||
|
url = weather_path + params |
||||
|
try: |
||||
|
f = urllib.urlopen(url) |
||||
|
except Exception: |
||||
|
f = False |
||||
|
if f: |
||||
|
ret = f.read().decode('utf-8') |
||||
|
result = json.loads(ret) |
||||
|
if result: |
||||
|
if "cod" in result.keys(): |
||||
|
if result['cod'] == 200: |
||||
|
city = False |
||||
|
city2 = False |
||||
|
if "name" in result.keys(): |
||||
|
city = result['name'] |
||||
|
if not city: |
||||
|
if rec.method == 'address': |
||||
|
city = rec.city |
||||
|
if rec.method == 'address': |
||||
|
city2 = rec.city |
||||
|
|
||||
|
temp = pytemperature.k2c(result['main']['temp']) |
||||
|
min_temp = pytemperature.k2c(result['main']['temp_min']) |
||||
|
max_temp = pytemperature.k2c(result['main']['temp_max']) |
||||
|
weather_rec = self.search([('user_id', '=', rec.user_id.id)]) |
||||
|
now_utc = datetime.now(timezone('UTC')) |
||||
|
user_list = self.env['res.users'].search([('id', '=', user_id)]) |
||||
|
if user_list.partner_id.tz: |
||||
|
tz = pytz.timezone(user_list.partner_id.tz) |
||||
|
now_pacific = now_utc.astimezone(timezone(str(tz))) |
||||
|
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p') |
||||
|
vals = { |
||||
|
'date_weather_update': current_time, |
||||
|
'name': city, |
||||
|
'city': city2, |
||||
|
'user_id': user_id, |
||||
|
'weather': result['weather'][0]['main'], |
||||
|
'description': result['weather'][0]['description'], |
||||
|
'temp': temp, |
||||
|
'pressure': result['main']['pressure'], |
||||
|
'humidity': result['main']['humidity'], |
||||
|
'min_temp': min_temp, |
||||
|
'max_temp': max_temp, |
||||
|
} |
||||
|
if weather_rec: |
||||
|
weather_rec.write(vals) |
||||
|
return { |
||||
|
'issue': '' |
||||
|
} |
||||
|
else: |
||||
|
weather_rec.create(vals) |
||||
|
return { |
||||
|
'issue': '' |
||||
|
} |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'timezone' |
||||
|
} |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'localization' |
||||
|
} |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'bad_request' |
||||
|
} |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'internet' |
||||
|
} |
||||
|
else: |
||||
|
return { |
||||
|
'issue': 'config' |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class UserWeatherMapConfig(models.Model): |
||||
|
_name = 'user.weather.map.config' |
||||
|
_inherit = 'res.config.settings' |
||||
|
_rec_name = 'user_id' |
||||
|
|
||||
|
def _default_street(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.street |
||||
|
|
||||
|
def _default_city(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.city |
||||
|
|
||||
|
def _default_state_id(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.state_id.id |
||||
|
|
||||
|
def _default_country_id(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.country_id.id |
||||
|
|
||||
|
def _default_zip(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.zip |
||||
|
|
||||
|
def _default_appid(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.appid |
||||
|
|
||||
|
def _default_method(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
return rec.method |
||||
|
else: |
||||
|
return 'address' |
||||
|
|
||||
|
def _default_longitude(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
if rec.method == 'coordinates': |
||||
|
return rec.u_longitude |
||||
|
else: |
||||
|
return '' |
||||
|
|
||||
|
def _default_latitude(self): |
||||
|
rec = self.search([('user_id', '=', self.env.user.id)]) |
||||
|
if rec: |
||||
|
if rec.method == 'coordinates': |
||||
|
return rec.u_latitude |
||||
|
else: |
||||
|
return '' |
||||
|
|
||||
|
user_id = fields.Many2one('res.users', string='User Name', readonly=True, default=lambda self: self.env.user.id) |
||||
|
u_longitude = fields.Char(string='Longitude', default=_default_longitude) |
||||
|
u_latitude = fields.Char(string='Latitude', default=_default_latitude) |
||||
|
|
||||
|
street = fields.Char('Street', default=_default_street) |
||||
|
zip = fields.Char('Zip', size=24, change_default=True, default=_default_zip) |
||||
|
city = fields.Char('City', default=_default_city) |
||||
|
state_id = fields.Many2one("res.country.state", string='State', ondelete='restrict', default=_default_state_id) |
||||
|
country_id = fields.Many2one('res.country', string='Country', ondelete='restrict', default=_default_country_id) |
||||
|
appid = fields.Char('App id', default=_default_appid, required=True, |
||||
|
help="Just sign up the OpenWeatherMap. Generate a Weather Key and provide here.") |
||||
|
method = fields.Selection([('address', 'By Address'), |
||||
|
('coordinates', 'By geolocation')], string='Type', default=_default_method) |
||||
|
|
||||
|
@api.multi |
||||
|
def onchange_state(self, state_id): |
||||
|
if state_id: |
||||
|
state = self.env['res.country.state'].browse(state_id) |
||||
|
return {'value': {'country_id': state.country_id.id}} |
||||
|
return {} |
||||
|
|
||||
|
|
||||
|
@api.multi |
||||
|
def execute_weather(self): |
||||
|
val = 0 |
||||
|
recs = self.search([('user_id', '=', self.user_id.id)]) |
||||
|
for rec1 in recs: |
||||
|
if val < rec1.id: |
||||
|
val = rec1.id |
||||
|
for rec2 in recs: |
||||
|
if val != rec2.id: |
||||
|
rec2.unlink() |
||||
|
if self.method == 'address': |
||||
|
self.geo_localize() |
||||
|
else: |
||||
|
pass |
||||
|
self.env['user.weather.map'].get_weather(self.user_id.id) |
||||
|
return { |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': '/web', |
||||
|
'target': 'self', |
||||
|
} |
||||
|
|
||||
|
def geo_query_address(self, street=None, zip=None, city=None, state=None, country=None): |
||||
|
if country and ',' in country and (country.endswith(' of') or country.endswith(' of the')): |
||||
|
# put country qualifier in front, otherwise GMap gives wrong results, |
||||
|
# e.g. 'Congo, Democratic Republic of the' => 'Democratic Republic of the Congo' |
||||
|
country = '{1} {0}'.format(*country.split(',', 1)) |
||||
|
return tools.ustr(', '.join(filter(None, [street, |
||||
|
("%s %s" % (zip or '', city or '')).strip(), |
||||
|
state, |
||||
|
country]))) |
||||
|
|
||||
|
def geo_find(self, addr): |
||||
|
url = 'https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=' |
||||
|
url += urllib.quote(addr.encode('utf8')) |
||||
|
try: |
||||
|
result = json.load(urllib.urlopen(url)) |
||||
|
except Exception, e: |
||||
|
raise odoo.exceptions.except_orm(_('Network error'), |
||||
|
_('Cannot contact geolocation servers. ' |
||||
|
'Please make sure that your internet connection is up and running (%s).') % e) |
||||
|
if result['status'] != 'OK': |
||||
|
return None |
||||
|
|
||||
|
try: |
||||
|
geo = result['results'][0]['geometry']['location'] |
||||
|
return float(geo['lat']), float(geo['lng']) |
||||
|
except (KeyError, ValueError): |
||||
|
return None |
||||
|
|
||||
|
@api.one |
||||
|
def geo_localize(self): |
||||
|
# Don't pass context to browse()! We need country names in english below |
||||
|
result = self.geo_find(self.geo_query_address(street=self.street, |
||||
|
zip=self.zip, |
||||
|
city=self.city, |
||||
|
state=self.state_id.name, |
||||
|
country=self.country_id.name)) |
||||
|
if result: |
||||
|
self.write({ |
||||
|
'u_latitude': result[0], |
||||
|
'u_longitude': result[1], |
||||
|
}, ) |
||||
|
else: |
||||
|
if self.method == 'address': |
||||
|
self.write({ |
||||
|
'u_latitude': '', |
||||
|
'u_longitude': '', |
||||
|
}, ) |
||||
|
return True |
|
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,222 @@ |
|||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan">User Weather Notification</h2> |
||||
|
<h3 class="oe_slogan">Real time Weather updates</h3> |
||||
|
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a> </h4> |
||||
|
<div> |
||||
|
<h4><p>Features:</p></h4> |
||||
|
<ul> |
||||
|
<li style="list-style:none !important;"><span style="color:green;"> ☑</span> The user will get the weather notification.</li> |
||||
|
<li style="list-style:none !important;"> |
||||
|
<span style="color:green;"> ☑</span> The user can configure their weather notification. |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4><p>Required:</p></h4> |
||||
|
<ul> |
||||
|
<li style="list-style:none !important;"><span style="color:red;"> ☑</span> Account in Open Weather Map and its API Key.</li> |
||||
|
<li style="list-style:none !important;"> |
||||
|
<span style="color:red;"> ☑</span> 'pytemperature' python package is needed. please install in ubuntu by using ==> pip install pytemperature. |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">Overview</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<p class="oe_mt32"> |
||||
|
As we know, many industries are depending on weather conditions like manufacturing, |
||||
|
Event Management, Construction etc. So we believe our concept of weather module can be used |
||||
|
in these industries to understand and plan their works according to the weather condition. |
||||
|
This module is a starter to think and explore the opportunity to bring the advanced features |
||||
|
in Odoo. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">Weather notification in Odoo</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="weather Board.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="oe_span12"> |
||||
|
<p class="oe_mt32"/> |
||||
|
<p class="oe_mt32"> |
||||
|
User can easily find the weather report from a single click. Summary of the weather |
||||
|
conditions is displayed on the weather board. The user will easily get weather updates, |
||||
|
state of climate and current temperature etc.. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan" style="color:#875A7B;">Enjoy advanced and automated weather update</h2> |
||||
|
<h3 class="oe_slogan">The most advanced weather notification in a very simple user interface |
||||
|
</h3> |
||||
|
<p class="oe_mt32 oe_mb64 lead text-center"> |
||||
|
Avoid search for weather updates, get it in a single click. |
||||
|
This module integrates the weather into the Odoo system. |
||||
|
</p> |
||||
|
<div class="oe_span4"> |
||||
|
<div class="text-center"> |
||||
|
<span class="fa fa-users fa-4x"/> |
||||
|
<h4 class="oe_mt16 oe_mb16"> |
||||
|
<b>Users</b> |
||||
|
</h4> |
||||
|
</div> |
||||
|
<p class="text-justify"> |
||||
|
Nowadays everyone is searching temperature and weather conditions in their city or any other |
||||
|
location by using search engines, here we have a very flexible way to find out it easily through |
||||
|
our module without any surfing. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="oe_span4"> |
||||
|
<div class="text-center"> |
||||
|
<span class="fa fa-cog fa-4x"/> |
||||
|
<h4 class="oe_mt16 oe_mb16"> |
||||
|
<b>Settings</b> |
||||
|
</h4> |
||||
|
</div> |
||||
|
<p class="text-justify"> |
||||
|
User can specify their current location or any location by providing address or coordinates. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="oe_span4"> |
||||
|
<div class="text-center"> |
||||
|
<span class="fa fa-circle-o fa-4x" style="color:#875a7b;"/> |
||||
|
<span class="fa fa-long-arrow-left fa-3x"/> |
||||
|
<span class="fa fa-cloud fa-4x" style="color:#ce671c;"/> |
||||
|
<h4 class="oe_mt16 oe_mb16"> |
||||
|
<b>Open Weather Map</b> |
||||
|
</h4> |
||||
|
</div> |
||||
|
<p class="text-justify"> |
||||
|
openweathermap.org is providing weather APIs calls and response. Odoo is using this API and provides |
||||
|
you the best result by the help of our application. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">How to configure your weather?</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="settings.png"> |
||||
|
</div> |
||||
|
<p class="oe_mt32"> |
||||
|
Click on the setting (<span class="fa fa-cog fa-1x"/>) button. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="config.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_span12"> |
||||
|
<p class="oe_mt32"> |
||||
|
Users can give address of the place or coordinates by selecting the type, |
||||
|
<p> |
||||
|
If you are selecting the address type, please provide the address and If it is coordinate, |
||||
|
then give the correct longitude and latitude. |
||||
|
</p> |
||||
|
</p> |
||||
|
<p class="oe_mt32"> |
||||
|
Provide the correct API key received from the OpenWeatherMap site. |
||||
|
</p> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">How to get API KEY?</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
Click on the Sing up (<span class="fa fa-sign-in fa-1x"/>) button. |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="sign up.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
It will go to the account creation page of Open Weather Map |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="sign_up_weather_map.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
Fill the required fields and create an account. |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="fill.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
Once we created the account, we can use the default API Key providing by Open Weather Map or |
||||
|
else you have an option for generating your own API Key manually. |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<div class="oe_row_img oe_centered"> |
||||
|
<img class="oe_picture oe_screenshot" src="api.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> |
||||
|
<div class="oe_slogan" style="margin-top:10px !important;"> |
||||
|
<div> |
||||
|
<a class="btn btn-primary btn-lg mt8" |
||||
|
style="color: #FFFFFF !important;border-radius: 0;" href="http://www.cybrosys.com"><i |
||||
|
class="fa fa-envelope"></i> Email </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="http://www.cybrosys.com/contact/"><i |
||||
|
class="fa fa-phone"></i> Contact Us </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="http://www.cybrosys.com/odoo-customization-and-installation/"><i |
||||
|
class="fa fa-check-square"></i> Request Customization </a> |
||||
|
</div> |
||||
|
<br> |
||||
|
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> |
||||
|
<div> |
||||
|
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td> |
||||
|
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td> |
||||
|
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 21 KiB |
@ -0,0 +1,77 @@ |
|||||
|
|
||||
|
.oe_webclient_notification_action t { |
||||
|
color: white; |
||||
|
} |
||||
|
.oe_webclient_notification_action p { |
||||
|
color: white; |
||||
|
margin-top: 1em; |
||||
|
} |
||||
|
.label { |
||||
|
display: inline-block; |
||||
|
color: black; |
||||
|
max-width: 100%; |
||||
|
margin-bottom: 5px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.reminder-dropdown { |
||||
|
.o-flex(0, 1, auto); |
||||
|
background: #FFFFFF; |
||||
|
max-height: 400px; |
||||
|
min-height: 50px; |
||||
|
overflow-y: auto; |
||||
|
|
||||
|
@media (max-width: @screen-xs-max) { |
||||
|
max-height: none; |
||||
|
} |
||||
|
.weather_notification { |
||||
|
width: 100%; |
||||
|
background: #eeeeee; |
||||
|
} |
||||
|
.weather_settings { |
||||
|
float:left; |
||||
|
text-align: right; |
||||
|
width:100%; |
||||
|
} |
||||
|
|
||||
|
.fa-sign-in:hover { |
||||
|
opacity:.5; |
||||
|
} |
||||
|
|
||||
|
.fa-cog{ |
||||
|
-webkit-transition: -webkit-transform .8s ease-in-out; |
||||
|
transition: transform .8s ease-in-out; |
||||
|
} |
||||
|
|
||||
|
.fa-cog:hover{ |
||||
|
-webkit-transform: rotate(360deg); |
||||
|
transform: rotate(360deg) ; |
||||
|
} |
||||
|
|
||||
|
.weather_content{ |
||||
|
width: 100%; |
||||
|
float: left; |
||||
|
padding-left: 5%; |
||||
|
padding-top: 4%; |
||||
|
padding-bottom: 5%; |
||||
|
|
||||
|
|
||||
|
} |
||||
|
.weather_content p{ |
||||
|
margin:2px 0 4px 0; |
||||
|
color: #808080; |
||||
|
font-size: 11px; |
||||
|
} |
||||
|
.weather_content h1{ |
||||
|
margin:0px; |
||||
|
font-size: 26px; |
||||
|
padding: 3px 0 3px 0; |
||||
|
} |
||||
|
.detail-client-address-country { |
||||
|
color: black; |
||||
|
} |
||||
|
.warning h4{ |
||||
|
color: #d21010; |
||||
|
font-weight: 100; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 998 B |
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,66 @@ |
|||||
|
odoo.define('user_weather_map.weather_notification', function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var core = require('web.core'); |
||||
|
var SystrayMenu = require('web.SystrayMenu'); |
||||
|
var Widget = require('web.Widget'); |
||||
|
var Model = require('web.DataModel'); |
||||
|
var QWeb = core.qweb; |
||||
|
|
||||
|
var weather_menu = Widget.extend({ |
||||
|
template:'user_weather_map.weather_menu', |
||||
|
|
||||
|
events: { |
||||
|
"click .dropdown-toggle": "on_click_weather_board", |
||||
|
"click .fa-cog": "go_to_weather_settings", |
||||
|
}, |
||||
|
|
||||
|
init:function(parent, name){ |
||||
|
this.widget = {}; |
||||
|
this.reminder = null; |
||||
|
this._super(parent); |
||||
|
}, |
||||
|
|
||||
|
render_widget: function() { |
||||
|
var self = this; |
||||
|
var user = self.session.uid; |
||||
|
var weather = new Model('user.weather.map'); |
||||
|
new Model("user.weather.map").call("get_weather_data",['',user]).then(function(data){ |
||||
|
var weather = QWeb.render("WeatherDetails", {widget:self, |
||||
|
date_now: data.date_now, |
||||
|
date_weather_update: data.date_weather_update, |
||||
|
name: data.name, |
||||
|
city: data.city, |
||||
|
user_id: data.user_id, |
||||
|
weather: data.weather, |
||||
|
description: data.description, |
||||
|
temp: data.temp, |
||||
|
pressure: data.pressure, |
||||
|
humidity: data.humidity, |
||||
|
min_temp: data.min_temp, |
||||
|
max_temp: data.max_temp, |
||||
|
issue: data.issue, |
||||
|
}); |
||||
|
$('.weather_notification').html(weather); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
go_to_weather_settings: function (event) { |
||||
|
var action = { |
||||
|
type: 'ir.actions.act_window', |
||||
|
res_model: 'user.weather.map.config', |
||||
|
view_mode: 'form', |
||||
|
target:'inline', |
||||
|
views: [[false, 'form']], |
||||
|
}; |
||||
|
this.do_action(action); |
||||
|
}, |
||||
|
|
||||
|
on_click_weather_board: function (event) { |
||||
|
this.render_widget(); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
SystrayMenu.Items.push(weather_menu); |
||||
|
}); |
@ -0,0 +1,120 @@ |
|||||
|
// Navbar icon and dropdown |
||||
|
.o_weather_navbar_item { |
||||
|
> a { |
||||
|
opacity: 1; |
||||
|
float: left; |
||||
|
> i { |
||||
|
font-size: larger; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
&.open .o_weather_navbar_dropdown { |
||||
|
.o-flex-display(); |
||||
|
.o-flex-flow(column, nowrap); |
||||
|
} |
||||
|
.weather_board{ |
||||
|
width: auto; |
||||
|
float: left; |
||||
|
font-size: 16px; |
||||
|
text-align:right; |
||||
|
} |
||||
|
.o_weather_navbar_dropdown { |
||||
|
width: 310px; |
||||
|
padding: 0; |
||||
|
|
||||
|
.o_spinner { |
||||
|
.o-flex-display(); |
||||
|
.o-align-items(center); |
||||
|
.o-justify-content(center); |
||||
|
color: @odoo-main-text-color; |
||||
|
height: 50px; |
||||
|
} |
||||
|
|
||||
|
.o_mail_navbar_dropdown_top { |
||||
|
.o-flex-display(); |
||||
|
.o-flex(0, 0, auto); |
||||
|
justify-content: space-between; |
||||
|
border-bottom: 1px solid lightgray; |
||||
|
|
||||
|
.o_filter_button, .o_new_message { |
||||
|
.btn-link; |
||||
|
padding: 5px; |
||||
|
} |
||||
|
.o_filter_button { |
||||
|
color: @odoo-main-color-muted; |
||||
|
&:hover, &.o_selected { |
||||
|
color: @odoo-brand-optional; |
||||
|
} |
||||
|
&.o_selected { |
||||
|
cursor: default; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.o_mail_navbar_dropdown_channels { |
||||
|
.o-flex(0, 1, auto); |
||||
|
max-height: 400px; |
||||
|
min-height: 50px; |
||||
|
overflow-y: auto; |
||||
|
|
||||
|
@media (max-width: @screen-xs-max) { |
||||
|
max-height: none; |
||||
|
} |
||||
|
|
||||
|
.o_mail_channel_preview { |
||||
|
.o-flex-display(); |
||||
|
height: 50px; |
||||
|
align-items: center; |
||||
|
padding: 5px; |
||||
|
cursor: pointer; |
||||
|
font-size: 12px; |
||||
|
overflow: hidden; |
||||
|
&~.o_mail_channel_preview { |
||||
|
border-top: 1px solid lightgray; |
||||
|
} |
||||
|
&.o_channel_unread { |
||||
|
background-color: lighten(lightgray, 10%); |
||||
|
} |
||||
|
&:hover { |
||||
|
background-color: lighten(lightgray, 5%); |
||||
|
} |
||||
|
|
||||
|
.o_channel_image { |
||||
|
.o-flex(0, 0, 36px); |
||||
|
max-height: 36px; |
||||
|
} |
||||
|
.o_channel_info { |
||||
|
.o-flex(1, 1, 100%); |
||||
|
margin-left: 5px; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.o_channel_title { |
||||
|
.o-flex-display(); |
||||
|
.o_channel_name { |
||||
|
.o-flex(1, 1, auto); |
||||
|
.o-text-overflow(); |
||||
|
color: @odoo-main-text-color; |
||||
|
} |
||||
|
.o_last_message_date { |
||||
|
.o-flex(0, 0, auto); |
||||
|
padding-top: 3px; |
||||
|
font-size: xx-small; |
||||
|
color: @odoo-main-color-muted; |
||||
|
} |
||||
|
} |
||||
|
.o_last_message_preview { |
||||
|
width: 100%; |
||||
|
color: @odoo-main-color-muted; |
||||
|
.o-text-overflow(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.o_no_chat_window .o_mail_navbar_dropdown .o_new_message { |
||||
|
display: none; // hide 'new message' button if chat windows are disabled |
||||
|
} |
@ -0,0 +1,95 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<t t-name="user_weather_map.weather_menu"> |
||||
|
<li class="o_weather_navbar_item"> |
||||
|
<a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#" title="Weather"> |
||||
|
<div class="weather_board"><i class="fa fa-fw fa-cloud"/></div> |
||||
|
</a> |
||||
|
|
||||
|
<ul class="o_weather_navbar_dropdown dropdown-menu" role="menu"> |
||||
|
<li class="o_weather_navbar_dropdown_top"> |
||||
|
<div class="weather_notification"/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</li> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="WeatherDetails"> |
||||
|
<div class="weather_notification"> |
||||
|
<div> |
||||
|
<div class="weather_settings"> |
||||
|
<a title="Sign up" href="http://home.openweathermap.org/users/sign_up"> |
||||
|
<i class="fa fa-fw fa-sign-in"/> |
||||
|
</a> |
||||
|
<i title="Settings" class="fa fa-fw fa-cog"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="weather_content"> |
||||
|
<div class="col-md-8"> |
||||
|
<t t-if="date_now"> |
||||
|
<p> |
||||
|
<t t-raw="date_now"/> |
||||
|
</p> |
||||
|
</t> |
||||
|
<t t-if="! issue"> |
||||
|
<t t-if="max_temp"> |
||||
|
<t t-if="min_temp"> |
||||
|
<p>Day <t t-raw="max_temp"/>° <i class="fa fa-long-arrow-up" aria-hidden="true"></i>, |
||||
|
Night <t t-raw="min_temp"/>° <i class="fa fa-long-arrow-down" aria-hidden="true"></i> |
||||
|
</p> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-if="temp"> |
||||
|
<h1><t t-raw="temp"/>° <t t-if="weather"><t t-raw="weather"/></t></h1> |
||||
|
</t> |
||||
|
<t t-if="description"> |
||||
|
<p><t t-raw="description"/> <t t-if="name"> in <t t-raw="name"/></t></p> |
||||
|
</t> |
||||
|
<t t-if="city"> |
||||
|
<p>Near &nbsp;<t t-raw="city"/></p> |
||||
|
</t> |
||||
|
<t t-if="date_weather_update"> |
||||
|
last update:<p><t t-raw="date_weather_update"/></p> |
||||
|
</t> |
||||
|
</t> |
||||
|
<!--********************IF you need you can show the pressure,humidity etc.********************--> |
||||
|
</div> |
||||
|
|
||||
|
<t t-if="! issue"> |
||||
|
<div class="col-md-4" style="padding-top: 6%;padding-left: 0px;"> |
||||
|
<t t-if="weather =='Clouds'"> |
||||
|
<img src="/user_weather_map/static/src/img/cloud.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Rain'"> |
||||
|
<img src="/user_weather_map/static/src/img/rain.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Clear'"> |
||||
|
<img src="/user_weather_map/static/src/img/sun.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Haze'"> |
||||
|
<img src="/user_weather_map/static/src/img/haze.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Mist'"> |
||||
|
<img src="/user_weather_map/static/src/img/mist.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Snow'"> |
||||
|
<img src="/user_weather_map/static/src/img/snow.png"></img> |
||||
|
</t> |
||||
|
<t t-if="weather =='Extreme'"> |
||||
|
<img src="/user_weather_map/static/src/img/haze.png"></img> |
||||
|
</t> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
<t t-if="issue"> |
||||
|
<div class="col-md-8 warning" style="padding-top: 6%;padding-left: 0px;"> |
||||
|
<h4><t t-raw="issue"/></h4> |
||||
|
</div> |
||||
|
<div class="col-md-4" style="padding-top: 0%;padding-left: 0px;"> |
||||
|
<img src="/user_weather_map/static/src/img/cloud-warning.png"></img> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,49 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="action_weather_conf_form" model="ir.ui.view"> |
||||
|
<field name="name">user.weather.map.conf.form</field> |
||||
|
<field name="model">user.weather.map.config</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Configure Weather" class="oe_form_configuration"> |
||||
|
<header> |
||||
|
<button string="Apply" type="object" name="execute_weather" class="oe_highlight"/> |
||||
|
</header> |
||||
|
<separator string="Weather" groups="base.group_user"/> |
||||
|
<group name="Weather" groups="base.group_user"> |
||||
|
<group> |
||||
|
<field name="user_id" /> |
||||
|
<field name="method" widget="radio"/> |
||||
|
<label for="street" string="Address"/> |
||||
|
<div> |
||||
|
<field name="street" placeholder="Street..." /> |
||||
|
<div class="address_format"> |
||||
|
<field name="city" placeholder="City" style="width: 40%" /> |
||||
|
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%" options="{"no_open": True}" on_change="onchange_state(state_id)" domain="[('country_id','=',country_id)]" /> |
||||
|
<field name="zip" placeholder="ZIP" style="width: 20%" /> |
||||
|
</div> |
||||
|
<field name="country_id" placeholder="Country" class="oe_no_button" options="{"no_open": True}" /> |
||||
|
</div> |
||||
|
<field name="appid" /> |
||||
|
</group> |
||||
|
|
||||
|
<group> |
||||
|
<group colspan="2" col="2"> |
||||
|
<separator string="Geo Localization" colspan="2"/> |
||||
|
<field name="u_longitude" attrs="{'required':[('method','!=','address')]}"/> |
||||
|
<field name="u_latitude" attrs="{'required':[('method','!=','address')]}"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="action_weather_config" model="ir.actions.act_window"> |
||||
|
<field name="name">Weather Settings</field> |
||||
|
<field name="res_model">user.weather.map.config</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">inline</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<template id="assets_backend" name="mail assets" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<link rel="stylesheet" href="/user_weather_map/static/src/css/notification.css"/> |
||||
|
<link rel="stylesheet" href="/user_weather_map/static/src/less/weather.less"/> |
||||
|
<script type="text/javascript" src="/user_weather_map/static/src/js/weather_notification.js"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</openerp> |