Default value of company should be -1 to get the right cast and an impossible value. Replace False by None as other value in "in" clause. issue3394 review1119002
255 lines
9.1 KiB
Python
255 lines
9.1 KiB
Python
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
#this repository contains the full copyright notices and license terms.
|
|
from sql import Literal
|
|
from sql.aggregate import Max, Sum
|
|
from sql.conditionals import Coalesce
|
|
from sql.functions import Extract
|
|
|
|
from trytond.model import ModelView, ModelSQL, fields
|
|
from trytond.wizard import Wizard, StateView, StateAction, Button
|
|
from trytond.pyson import Eval, PYSONEncoder, Date, Get
|
|
from trytond.transaction import Transaction
|
|
from trytond.pool import Pool
|
|
|
|
__all__ = ['Line', 'EnterLinesStart', 'EnterLines',
|
|
'HoursEmployee',
|
|
'OpenHoursEmployeeStart', 'OpenHoursEmployee',
|
|
'HoursEmployeeWeekly', 'HoursEmployeeMonthly']
|
|
|
|
|
|
class Line(ModelSQL, ModelView):
|
|
'Timesheet Line'
|
|
__name__ = 'timesheet.line'
|
|
employee = fields.Many2One('company.employee', 'Employee', required=True,
|
|
select=True, domain=[
|
|
('company', '=', Eval('context', {}).get('company', -1)),
|
|
])
|
|
date = fields.Date('Date', required=True, select=True)
|
|
hours = fields.Float('Hours', digits=(16, 2), required=True)
|
|
work = fields.Many2One('timesheet.work', 'Work',
|
|
required=True, select=True, domain=[
|
|
('timesheet_available', '=', True),
|
|
['OR',
|
|
('timesheet_start_date', '=', None),
|
|
('timesheet_start_date', '<=', Eval('date')),
|
|
],
|
|
['OR',
|
|
('timesheet_end_date', '=', None),
|
|
('timesheet_end_date', '>=', Eval('date')),
|
|
],
|
|
],
|
|
depends=['date'])
|
|
description = fields.Char('Description')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(Line, cls).__setup__()
|
|
cls._sql_constraints += [
|
|
('check_move_hours_pos',
|
|
'CHECK(hours >= 0.0)', 'Hours field must be positive'),
|
|
]
|
|
|
|
@staticmethod
|
|
def default_employee():
|
|
User = Pool().get('res.user')
|
|
employee_id = None
|
|
if Transaction().context.get('employee'):
|
|
employee_id = Transaction().context['employee']
|
|
else:
|
|
user = User(Transaction().user)
|
|
if user.employee:
|
|
employee_id = user.employee.id
|
|
if employee_id:
|
|
return employee_id
|
|
|
|
@staticmethod
|
|
def default_date():
|
|
Date_ = Pool().get('ir.date')
|
|
return Transaction().context.get('date') or Date_.today()
|
|
|
|
@classmethod
|
|
def view_header_get(cls, value, view_type='form'):
|
|
if not Transaction().context.get('employee'):
|
|
return value
|
|
Employee = Pool().get('company.employee')
|
|
employee = Employee(Transaction().context['employee'])
|
|
return value + " (" + employee.rec_name + ")"
|
|
|
|
|
|
class EnterLinesStart(ModelView):
|
|
'Enter Lines'
|
|
__name__ = 'timesheet.line.enter.start'
|
|
employee = fields.Many2One('company.employee', 'Employee', required=True,
|
|
domain=[('company', '=', Eval('context', {}).get('company', -1))])
|
|
date = fields.Date('Date', required=True)
|
|
|
|
@staticmethod
|
|
def default_employee():
|
|
Line = Pool().get('timesheet.line')
|
|
return Line.default_employee()
|
|
|
|
@staticmethod
|
|
def default_date():
|
|
Line = Pool().get('timesheet.line')
|
|
return Line.default_date()
|
|
|
|
|
|
class EnterLines(Wizard):
|
|
'Enter Lines'
|
|
__name__ = 'timesheet.line.enter'
|
|
start = StateView('timesheet.line.enter.start',
|
|
'timesheet.line_enter_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Enter', 'enter', 'tryton-ok', default=True),
|
|
])
|
|
enter = StateAction('timesheet.act_line_form')
|
|
|
|
def do_enter(self, action):
|
|
date = self.start.date
|
|
date = Date(date.year, date.month, date.day)
|
|
action['pyson_domain'] = PYSONEncoder().encode([
|
|
('employee', '=', self.start.employee.id),
|
|
('date', '=', date),
|
|
])
|
|
action['pyson_context'] = PYSONEncoder().encode({
|
|
'employee': self.start.employee.id,
|
|
'date': date,
|
|
})
|
|
action['name'] += " - " + self.start.employee.rec_name
|
|
return action, {}
|
|
|
|
def transition_enter(self):
|
|
return 'end'
|
|
|
|
|
|
class HoursEmployee(ModelSQL, ModelView):
|
|
'Hours per Employee'
|
|
__name__ = 'timesheet.hours_employee'
|
|
employee = fields.Many2One('company.employee', 'Employee', select=True)
|
|
hours = fields.Float('Hours', digits=(16, 2))
|
|
|
|
@staticmethod
|
|
def table_query():
|
|
pool = Pool()
|
|
Line = pool.get('timesheet.line')
|
|
line = Line.__table__()
|
|
where = Literal(True)
|
|
if Transaction().context.get('start_date'):
|
|
where &= line.date >= Transaction().context['start_date']
|
|
if Transaction().context.get('end_date'):
|
|
where &= line.date <= Transaction().context['end_date']
|
|
return line.select(
|
|
line.employee.as_('id'),
|
|
Max(line.create_uid).as_('create_uid'),
|
|
Max(line.create_date).as_('create_date'),
|
|
Max(line.write_uid).as_('write_uid'),
|
|
Max(line.write_date).as_('write_date'),
|
|
line.employee,
|
|
Sum(Coalesce(line.hours, 0)).as_('hours'),
|
|
where=where,
|
|
group_by=line.employee)
|
|
|
|
|
|
class OpenHoursEmployeeStart(ModelView):
|
|
'Open Hours per Employee'
|
|
__name__ = 'timesheet.hours_employee.open.start'
|
|
start_date = fields.Date('Start Date')
|
|
end_date = fields.Date('End Date')
|
|
|
|
|
|
class OpenHoursEmployee(Wizard):
|
|
'Open Hours per Employee'
|
|
__name__ = 'timesheet.hours_employee.open'
|
|
start = StateView('timesheet.hours_employee.open.start',
|
|
'timesheet.hours_employee_open_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Open', 'open_', 'tryton-ok', default=True),
|
|
])
|
|
open_ = StateAction('timesheet.act_hours_employee_form')
|
|
|
|
def do_open_(self, action):
|
|
action['pyson_context'] = PYSONEncoder().encode({
|
|
'start_date': self.start.start_date,
|
|
'end_date': self.start.end_date,
|
|
})
|
|
return action, {}
|
|
|
|
def transition_open_(self):
|
|
return 'end'
|
|
|
|
|
|
class HoursEmployeeWeekly(ModelSQL, ModelView):
|
|
'Hours per Employee per Week'
|
|
__name__ = 'timesheet.hours_employee_weekly'
|
|
year = fields.Char('Year', select=True)
|
|
week = fields.Integer('Week', select=True)
|
|
employee = fields.Many2One('company.employee', 'Employee', select=True)
|
|
hours = fields.Float('Hours', digits=(16, 2), select=True)
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(HoursEmployeeWeekly, cls).__setup__()
|
|
cls._order.insert(0, ('year', 'DESC'))
|
|
cls._order.insert(1, ('week', 'DESC'))
|
|
cls._order.insert(2, ('employee', 'ASC'))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
pool = Pool()
|
|
Line = pool.get('timesheet.line')
|
|
line = Line.__table__()
|
|
type_name = cls.year.sql_type().base
|
|
year_column = Extract('YEAR', line.date).cast(type_name).as_('year')
|
|
week_column = Extract('WEEK', line.date).as_('week')
|
|
return line.select(
|
|
Max(Extract('WEEK', line.date)
|
|
+ Extract('YEAR', line.date) * 100
|
|
+ line.employee * 1000000).as_('id'),
|
|
Max(line.create_uid).as_('create_uid'),
|
|
Max(line.create_date).as_('create_date'),
|
|
Max(line.write_uid).as_('write_uid'),
|
|
Max(line.write_date).as_('write_date'),
|
|
year_column,
|
|
week_column,
|
|
line.employee,
|
|
Sum(Coalesce(line.hours, 0)).as_('hours'),
|
|
group_by=(year_column, week_column, line.employee))
|
|
|
|
|
|
class HoursEmployeeMonthly(ModelSQL, ModelView):
|
|
'Hours per Employee per Month'
|
|
__name__ = 'timesheet.hours_employee_monthly'
|
|
year = fields.Char('Year', select=True)
|
|
month = fields.Integer('Month', select=True)
|
|
employee = fields.Many2One('company.employee', 'Employee', select=True)
|
|
hours = fields.Float('Hours', digits=(16, 2), select=True)
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(HoursEmployeeMonthly, cls).__setup__()
|
|
cls._order.insert(0, ('year', 'DESC'))
|
|
cls._order.insert(1, ('month', 'DESC'))
|
|
cls._order.insert(2, ('employee', 'ASC'))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
pool = Pool()
|
|
Line = pool.get('timesheet.line')
|
|
line = Line.__table__()
|
|
type_name = cls.year.sql_type().base
|
|
year_column = Extract('YEAR', line.date).cast(type_name).as_('year')
|
|
month_column = Extract('MONTH', line.date).as_('month')
|
|
return line.select(
|
|
Max(Extract('MONTH', line.date)
|
|
+ Extract('YEAR', line.date) * 100
|
|
+ line.employee * 1000000).as_('id'),
|
|
Max(line.create_uid).as_('create_uid'),
|
|
Max(line.create_date).as_('create_date'),
|
|
Max(line.write_uid).as_('write_uid'),
|
|
Max(line.write_date).as_('write_date'),
|
|
year_column,
|
|
month_column,
|
|
line.employee,
|
|
Sum(Coalesce(line.hours, 0)).as_('hours'),
|
|
group_by=(year_column, month_column, line.employee))
|