Browse Source

[IMP] website_shift: Refactor templates

Refactor templates to avoid dupplicate code.
Refactor the controller to match with new templates.
Add license.
pull/33/head
Rémy Taymans 6 years ago
parent
commit
b4483cc32f
  1. 10
      beesdoo_website_shift/__openerp__.py
  2. 252
      beesdoo_website_shift/controllers/main.py
  3. 4
      beesdoo_website_shift/data/res_config_data.xml
  4. 3
      beesdoo_website_shift/models/res_config.py
  5. 532
      beesdoo_website_shift/views/my_shift_website_templates.xml
  6. 14
      beesdoo_website_shift/views/res_config_views.xml
  7. 637
      beesdoo_website_shift/views/shift_website_templates.xml

10
beesdoo_website_shift/__openerp__.py

@ -1,6 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Beescoop Shift Website',
'name': 'BEES coop Shift Website',
'summary': """
Show available shifts for regular and irregular workers in
@ -10,16 +14,18 @@
""",
'author': 'Rémy Taymans',
'license': 'AGPL-3',
'version': '9.0.1.0',
'website': "https://github.com/beescoop/Obeesdoo",
'category': 'Cooperative management',
'version': '0.1',
'depends': ['website', 'beesdoo_shift'],
'data': [
'data/res_config_data.xml',
'views/shift_website_templates.xml',
'views/my_shift_website_templates.xml',
'views/res_config_views.xml',
]
}

252
beesdoo_website_shift/controllers/main.py

@ -1,4 +1,9 @@
# -*- coding: utf8 -*-
# Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
# Copyright 2017-2018 Thibault François
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from ast import literal_eval
from datetime import datetime, timedelta
from itertools import groupby
@ -11,26 +16,57 @@ from openerp.addons.beesdoo_shift.models.planning import float_to_time
class WebsiteShiftController(http.Controller):
@http.route('/shift', auth='user', website=True)
def shift(self, **kwargs):
cur_user = request.env['res.users'].browse(request.uid)
working_mode = cur_user.partner_id.working_mode
if working_mode == 'irregular':
return self.shift_irregular_worker()
if working_mode == 'regular':
return self.shift_template_regular_worker()
if working_mode == 'exempt':
return self.shift_exempted_worker()
def is_user_irregular(self):
user = request.env['res.users'].browse(request.uid)
working_mode = user.partner_id.working_mode
return working_mode == 'irregular'
def is_user_regular(self):
user = request.env['res.users'].browse(request.uid)
working_mode = user.partner_id.working_mode
return working_mode == 'regular'
def is_user_exempted(self):
user = request.env['res.users'].browse(request.uid)
working_mode = user.partner_id.working_mode
return working_mode == 'exempt'
@http.route('/my/shift', auth='user', website=True)
def my_shift(self, **kw):
"""
Personnal page for managing your shifts
"""
if self.is_user_irregular():
return request.render(
'beesdoo_website_shift.my_shift_irregular_worker',
self.my_shift_irregular_worker(nexturl='/my/shift')
)
if self.is_user_regular():
return request.render(
'beesdoo_website_shift.my_shift_regular_worker',
self.my_shift_regular_worker()
)
if self.is_user_exempted():
return request.render(
'beesdoo_website_shift.my_shift_exempted_worker',
self.my_shift_exempted_worker()
)
return request.render(
'beesdoo_website_shift.shift',
{
'user': cur_user,
}
'beesdoo_website_shift.my_shift_non_worker',
{}
)
@http.route('/shift/<model("beesdoo.shift.shift"):shift>/subscribe', auth='user', website=True)
def subscribe_to_shift(self, shift=None, **kwargs):
def subscribe_to_shift(self, shift=None, **kw):
"""
Subscribe the current connected user into the given shift
This is done only if :
* shift sign up is authorised via configuration panel
* the current connected user is an irregular worker
* the given shift exist
* the shift is free for subscription
"""
# Get current user
cur_user = request.env['res.users'].browse(request.uid)
# Get config
@ -42,13 +78,112 @@ class WebsiteShiftController(http.Controller):
and shift
and not shift.worker_id):
shift.worker_id = cur_user.partner_id
return request.redirect(kwargs['nexturl'])
return request.redirect(kw['nexturl'])
@http.route('/shift_irregular_worker', auth='public', website=True)
def public_shift_irregular_worker(self, **kw):
"""
Show a public access page that show all the available shifts for irregular worker.
"""
nexturl = '/shift_irregular_worker'
irregular_enable_sign_up = False
# Create template context
template_context = {}
template_context.update(self.available_shift_irregular_worker(
irregular_enable_sign_up, nexturl
))
return request.render(
'beesdoo_website_shift.public_shift_irregular_worker',
template_context
)
@http.route('/shift_template_regular_worker', auth='public', website=True)
def public_shift_template_regular_worker(self, **kw):
"""
Show a public access page that show all the available shift templates for regular worker.
"""
# Get all the task template
template = request.env['beesdoo.shift.template']
task_templates = template.sudo().search([], order="planning_id, day_nb_id, start_time")
return request.render(
'beesdoo_website_shift.public_shift_template_regular_worker',
{
'task_templates': task_templates,
'float_to_time': float_to_time,
}
)
def shift_irregular_worker(self, **kwargs):
def my_shift_irregular_worker(self, nexturl=""):
"""
Return template variables for 'beesdoo_website_shift.my_shift_irregular_worker' template
"""
# Get current user
cur_user = request.env['res.users'].browse(request.uid)
cur_cooperative_status = cur_user.partner_id.cooperative_status_ids
# Get config
irregular_enable_sign_up = literal_eval(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.irregular_enable_sign_up'))
# Create template context
template_context = {}
template_context.update(self.my_shift_worker_status())
template_context.update(self.my_shift_next_shifts())
template_context.update(self.available_shift_irregular_worker(
irregular_enable_sign_up, nexturl
))
# Compute date before which the worker is up to date
today_date = fields.Date.from_string(cur_cooperative_status.today)
delta = (today_date - fields.Date.from_string(cur_cooperative_status.irregular_start_date)).days
date_before_last_shift = today_date + timedelta(days=(cur_cooperative_status.sr + 1) * 28 - delta % 28)
date_before_last_shift = date_before_last_shift.strftime('%Y-%m-%d')
template_context.update(
{
'date_before_last_shift': date_before_last_shift,
}
)
return template_context
def my_shift_regular_worker(self):
"""
Return template variables for 'beesdoo_website_shift.my_shift_regular_worker' template
"""
# Create template context
template_context = {}
# Get all the task template
template = request.env['beesdoo.shift.template']
task_templates = template.sudo().search([], order="planning_id, day_nb_id, start_time")
template_context.update(self.my_shift_worker_status())
template_context.update(self.my_shift_next_shifts())
template_context.update(
{
'task_templates': task_templates,
'float_to_time': float_to_time,
}
)
return template_context
def my_shift_exempted_worker(self):
"""
Return template variables for 'beesdoo_website_shift.my_shift_exempted_worker' template
"""
return self.my_shift_worker_status()
def available_shift_irregular_worker(self, irregular_enable_sign_up=False, nexturl=""):
"""
Return template variables for 'beesdoo_website_shift.available_shift_irregular_worker' template
"""
# Get current user
cur_user = request.env['res.users'].browse(request.uid)
# Get all the shifts in the future with no worker
now = datetime.now()
shifts = request.env['beesdoo.shift.shift'].sudo().search(
@ -64,12 +199,6 @@ class WebsiteShiftController(http.Controller):
order="start_time, task_template_id, task_type_id",
)
# Compute date before which the worker is up to date
today_date = fields.Date.from_string(cur_cooperative_status.today)
delta = (today_date - fields.Date.from_string(cur_cooperative_status.irregular_start_date)).days
date_before_last_shift = today_date + timedelta(days=(cur_cooperative_status.sr + 1) * 28 - delta % 28)
date_before_last_shift = date_before_last_shift.strftime('%Y-%m-%d')
# Get config
irregular_shift_limit = int(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.irregular_shift_limit'))
@ -77,22 +206,23 @@ class WebsiteShiftController(http.Controller):
'beesdoo_website_shift.highlight_rule'))
hide_rule = int(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.hide_rule')) / 100.0
irregular_enable_sign_up = literal_eval(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.irregular_enable_sign_up'))
# Grouby task_template_id, if no task_template_id is specified
# then group by start_time
groupby_func = lambda s: (s.task_template_id, s.start_time, s.task_type_id)
groupby_iter = groupby(shifts, groupby_func)
# then group by start_time, if no start_time specified sort by
# task_type
groupby_iter = groupby(
shifts,
lambda s: (s.task_template_id, s.start_time, s.task_type_id)
)
shifts_count_subscribed = []
nb_displayed_shift = 0 # Number of shift displayed
for (keys, grouped_shifts) in groupby_iter:
(task_template, start_time, task_type) = keys
nb_displayed_shift = nb_displayed_shift + 1
s = list(grouped_shifts)
shift_list = list(grouped_shifts)
# Compute available space
free_space = len(s)
free_space = len(shift_list)
# Is the current user subscribed to this task_template
is_subscribed = any(
(sub_shift.task_template_id == task_template and
@ -100,33 +230,24 @@ class WebsiteShiftController(http.Controller):
sub_shift.task_type_id == task_type)
for sub_shift in subscribed_shifts)
if free_space >= task_template.worker_nb * hide_rule:
shifts_count_subscribed.append([s[0], free_space, is_subscribed])
shifts_count_subscribed.append([shift_list[0], free_space, is_subscribed])
# Stop showing shifts if the limit is reached
if irregular_shift_limit > 0 and nb_displayed_shift >= irregular_shift_limit:
break
return request.render(
'beesdoo_website_shift.irregular_worker',
{
'partner': cur_user.partner_id,
'status': cur_cooperative_status,
'date_before_last_shift': date_before_last_shift,
'shift_templates': shifts_count_subscribed,
'highlight_rule': highlight_rule,
'nexturl': '/shift',
'subscribed_shifts': subscribed_shifts,
'irregular_enable_sign_up': irregular_enable_sign_up,
}
)
return {
'shift_templates': shifts_count_subscribed,
'highlight_rule': highlight_rule,
'nexturl': nexturl,
'irregular_enable_sign_up': irregular_enable_sign_up,
}
def shift_template_regular_worker(self, **kwargs):
def my_shift_next_shifts(self):
"""
Return template variables for 'beesdoo_website_shift.my_shift_next_shifts' template
"""
# Get current user
cur_user = request.env['res.users'].browse(request.uid)
# Get all the task template
template = request.env['beesdoo.shift.template']
task_templates = template.sudo().search([], order="planning_id, day_nb_id, start_time")
# Get shifts where user is subscribed
now = datetime.now()
subscribed_shifts = request.env['beesdoo.shift.shift'].sudo().search(
@ -134,26 +255,15 @@ class WebsiteShiftController(http.Controller):
('worker_id', '=', cur_user.partner_id.id)],
order="start_time, task_template_id, task_type_id",
)
return {
'subscribed_shifts': subscribed_shifts,
}
return request.render(
'beesdoo_website_shift.regular_worker',
{
'partner': cur_user.partner_id,
'status': cur_user.partner_id.cooperative_status_ids,
'task_templates': task_templates,
'float_to_time': float_to_time,
'subscribed_shifts': subscribed_shifts,
}
)
def shift_exempted_worker(self, **kwargs):
# Get current user
def my_shift_worker_status(self):
"""
Return template variables for 'beesdoo_website_shift.my_shift_worker_status_*' template
"""
cur_user = request.env['res.users'].browse(request.uid)
return request.render(
'beesdoo_website_shift.exempted_worker',
{
'partner': cur_user.partner_id,
'status': cur_user.partner_id.cooperative_status_ids,
}
)
return {
'status': cur_user.partner_id.cooperative_status_ids,
}

4
beesdoo_website_shift/data/res_config_data.xml

@ -1,4 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<data noupdate="1">
<record id="beesdoo_website_shift.irregular_shift_limit" model="ir.config_parameter">

3
beesdoo_website_shift/models/res_config.py

@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from ast import literal_eval
from openerp import fields, models, api

532
beesdoo_website_shift/views/my_shift_website_templates.xml

@ -0,0 +1,532 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<!-- Add menu entries -->
<template id="my_shift_link" name="Link to frontend portal" inherit_id="website.layout">
<xpath expr="//li[@id='o_logout']" position="before">
<li><a href="/my/shift" role="menuitem">My Shift</a></li>
</xpath>
</template>
<!-- Reusable templates -->
<template
id="my_shift_title"
name="My Shift Title">
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="text-center">
Your shifts
</h1>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</template>
<template
id="my_shift_worker_status_title"
name="My Shift Worker Status Title">
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Worker status
<span t-att-class="'label %s pull-right' % ('label-success' if status.can_shop else 'label-danger',)">
<span class="fa fa-shopping-cart"></span>
<t t-if="status.can_shop">
<span class="fa fa-check"></span>
</t>
<t t-if="not status.can_shop">
<span class="fa fa-times"></span>
</t>
</span>
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</template>
<template
id="my_shift_worker_status_common"
name="My Shift Worker Status Common">
<p>
<label>Working Mode:</label>
<t t-esc="dict(status.fields_get(allfields=['working_mode'])['working_mode']['selection'])[status.working_mode]"/>
</p>
<p>
<label>Status:</label>
<t t-esc="dict(status.fields_get(allfields=['status'])['status']['selection'])[status.status]"/>
</p>
<p t-if="status.holiday_start_time">
<label>Holiday start time:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.holiday_end_time">
<label>Holiday end time:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_end_time, '%Y-%m-%d'))"/>
</p>
</template>
<template
id="my_shift_next_shifts"
name="My Shift : Next Shifts">
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Your next shifts
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<div class="visible-xs" t-foreach="subscribed_shifts" t-as="shift">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</div>
</div>
<div class="panel-body">
<t t-esc="shift.task_type_id.name"/>
</div>
</div>
</div>
<table class="hidden-xs table table-striped" t-if="subscribed_shifts">
<thead>
<tr>
<th>Day</th>
<th>Date</th>
<th>Time</th>
<th>Type of Shift</th>
</tr>
</thead>
<tbody>
<t t-foreach="subscribed_shifts" t-as="shift">
<tr>
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</td>
<td>
<t t-esc="shift.task_type_id.name"/>
</td>
</tr>
</t>
</tbody>
</table>
<section class="wrap" t-if="not subscribed_shifts">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-warning">
<strong>Warning !</strong> You have not yet signed up to a shift.
</div>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</template>
<template
id="available_shift_irregular_worker"
name="Available Shift for Irregular Worker">
<div class="oe_structure"/>
<div class="visible-xs" t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<t t-set="highlight_class" t-value="'panel-warning' if count >= highlight_rule else 'panel-default'"/>
<div t-att-class="'panel %s' % highlight_class">
<div class="panel-heading clearfix">
<div class="panel-title pull-left">
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</div>
<div class="label label-default pull-right">
<t t-esc="count"/> space(s)
</div>
</div>
<div class="panel-body clearfix">
<t t-esc="shift.task_type_id.name"/>
<t t-if="is_subscribed">
<div class="label label-success pull-right">
<span class="fa fa-check" aria-hidden="true"></span>
Subscribed
</div>
</t>
<t t-if="irregular_enable_sign_up and not is_subscribed">
<button type="button" class="btn btn-default btn-sm pull-right" data-toggle="modal"
t-att-data-target="'#subscribe-shift-%s' % shift.id">
<span class="fa fa-user-plus" aria-hidden="true"></span>
Subscribe
</button>
</t>
</div>
</div>
</div>
<table class="hidden-xs table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Date</th>
<th>Time</th>
<th>Type of Shift</th>
<th class="text-center">Available Spaces</th>
<th class="text-center" t-if="irregular_enable_sign_up">Subscribed</th>
</tr>
</thead>
<tbody>
<t t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<tr t-attf-class="{{ 'warning' if count >= highlight_rule else '' }}">
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</td>
<td>
<t t-esc="shift.task_type_id.name"/>
</td>
<td class="text-center">
<t t-esc="count"/>
</td>
<td class="text-center" t-if="irregular_enable_sign_up">
<t t-if="is_subscribed">
<div class="label label-success">
<span class="fa fa-check" aria-hidden="true"></span>
Subscribed
</div>
</t>
<t t-if="not is_subscribed">
<button type="button" class="btn btn-default btn-sm" data-toggle="modal"
t-att-data-target="'#subscribe-shift-%s' % shift.id">
<span class="fa fa-user-plus" aria-hidden="true"></span>
Subscribe
</button>
</t>
</td>
</tr>
</t>
</tbody>
</table>
<!-- Subscribe check -->
<t t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<div class="modal fade" t-att-id="'subscribe-shift-%s' % shift.id" tabindex="-1" role="dialog"
t-att-aria-labelledby="'subscribe-shift-%s-label' % shift.id">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" t-att-id="'subscribe-shift-%s-label' % shift.id">
Are you shure you want to subscribe to this shift?
</h4>
</div>
<div class="modal-body">
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/><br/>
<t t-esc="shift.task_type_id.name"/><br/>
<t t-esc="count"/> available space(s)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<a class="btn btn-primary"
t-if="irregular_enable_sign_up"
t-att-href="'/shift/%s/subscribe?nexturl=%s' % (shift.id, nexturl)">
Subscribe
</a>
</div>
</div>
</div>
</div>
</t>
<div class="oe_structure"/>
</template>
<!-- Shift for non-worker -->
<template
id="my_shift_non_worker"
name="My Shift for Non Worker"
page="True">
<t t-call="website.layout">
<t t-call="beesdoo_website_shift.my_shift_title"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
You don't have to participate to shift system.
</div>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</t>
</template>
<!-- Shifts Exempted Workers -->
<template
id="my_shift_exempted_worker"
name="My Shifts for Exempted Workers"
page="True">
<t t-call="website.layout">
<t t-call="beesdoo_website_shift.my_shift_title"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<t t-call="beesdoo_website_shift.my_shift_worker_status_title"/>
<t t-call="beesdoo_website_shift.my_shift_worker_status_common"/>
<p t-if="status.exempt_reason_id">
<label>Exempt Reason:</label>
<t t-esc="status.exempt_reason_id.name"/>
</p>
<div class="oe_structure"/>
</div>
<div class="col-xs-12 col-md-8">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
You don't have to participate to shift system.
</div>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</div> <!-- col-md-8 -->
</div> <!-- row -->
</div> <!-- container -->
</section>
<div class="oe_structure"/>
</t>
</template>
<!-- Shifts for Regular Workers -->
<template
id="my_shift_regular_worker"
name="My Shifts for Regular Workers"
page="True">
<t t-call="website.layout">
<t t-call="beesdoo_website_shift.my_shift_title"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<t t-call="beesdoo_website_shift.my_shift_worker_status_title"/>
<t t-call="beesdoo_website_shift.my_shift_worker_status_common"/>
<p t-if="status.sr != 0">
<label>Shift in Advance:</label>
<t t-esc="status.sr"/>
</p>
<p t-if="status.sc != 0">
<label>Compensation Shift:</label>
<t t-esc="status.sc"/>
</p>
<p t-if="status.alert_start_time">
<label>In Alert Since:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.alert_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.extension_start_time">
<label>In Extension Since:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.extension_start_time, '%Y-%m-%d'))"/>
</p>
<div class="oe_structure"/>
</div>
<div class="col-xs-12 col-md-8">
<t t-call="beesdoo_website_shift.my_shift_next_shifts"/>
</div> <!-- col-md-8 -->
</div> <!-- row -->
</div> <!-- container -->
</section>
<div class="oe_structure"/>
</t>
</template>
<!-- Shifts for Irregular Workers -->
<template
id="my_shift_irregular_worker"
name="Shifts for Irregular Workers"
page="True">
<t t-call="website.layout">
<t t-call="beesdoo_website_shift.my_shift_title"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<t t-call="beesdoo_website_shift.my_shift_worker_status_title"/>
<t t-call="beesdoo_website_shift.my_shift_worker_status_common"/>
<p>
<label>Shift in Advance:</label>
<t t-esc="status.sr"/>
</p>
<p t-if="date_before_last_shift">
<label>Date Before Last Shift:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(date_before_last_shift, '%Y-%m-%d'))"/>
</p>
<p t-if="status.irregular_absence_date">
<label>Last Absence Date:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.irregular_absence_date, '%Y-%m-%d'))"/>
</p>
<p t-if="status.irregular_absence_counter">
<label>Number of Absence:</label>
<t t-esc="status.irregular_absence_counter"/>
</p>
<div class="oe_structure"/>
</div>
<div class="col-xs-12 col-md-8">
<t t-call="beesdoo_website_shift.my_shift_next_shifts"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Available Shifts
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p>
Explanation text
</p>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<t t-call="beesdoo_website_shift.available_shift_irregular_worker"/>
</div> <!-- col-md-8 -->
</div> <!-- row -->
</div> <!-- container -->
</section>
<div class="oe_structure"/>
</t>
</template>
</openerp>

14
beesdoo_website_shift/views/res_config_views.xml

@ -1,12 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<data>
<record id="view_website_shift_config_irregular" model="ir.ui.view">
<field name="name">Website Shift Settings</field>
<field name="name">Website Shift Settings Irregular Worker</field>
<field name="model">beesdoo.website.shift.config.settings</field>
<field name="arch" type="xml">
<form string="Configure Website Shift" class="oe_form_configuration">
<form string="Configure Website Shift Irregular Worker" class="oe_form_configuration">
<header>
<button string="Apply" type="object" name="execute" class="oe_highlight"/>
<button string="Cancel" type="object" name="cancel" class="oe_link" special="cancel"/>
@ -31,8 +35,8 @@
</field>
</record>
<record id="action_website_shift_configuration" model="ir.actions.act_window">
<field name="name">Website Shift Settings</field>
<record id="action_website_shift_config_irregular" model="ir.actions.act_window">
<field name="name">Website Shift Settings Irregular Worker</field>
<field name="res_model">beesdoo.website.shift.config.settings</field>
<field name="view_id" ref="view_website_shift_config_irregular"/>
<field name="view_mode">form</field>
@ -48,7 +52,7 @@
<menuitem
id="menu_website_shift_irregular"
name="Irregular Shift"
action="action_website_shift_configuration"
action="action_website_shift_config_irregular"
parent="menu_website_shift_root"
sequence="1"/>

637
beesdoo_website_shift/views/shift_website_templates.xml

@ -1,58 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<openerp>
<!-- Add menu entries -->
<data noupdate="1">
<record id="menu_work_irregular" model="website.menu">
<field name="name">Shifts</field>
<field name="url">/shift</field>
<field name="name">Shifts Irregular</field>
<field name="url">/shift_irregular_worker</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">50</field>
</record>
<record id="menu_work_regular" model="website.menu">
<field name="name">Shifts Regular</field>
<field name="url">/shift_template_regular_worker</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">51</field>
</record>
</data>
<!-- Shift -->
<template
id="shift"
name="Shift"
page="True">
<t t-call="website.layout">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="text-center">
Your shifts
</h1>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
You don't have to participate to shift system.
</div>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</t>
</template>
<!-- Shifts Exempted Workers -->
<!-- Public Available Tasks Templates for Regular Workers -->
<template
id="exempted_worker"
name="Shifts for Exempted Workers"
id="public_shift_template_regular_worker"
name="Available Tasks Templates for Regular Workers"
page="True">
<t t-call="website.layout">
@ -63,7 +35,7 @@
<div class="row">
<div class="col-md-12">
<h1 class="text-center">
Your shifts
Available Tasks Templates for Regular Workers
</h1>
</div>
</div>
@ -72,270 +44,23 @@
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Worker status
<span t-att-class="'label %s pull-right' % ('label-success' if status.can_shop else 'label-danger',)">
<span class="fa fa-shopping-cart"></span>
<t t-if="status.can_shop">
<span class="fa fa-check"></span>
</t>
<t t-if="not status.can_shop">
<span class="fa fa-times"></span>
</t>
</span>
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<p>
<label>Working Mode:</label>
<t t-esc="dict(status.fields_get(allfields=['working_mode'])['working_mode']['selection'])[status.working_mode]"/>
</p>
<p>
<label>Status:</label>
<t t-esc="dict(status.fields_get(allfields=['status'])['status']['selection'])[status.status]"/>
</p>
<p t-if="status.exempt_reason_id">
<label>Exempt Reason:</label>
<t t-esc="status.exempt_reason_id.name"/>
</p>
<p t-if="status.holiday_start_time">
<label>Holiday start time:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.holiday_end_time">
<label>Holiday end time:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_end_time, '%Y-%m-%d'))"/>
</p>
<div class="oe_structure"/>
</div>
<div class="col-xs-12 col-md-8">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
You don't have to participate to shift system.
</div>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
</div> <!-- col-md-8 -->
</div> <!-- row -->
</div> <!-- container -->
</section>
<div class="oe_structure"/>
</t>
</template>
<!-- Shifts for Regular Workers -->
<template
id="regular_worker"
name="Shifts for Regular Workers"
page="True">
<t t-call="website.layout">
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="text-center">
Your shifts
</h1>
<p class="text-center">
Subscribe via the member office or via
<a href="mailto:membre@bees-coop.be">membre@bees-coop.be</a>
</p>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Worker status
<span t-att-class="'label %s pull-right' % ('label-success' if status.can_shop else 'label-danger',)">
<span class="fa fa-shopping-cart"></span>
<t t-if="status.can_shop">
<span class="fa fa-check"></span>
</t>
<t t-if="not status.can_shop">
<span class="fa fa-times"></span>
</t>
</span>
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<p>
<label>Working Mode:</label>
<t t-esc="dict(status.fields_get(allfields=['working_mode'])['working_mode']['selection'])[status.working_mode]"/>
</p>
<p>
<label>Status:</label>
<t t-esc="dict(status.fields_get(allfields=['status'])['status']['selection'])[status.status]"/>
</p>
<p t-if="status.sr != 0">
<label>Shift in Advance:</label>
<t t-esc="status.sr"/>
</p>
<p t-if="status.sc != 0">
<label>Compensation Shift:</label>
<t t-esc="status.sc"/>
</p>
<p t-if="status.holiday_start_time">
<label>Begining of Holiday:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.holiday_end_time">
<label>End of Holiday:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_end_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.alert_start_time">
<label>In Alert Since:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.alert_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.extension_start_time">
<label>In Extension Since:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.extension_start_time, '%Y-%m-%d'))"/>
</p>
<div class="oe_structure"/>
</div>
<div class="col-xs-12 col-md-8">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Your next shifts
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<div class="visible-xs" t-foreach="subscribed_shifts" t-as="shift">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</div>
</div>
<div class="panel-body">
<t t-esc="shift.task_type_id.name"/>
</div>
</div>
</div>
<table class="hidden-xs table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Date</th>
<th>Time</th>
<th>Type of Shift</th>
</tr>
</thead>
<tbody>
<t t-foreach="subscribed_shifts" t-as="shift">
<tr>
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</td>
<td>
<t t-esc="shift.task_type_id.name"/>
</td>
</tr>
</t>
</tbody>
</table>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Available Task Templates
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p>
Explanation text
</p>
</div>
</div>
</div>
</section>
<div class="col-md-12">
<div class="oe_structure"/>
@ -411,7 +136,7 @@
</tbody>
</table>
</div> <!-- col-md-8 -->
</div> <!-- col-md -->
</div> <!-- row -->
</div> <!-- container -->
</section>
@ -421,10 +146,11 @@
</t>
</template>
<!-- Shifts for Irregular Workers -->
<!-- Public Available Shifts for Irregular Workers -->
<template
id="irregular_worker"
name="Shifts for Irregular Workers"
id="public_shift_irregular_worker"
name="Available Shifts for Irregular Workers"
page="True">
<t t-call="website.layout">
@ -435,7 +161,7 @@
<div class="row">
<div class="col-md-12">
<h1 class="text-center">
Your shifts
Available Shifts for Irregular Workers
</h1>
</div>
</div>
@ -447,305 +173,25 @@
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-4 pull-right">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Worker status
<span t-att-class="'label %s pull-right' % ('label-success' if status.can_shop else 'label-danger',)">
<span class="fa fa-shopping-cart"></span>
<t t-if="status.can_shop">
<span class="fa fa-check"></span>
</t>
<t t-if="not status.can_shop">
<span class="fa fa-times"></span>
</t>
</span>
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<p>
<label>Working Mode:</label>
<t t-esc="dict(status.fields_get(allfields=['working_mode'])['working_mode']['selection'])[status.working_mode]"/>
</p>
<p>
<label>Status:</label>
<t t-esc="dict(status.fields_get(allfields=['status'])['status']['selection'])[status.status]"/>
</p>
<p>
<label>Shift in Advance:</label>
<t t-esc="status.sr"/>
</p>
<p t-if="date_before_last_shift">
<label>Date Before Last Shift:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(date_before_last_shift, '%Y-%m-%d'))"/>
</p>
<p t-if="status.holiday_start_time">
<label>Begining of Holiday:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_start_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.holiday_end_time">
<label>End of Holiday:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.holiday_end_time, '%Y-%m-%d'))"/>
</p>
<p t-if="status.irregular_absence_date">
<label>Last Absence Date:</label>
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(status.irregular_absence_date, '%Y-%m-%d'))"/>
</p>
<p t-if="status.irregular_absence_counter">
<label>Number of Absence:</label>
<t t-esc="status.irregular_absence_counter"/>
<div class="col-md-12">
<p class="text-center">
Subscribe via <a href="mailto:volant@bees-coop.be">volant@bees-coop.be</a>
</p>
<div class="oe_structure"/>
</div>
</div>
</div>
</section>
<div class="col-xs-12 col-md-8">
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Your next shifts
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<div class="visible-xs" t-foreach="subscribed_shifts" t-as="shift">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</div>
</div>
<div class="panel-body">
<t t-esc="shift.task_type_id.name"/>
</div>
</div>
</div>
<table class="hidden-xs table table-striped" t-if="subscribed_shifts">
<thead>
<tr>
<th>Day</th>
<th>Date</th>
<th>Time</th>
<th>Type of Shift</th>
</tr>
</thead>
<tbody>
<t t-foreach="subscribed_shifts" t-as="shift">
<tr>
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</td>
<td>
<t t-esc="shift.task_type_id.name"/>
</td>
</tr>
</t>
</tbody>
</table>
<section class="wrap" t-if="not subscribed_shifts">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-warning">
<strong>Warning !</strong> You have not yet signed up to a shift.
</div>
</div>
</div>
</div>
</section>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>
Available Shifts
</h2>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p>
Explanation text
</p>
</div>
</div>
</div>
</section>
<div class="oe_structure"/>
<div class="visible-xs" t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<t t-set="highlight_class" t-value="'panel-warning' if count >= highlight_rule else 'panel-default'"/>
<div t-att-class="'panel %s' % highlight_class">
<div class="panel-heading clearfix">
<div class="panel-title pull-left">
<t t-esc="time.strftime('%A %d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</div>
<div class="label label-default pull-right">
<t t-esc="count"/> space(s)
</div>
</div>
<div class="panel-body clearfix">
<t t-esc="shift.task_type_id.name"/>
<t t-if="is_subscribed">
<div class="label label-success pull-right">
<span class="fa fa-check" aria-hidden="true"></span>
Subscribed
</div>
</t>
<t t-if="irregular_enable_sign_up and not is_subscribed">
<button type="button" class="btn btn-default btn-sm pull-right" data-toggle="modal"
t-att-data-target="'#subscribe-shift-%s' % shift.id">
<span class="fa fa-user-plus" aria-hidden="true"></span>
Subscribe
</button>
</t>
</div>
</div>
</div>
<table class="hidden-xs table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Date</th>
<th>Time</th>
<th>Type of Shift</th>
<th class="text-center">Available Spaces</th>
<th class="text-center" t-if="irregular_enable_sign_up">Subscribed</th>
</tr>
</thead>
<tbody>
<t t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<tr t-attf-class="{{ 'warning' if count >= highlight_rule else '' }}">
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
<td>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/>
</td>
<td>
<t t-esc="shift.task_type_id.name"/>
</td>
<td class="text-center">
<t t-esc="count"/>
</td>
<td class="text-center" t-if="irregular_enable_sign_up">
<t t-if="is_subscribed">
<div class="label label-success">
<span class="fa fa-check" aria-hidden="true"></span>
Subscribed
</div>
</t>
<t t-if="not is_subscribed">
<button type="button" class="btn btn-default btn-sm" data-toggle="modal"
t-att-data-target="'#subscribe-shift-%s' % shift.id">
<span class="fa fa-user-plus" aria-hidden="true"></span>
Subscribe
</button>
</t>
</td>
</tr>
</t>
</tbody>
</table>
<div class="oe_structure"/>
<!-- Subscribe check -->
<t t-foreach="shift_templates" t-as="shift_count_subscribed">
<t t-set="shift" t-value="shift_count_subscribed[0]" />
<t t-set="count" t-value="shift_count_subscribed[1]" />
<t t-set="is_subscribed" t-value="shift_count_subscribed[2]" />
<div class="modal fade" t-att-id="'subscribe-shift-%s' % shift.id" tabindex="-1" role="dialog"
t-att-aria-labelledby="'subscribe-shift-%s-label' % shift.id">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" t-att-id="'subscribe-shift-%s-label' % shift.id">
Are you shure you want to subscribe to this shift?
</h4>
</div>
<div class="modal-body">
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<t t-esc="time.strftime('%d %B %Y', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
<span t-field="shift.start_time" t-field-options='{"format": "HH:mm"}'/> -
<span t-field="shift.end_time" t-field-options='{"format": "HH:mm"}'/><br/>
<t t-esc="shift.task_type_id.name"/><br/>
<t t-esc="count"/> available space(s)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<a class="btn btn-primary"
t-if="irregular_enable_sign_up"
t-att-href="'/shift/%s/subscribe?nexturl=%s' % (shift.id, nexturl)">
Subscribe
</a>
</div>
</div>
</div>
</div>
</t>
<section class="wrap">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="oe_structure"/>
<t t-call="beesdoo_website_shift.available_shift_irregular_worker"/>
</div> <!-- col-md-8 -->
</div> <!-- col-md -->
</div> <!-- row -->
</div> <!-- container -->
</section>
@ -754,4 +200,5 @@
</t>
</template>
</openerp>
Loading…
Cancel
Save