Browse Source
[ADD] beesdoo_shift module, first version of the module to manage shifts
pull/105/head
[ADD] beesdoo_shift module, first version of the module to manage shifts
pull/105/head
Thibault Francois
8 years ago
committed by
Elouan
14 changed files with 731 additions and 0 deletions
-
3beesdoo_shift/__init__.py
-
28beesdoo_shift/__openerp__.py
-
3beesdoo_shift/models/__init__.py
-
118beesdoo_shift/models/planning.py
-
36beesdoo_shift/models/task.py
-
6beesdoo_shift/security/ir.model.access.csv
-
80beesdoo_shift/views/planning.xml
-
77beesdoo_shift/views/task.xml
-
246beesdoo_shift/views/task_template.xml
-
2beesdoo_shift/wizard/__init__.py
-
53beesdoo_shift/wizard/batch_template.py
-
41beesdoo_shift/wizard/batch_template.xml
-
18beesdoo_shift/wizard/instanciate_planning.py
-
20beesdoo_shift/wizard/instanciate_planning.xml
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
import models |
|||
import wizard |
@ -0,0 +1,28 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': "Beescoop Shift Management", |
|||
|
|||
'summary': """ |
|||
Volonteer Timetable Management""", |
|||
|
|||
'description': """ |
|||
|
|||
""", |
|||
|
|||
'author': "Thibault Francois", |
|||
'website': "https://github.com/beescoop/Obeesdoo", |
|||
|
|||
'category': 'Coop', |
|||
'version': '0.1', |
|||
|
|||
'depends': ['beesdoo_base'], |
|||
|
|||
'data': [ |
|||
"security/ir.model.access.csv", |
|||
"views/task_template.xml", |
|||
"views/task.xml", |
|||
"views/planning.xml", |
|||
"wizard/instanciate_planning.xml", |
|||
"wizard/batch_template.xml", |
|||
], |
|||
} |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
import planning |
|||
import task |
@ -0,0 +1,118 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from openerp import models, fields, api, _ |
|||
from openerp.exceptions import UserError |
|||
|
|||
from pytz import UTC |
|||
import math |
|||
from datetime import datetime, timedelta |
|||
|
|||
def float_to_time(f): |
|||
decimal, integer = math.modf(f) |
|||
return "%s:%s" % (str(int(integer)).zfill(2), str(int(round(decimal * 60))).zfill(2)) |
|||
|
|||
def floatime_to_hour_minute(f): |
|||
decimal, integer = math.modf(f) |
|||
return int(integer), int(round(decimal * 60)) |
|||
|
|||
def get_first_day_of_week(): |
|||
today = datetime.now() |
|||
return datetime.now() - timedelta(days=today.weekday()) |
|||
|
|||
class TaskType(models.Model): |
|||
_name = 'beesdoo.shift.type' |
|||
|
|||
name = fields.Char() |
|||
description = fields.Text() |
|||
active = fields.Boolean(default=True) |
|||
|
|||
class DayNumber(models.Model): |
|||
_name = 'beesdoo.shift.daynumber' |
|||
|
|||
_order = 'number asc' |
|||
|
|||
name = fields.Char() |
|||
number = fields.Integer("Day Number", help="From 1 to N, When you will instanciate your planning, Day 1 will be the start date of the instance, Day 2 the second, etc...") |
|||
active = fields.Boolean(default=True) |
|||
|
|||
class Planning(models.Model): |
|||
_name = 'beesdoo.shift.planning' |
|||
|
|||
name = fields.Char() |
|||
task_template_ids = fields.One2many('beesdoo.shift.template', 'planning_id') |
|||
|
|||
class TaskTemplate(models.Model): |
|||
_name = 'beesdoo.shift.template' |
|||
|
|||
name = fields.Char(required=True) |
|||
planning_id = fields.Many2one('beesdoo.shift.planning', required=True) |
|||
day_nb_id = fields.Many2one('beesdoo.shift.daynumber', string='Day', required=True) |
|||
task_type_id = fields.Many2one('beesdoo.shift.type', string="Type") |
|||
start_time = fields.Float(required=True) |
|||
end_time = fields.Float(required=True) |
|||
|
|||
duration = fields.Float(help="Duration in Hour") |
|||
worker_nb = fields.Integer(string="Number of worker", help="Max number of worker for this task", default=1) |
|||
worker_ids = fields.Many2many('res.partner', string="Recurrent worker assigned", domain=[('eater', '=', 'worker_eater')]) |
|||
remaining_worker = fields.Integer(compute="_get_remaining", store=True, string="Remaining Place") |
|||
active = fields.Boolean(default=True) |
|||
#For Kanban View Only |
|||
color = fields.Integer('Color Index') |
|||
worker_name = fields.Char(compute="_get_worker_name") |
|||
#For calendar View |
|||
start_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search") |
|||
end_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search") |
|||
|
|||
@api.depends('start_time', 'end_time') |
|||
def _get_fake_date(self): |
|||
today = datetime.strptime(self._context.get('visualize_date'), '%Y-%m-%d') if self._context.get('visualize_date') else get_first_day_of_week() |
|||
for rec in self: |
|||
day = today + timedelta(days=rec.day_nb_id.number - 1) |
|||
h_begin, m_begin = floatime_to_hour_minute(rec.start_time) |
|||
h_end, m_end = floatime_to_hour_minute(rec.end_time) |
|||
rec.start_date = fields.Datetime.context_timestamp(self, day).replace(hour=h_begin, minute=m_begin, second=0).astimezone(UTC) |
|||
rec.end_date = fields.Datetime.context_timestamp(self, day).replace(hour=h_end, minute=m_end, second=0).astimezone(UTC) |
|||
|
|||
def _dummy_search(self, operator, value): |
|||
return [] |
|||
|
|||
@api.depends('worker_ids', 'worker_nb') |
|||
def _get_remaining(self): |
|||
for rec in self: |
|||
rec.remaining_worker = rec.worker_nb - len(rec.worker_ids) |
|||
|
|||
@api.depends("worker_ids") |
|||
def _get_worker_name(self): |
|||
for rec in self: |
|||
rec.worker_name = ','.join(rec.worker_ids.mapped('display_name')) |
|||
|
|||
@api.constrains('worker_nb', 'worker_ids') |
|||
def _nb_worker_max(self): |
|||
for rec in self: |
|||
if len(rec.worker_ids) > rec.worker_nb: |
|||
raise UserError(_('you cannot assign more worker then the number maximal define on the template')) |
|||
|
|||
|
|||
@api.onchange('start_time', 'end_time') |
|||
def _get_duration(self): |
|||
if self.start_time and self.end_time: |
|||
self.duration = self.end_time - self.start_time |
|||
|
|||
@api.onchange('duration') |
|||
def _set_duration(self): |
|||
if self.start_time: |
|||
self.end_time = self.start_time +self.duration |
|||
|
|||
def _generate_task_day(self): |
|||
tasks = self.env['beesdoo.shift.shift'] |
|||
for rec in self: |
|||
for i in xrange(0, rec.worker_nb): |
|||
tasks |= tasks.create({ |
|||
'name' : "%s (%s) - (%s) [%s]" % (rec.name, float_to_time(rec.start_time), float_to_time(rec.end_time), i), |
|||
'task_template_id' : rec.id, |
|||
'task_type_id' : rec.task_type_id.id, |
|||
'worker_id' : rec.worker_ids[i].id if len(rec.worker_ids) > i else False, |
|||
'start_time' : rec.start_date, |
|||
'end_time' : rec.end_date, |
|||
}) |
|||
return tasks |
@ -0,0 +1,36 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp import models, fields |
|||
|
|||
STATES = [ |
|||
('draft', 'Unconfirmed'), |
|||
('open', 'Confirmed'), |
|||
('done', 'Attended'), |
|||
('absent', 'Absent'), |
|||
('excused', 'Excused'), |
|||
('replaced', 'Replaced'), |
|||
('cancel', 'Cancelled'), |
|||
] |
|||
|
|||
class Task(models.Model): |
|||
_name = 'beesdoo.shift.shift' |
|||
|
|||
#EX01 ADD inheritance |
|||
_inherit = ['mail.thread'] |
|||
|
|||
name = fields.Char(track_visibility='always') |
|||
task_template_id = fields.Many2one('beesdoo.shift.template') |
|||
planning_id = fields.Many2one(related='task_template_id.planning_id', store=True) |
|||
task_type_id = fields.Many2one('beesdoo.shift.type', string="Task Type") |
|||
worker_id = fields.Many2one('res.partner', track_visibility='onchange', domain=[('eater', '=', 'worker_eater')]) |
|||
start_time = fields.Datetime(track_visibility='always') |
|||
end_time = fields.Datetime(track_visibility='always') |
|||
state = fields.Selection(STATES, default='draft', track_visibility='onchange') |
|||
|
|||
def message_auto_subscribe(self, updated_fields, values=None): |
|||
self._add_follower(values) |
|||
return super(Task, self).message_auto_subscribe(updated_fields, values=values) |
|||
|
|||
def _add_follower(self, vals): |
|||
if vals.get('worker_id'): |
|||
worker = self.env['res.partner'].browse(vals['worker_id']) |
|||
self.message_subscribe(partner_ids=worker.ids) |
@ -0,0 +1,6 @@ |
|||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_coopplanning_task_type,access_coopplanning_task_type,model_beesdoo_shift_type,,1,1,1,1 |
|||
access_coopplanning_daynumber,access_coopplanning_daynumber,model_beesdoo_shift_daynumber,,1,1,1,1 |
|||
access_coopplanning_planning,access_coopplanning_planning,model_beesdoo_shift_planning,,1,1,1,1 |
|||
access_coopplanning_task_template,access_coopplanning_task_template,model_beesdoo_shift_template,,1,1,1,1 |
|||
access_coopplanning_task,access_coopplanning_task,model_beesdoo_shift_shift,,1,1,1,1 |
@ -0,0 +1,80 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="planning_view_tree"> |
|||
<field name="name">Planning List</field> |
|||
<field name="model">beesdoo.shift.planning</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.actions.act_window" id="action_shift_template"> |
|||
<field name="name">Planning Action</field> |
|||
<field name="res_model">beesdoo.shift.template</field> |
|||
<field name="view_mode">kanban,tree,form,calendar,pivot</field> |
|||
<field name="context">{'group_by': 'day_nb_id', |
|||
'search_default_planning_id': active_id, |
|||
'default_planning_id': active_id}</field> |
|||
</record> |
|||
|
|||
<record model="ir.actions.act_window" id="action_generate_shift_wizard"> |
|||
<field name="name">Instanciate Planning Action</field> |
|||
<field name="res_model">beesddoo.shift.generate_planning</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="planning_view_form"> |
|||
<field name="name">Planning Form</field> |
|||
<field name="model">beesdoo.shift.planning</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<header> |
|||
|
|||
</header> |
|||
<sheet> |
|||
<div class="oe_button_box" name="button_box"> |
|||
<button class="oe_stat_button" type="action" |
|||
name="%(action_shift_template)d" icon="fa-book" |
|||
string="Shifts"> |
|||
<!-- <field string="Ventes" name="sale_order_count" |
|||
widget="statinfo" modifiers="{'readonly': true}"/> --> |
|||
</button> |
|||
</div> |
|||
<div class="oe_title"> |
|||
<h1> |
|||
<field name="name" placeholder="name" /> |
|||
</h1> |
|||
</div> |
|||
<group> |
|||
<button type="action" |
|||
name="%(action_generate_shift_wizard)d" string="Generate shifts" colspan="2"/> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="planning_view_tree"> |
|||
<field name="name">Planning Tree</field> |
|||
<field name="model">beesdoo.shift.planning</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name" /> |
|||
<button type="action" name="%(action_shift_template)d" |
|||
string="Shifts" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<!-- Actions --> |
|||
<record model="ir.actions.act_window" id="action_planning"> |
|||
<field name="name">Planning Action</field> |
|||
<field name="res_model">beesdoo.shift.planning</field> |
|||
<field name="view_mode">tree,form</field> |
|||
</record> |
|||
|
|||
<menuitem name="Planning Week" id="menu_planning" parent="menu_template_top" |
|||
sequence="10" action="action_planning" /> |
|||
</odoo> |
@ -0,0 +1,77 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="task_view_tree"> |
|||
<field name="name">Task Template List</field> |
|||
<field name="model">beesdoo.shift.shift</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="start_time" /> |
|||
<field name="planning_id" /> |
|||
<field name="task_type_id" /> |
|||
<field name="name" /> |
|||
<field name="worker_id" /> |
|||
<field name="end_time" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_view_calendar"> |
|||
<field name="name">Task Template List</field> |
|||
<field name="model">beesdoo.shift.shift</field> |
|||
<field name="arch" type="xml"> |
|||
<calendar string="Calendar View" date_start="start_time" |
|||
date_stop="end_time" color="task_type_id"> |
|||
<field name="name" /> |
|||
<field name="worker_id" /> |
|||
</calendar> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_view_form"> |
|||
<field name="name">Task Template Form</field> |
|||
<field name="model">beesdoo.shift.shift</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<header> |
|||
<field name="state" widget="statusbar" clickable="1" /> |
|||
</header> |
|||
<sheet> |
|||
<div class="oe_title"> |
|||
<h1> |
|||
<field name="name" /> |
|||
</h1> |
|||
</div> |
|||
<group> |
|||
<group> |
|||
<field name="task_template_id" /> |
|||
<field name="task_type_id" /> |
|||
<field name="worker_id" /> |
|||
</group> |
|||
<group> |
|||
<field name="start_time" /> |
|||
<field name="end_time" /> |
|||
</group> |
|||
</group> |
|||
</sheet> |
|||
<!-- Solution Ex1 --> |
|||
<div class="oe_chatter"> |
|||
<field name="message_follower_ids" widget="mail_followers" /> |
|||
<field name="message_ids" widget="mail_thread" /> |
|||
</div> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<!-- Actions --> |
|||
<record model="ir.actions.act_window" id="action_task"> |
|||
<field name="name">Task Action</field> |
|||
<field name="res_model">beesdoo.shift.shift</field> |
|||
<field name="view_mode">calendar,tree,form,pivot</field> |
|||
</record> |
|||
|
|||
<!-- Top menu item --> |
|||
<menuitem name="Planning" id="menu_task_top" parent="menu_root" |
|||
sequence="1" /> |
|||
<!-- actions --> |
|||
<menuitem name="Shift" id="menu_task" parent="menu_task_top" |
|||
action="action_task" /> |
|||
</odoo> |
@ -0,0 +1,246 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="task_template_view_tree"> |
|||
<field name="name">Shift Template List</field> |
|||
<field name="model">beesdoo.shift.template</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="planning_id" /> |
|||
<field name="task_type_id" /> |
|||
<field name="name" /> |
|||
<field name="day_nb_id" /> |
|||
<field name="start_time" /> |
|||
<field name="end_time" /> |
|||
<field name="duration" /> |
|||
<field name="worker_nb" /> |
|||
<field name="remaining_worker" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_template_view_search"> |
|||
<field name="name">Shift Template Search</field> |
|||
<field name="model">beesdoo.shift.template</field> |
|||
<field name="arch" type="xml"> |
|||
<search> |
|||
<field name="name" /> |
|||
<field name="planning_id" /> |
|||
<field name="task_type_id" /> |
|||
<field name="day_nb_id" /> |
|||
<field name="worker_ids" /> |
|||
<filter string="Planning" context="{'group_by':'planning_id'}" /> |
|||
<filter string="Week Day" context="{'group_by':'day_nb_id'}" /> |
|||
<filter string="Place Available" name="available" |
|||
domain="[('remaining_worker', '>', 0)]" /> |
|||
</search> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_template_view_form"> |
|||
<field name="name">Task Template Form</field> |
|||
<field name="model">beesdoo.shift.template</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<sheet> |
|||
<div class="oe_title"> |
|||
<h1> |
|||
<field name="name" placeholder="name" /> |
|||
</h1> |
|||
</div> |
|||
<group> |
|||
<group> |
|||
<field name="day_nb_id" /> |
|||
<field name="planning_id" /> |
|||
<field name="task_type_id" /> |
|||
<field name="worker_nb" /> |
|||
<field name="remaining_worker" /> |
|||
<field name="active" /> |
|||
</group> |
|||
<group> |
|||
<field name="start_time" widget="float_time" /> |
|||
<field name="duration" widget="float_time" /> |
|||
<field name="end_time" widget="float_time" /> |
|||
</group> |
|||
</group> |
|||
<separator string="Recurring Workers" /> |
|||
<field name="worker_ids" nolabel="1" /> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_template_view_calendar"> |
|||
<field name="name">Shift Template Calendar</field> |
|||
<field name="model">beesdoo.shift.template</field> |
|||
<field name="arch" type="xml"> |
|||
<calendar string="Calendar View" date_start="start_date" |
|||
date_stop="end_date" color="task_type_id"> |
|||
<field name="name" /> |
|||
<field name="worker_ids" /> |
|||
</calendar> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="task_template_view_kanban"> |
|||
<field name="name">Task Template Kanban</field> |
|||
<field name="model">beesdoo.shift.template</field> |
|||
<field name="arch" type="xml"> |
|||
<kanban> |
|||
<field name="planning_id" /> |
|||
<field name="color" /> |
|||
<field name="task_type_id" /> |
|||
<field name="name" /> |
|||
<field name="day_nb_id" /> |
|||
<field name="worker_nb" /> |
|||
<field name="worker_ids" /> |
|||
<field name="worker_name" /> |
|||
<templates> |
|||
<t t-name="kanban-box"> |
|||
<div |
|||
t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> |
|||
<div class="o_dropdown_kanban dropdown" |
|||
groups="base.group_user"> |
|||
<a class="dropdown-toggle btn" |
|||
data-toggle="dropdown" href="#"> |
|||
<span class="fa fa-bars fa-lg" /> |
|||
</a> |
|||
<ul class="dropdown-menu" role="menu" |
|||
aria-labelledby="dLabel"> |
|||
<t t-if="widget.editable"> |
|||
<li> |
|||
<a type="edit">Edit Shift |
|||
Template</a> |
|||
</li> |
|||
</t> |
|||
<t t-if="widget.deletable"> |
|||
<li> |
|||
<a type="delete">Delete</a> |
|||
</li> |
|||
</t> |
|||
<li> |
|||
<ul class="oe_kanban_colorpicker" |
|||
data-field="color" /> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="oe_kanban_content"> |
|||
<strong> |
|||
<field name="name" /> |
|||
</strong> |
|||
<div> |
|||
<field name="planning_id" /> |
|||
</div> |
|||
<div t-if="record.task_type_id.raw_value"> |
|||
Type: |
|||
<field name="task_type_id" /> |
|||
</div> |
|||
<div> |
|||
Worker Number: |
|||
<field name="worker_nb" /> |
|||
</div> |
|||
<div> |
|||
<field name="start_time" |
|||
widget="float_time" /> |
|||
- |
|||
<field name="end_time" widget="float_time" /> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<br /> |
|||
<strong>Recurring Workers</strong> |
|||
<t |
|||
t-foreach="record.worker_name.raw_value.split(',')" |
|||
t-as="worker"> |
|||
<div> |
|||
<t t-esc="worker" /> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
</templates> |
|||
</kanban> |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem name="Shift Management" id="menu_root" /> |
|||
<menuitem name="Templates" id="menu_template_top" parent="menu_root" /> |
|||
|
|||
|
|||
<!-- Configuration --> |
|||
<record model="ir.ui.view" id="daynumber_view_tree"> |
|||
<field name="name">Day Number List</field> |
|||
<field name="model">beesdoo.shift.daynumber</field> |
|||
<field name="arch" type="xml"> |
|||
<tree editable="top"> |
|||
<field name="name" /> |
|||
<field name="number" /> |
|||
<field name="active" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="type_view_tree"> |
|||
<field name="name">Shift Type List</field> |
|||
<field name="model">beesdoo.shift.type</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name" /> |
|||
<field name="description" /> |
|||
<field name="active" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.actions.act_window" id="action_generate_shift_template_wizard"> |
|||
<field name="name">Generate Shift Template</field> |
|||
<field name="res_model">beesddoo.shift.generate_shift_template</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="type_view_form"> |
|||
<field name="name">Shift Type Form</field> |
|||
<field name="model">beesdoo.shift.type</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<header> |
|||
<button type="action" |
|||
name="%(action_generate_shift_template_wizard)d" |
|||
string="Generate shift Templates" /> |
|||
</header> |
|||
<sheet> |
|||
<group> |
|||
<group> |
|||
<field name="name" /> |
|||
</group> |
|||
<group> |
|||
<field name="active" /> |
|||
</group> |
|||
</group> |
|||
<separator string="Description" /> |
|||
<field name="description" /> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<menuitem name="Configuration" id="menu_configuration_top" |
|||
parent="menu_root" /> |
|||
|
|||
<record model="ir.actions.act_window" id="action_day_number"> |
|||
<field name="name">Day Number</field> |
|||
<field name="res_model">beesdoo.shift.daynumber</field> |
|||
<field name="view_mode">tree</field> |
|||
</record> |
|||
|
|||
<menuitem name="Shift Day" id="menu_configuration_day" |
|||
parent="menu_configuration_top" action="action_day_number" /> |
|||
|
|||
<record model="ir.actions.act_window" id="action_type"> |
|||
<field name="name">Shift Type</field> |
|||
<field name="res_model">beesdoo.shift.type</field> |
|||
<field name="view_mode">tree,form</field> |
|||
</record> |
|||
|
|||
<menuitem name="Shift Type" id="menu_configuration_type" |
|||
parent="menu_configuration_top" action="action_type" /> |
|||
</odoo> |
@ -0,0 +1,2 @@ |
|||
import instanciate_planning |
|||
import batch_template |
@ -0,0 +1,53 @@ |
|||
# -*- coding: utf-8 -*- |
|||
''' |
|||
Created on 2 janv. 2017 |
|||
|
|||
@author: Thibault Francois |
|||
''' |
|||
|
|||
from openerp import models, fields, api, _ |
|||
|
|||
class GenerateShiftTemplate(models.TransientModel): |
|||
_name = 'beesddoo.shift.generate_shift_template' |
|||
|
|||
day_ids = fields.Many2many('beesdoo.shift.daynumber', relation='template_gen_day_number_rel', column1='wizard_id', column2='day_id') |
|||
planning_id = fields.Many2one('beesdoo.shift.planning', required=True) |
|||
type_id = fields.Many2one('beesdoo.shift.type', default=lambda self: self._context.get('active_id')) |
|||
line_ids = fields.One2many('beesddoo.shift.generate_shift_template.line', 'wizard_id') |
|||
|
|||
@api.multi |
|||
def generate(self): |
|||
self.ensure_one() |
|||
ids = [] |
|||
for day in self.day_ids: |
|||
for line in self.line_ids: |
|||
shift_template_data = { |
|||
'name': '%s' % self.type_id.name, |
|||
'planning_id': self.planning_id.id, |
|||
'task_type_id': self.type_id.id, |
|||
'day_nb_id': day.id, |
|||
'start_time': line.start_time, |
|||
'end_time': line.end_time, |
|||
'duration': line.end_time - line.start_time, |
|||
'worker_nb': line.worker_nb, |
|||
} |
|||
new_rec = self.env['beesdoo.shift.template'].create(shift_template_data) |
|||
ids.append(new_rec.id) |
|||
return { |
|||
'name': _('Generated Shift Template'), |
|||
'type': 'ir.actions.act_window', |
|||
'view_type': 'form', |
|||
'view_mode': 'kanban,tree,form', |
|||
'res_model': 'beesdoo.shift.template', |
|||
'target': 'current', |
|||
'domain': [('id', 'in', ids)], |
|||
'context': {'group_by': 'day_nb_id'}, |
|||
} |
|||
|
|||
class GenerateShiftTemplateLine(models.TransientModel): |
|||
_name = 'beesddoo.shift.generate_shift_template.line' |
|||
|
|||
wizard_id = fields.Many2one('beesddoo.shift.generate_shift_template') |
|||
start_time = fields.Float(required=True) |
|||
end_time = fields.Float(required=True) |
|||
worker_nb = fields.Integer(default=1) |
@ -0,0 +1,41 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="task_template_generation_view_form"> |
|||
<field name="name">Planning Form</field> |
|||
<field name="model">beesddoo.shift.generate_shift_template</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="planning_id" /> |
|||
<field name="type_id" invisible="1" /> |
|||
</group> |
|||
<group> |
|||
<group> |
|||
<separator string="Daily Schedule" colspan="2"/> |
|||
<field name="line_ids" nolabel="1" > |
|||
<tree editable="bottom"> |
|||
<field name="start_time" widget="float_time" /> |
|||
<field name="end_time" widget="float_time" /> |
|||
<field name="worker_nb" /> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
<group> |
|||
<separator string="Apply for Days" colspan="2"/> |
|||
<field name="day_ids" nolabel="1" > |
|||
<tree> |
|||
<field name="name" /> |
|||
<field name="number" /> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
</group> |
|||
<footer> |
|||
<button type="object" name="generate" string="Confirm" class="oe_highlight"/> |
|||
or |
|||
<button special="cancel" string="Cancel"/> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,18 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp import models, fields, api |
|||
|
|||
|
|||
class InstanciatePlanning(models.TransientModel): |
|||
_name = 'beesddoo.shift.generate_planning' |
|||
|
|||
def _get_planning(self): |
|||
return self._context.get('active_id') |
|||
|
|||
date_start = fields.Date("First Day of planning", required=True) |
|||
planning_id = fields.Many2one('beesdoo.shift.planning', readonly=True, default=_get_planning) |
|||
|
|||
@api.multi |
|||
def generate_task(self): |
|||
self.ensure_one() |
|||
self = self.with_context(visualize_date=self.date_start) |
|||
self.planning_id.task_template_ids._generate_task_day() |
@ -0,0 +1,20 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="planning_instanciate_view_form"> |
|||
<field name="name">Planning Form</field> |
|||
<field name="model">beesddoo.shift.generate_planning</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="date_start" /> |
|||
<field name="planning_id" invisible="1" /> |
|||
</group> |
|||
<footer> |
|||
<button type="object" name="generate_task" string="Confirm" class="oe_highlight"/> |
|||
or |
|||
<button special="cancel" string="Cancel"/> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue