[FIX] complete rewrite for clean up of hr_holidays

bzr revid: fp@tinyerp.com-20101229124123-7tt4ttk3jmkispw7
This commit is contained in:
Fabien Pinckaers 2010-12-29 13:41:23 +01:00
parent b05d9cfe25
commit 0a7c9c6ee2
13 changed files with 156 additions and 404 deletions

View File

@ -6,7 +6,6 @@
groups="group_account_user,group_account_manager,group_account_invoice"
web_icon="images/accounting.png"
web_icon_hover="images/accounting-hover.png"/>
<menuitem id="menu_partners" name="Partners" parent="menu_finance" sequence="1"/>
<menuitem id="menu_finance_receivables" name="Customers" parent="menu_finance" sequence="2"/>
<menuitem id="menu_finance_payables" name="Suppliers" parent="menu_finance" sequence="3"/>
<menuitem id="menu_finance_bank_and_cash" name="Bank and Cash" parent="menu_finance" sequence="4"

View File

@ -2762,11 +2762,13 @@ action = self.pool.get('res.config').next(cr, uid, [], context)
<field name="filter" eval="True"/>
</record>
<menuitem id="menu_partners_partners"
name="Partners"
parent="menu_partners"
action="action_partner_all"
sequence="1"/>
<menuitem id="menu_account_supplier" name="Customers"
parent="menu_finance_receivables"
action="base.action_partner_customer_form" sequence="100"/>
<menuitem id="menu_account_supplier" name="Suppliers"
parent="menu_finance_payables"
action="base.action_partner_supplier_form" sequence="100"/>
</data>
</openerp>

View File

@ -44,7 +44,7 @@
<field name="alarm_id" string="Reminder"
widget="selection" />
<group colspan="2" col="4" >
<field name="recurrency"/>
<field name="recurrency"/>
<field name="edit_all" attrs="{'invisible':[('recurrency','=', False)]}"
on_change="onchange_edit_all(rrule_type,edit_all)"/>
</group>

View File

@ -35,37 +35,11 @@ class hr_holidays_status(osv.osv):
_name = "hr.holidays.status"
_description = "Leave Type"
def get_days_cat(self, cr, uid, ids, category_id, return_false, context=None):
cr.execute("""SELECT id, type, number_of_days, holiday_status_id FROM hr_holidays WHERE category_id = %s AND state='validate' AND holiday_status_id in %s""",
[category_id, tuple(ids)])
result = sorted(cr.dictfetchall(), key=lambda x: x['holiday_status_id'])
grouped_lines = dict((k, [v for v in itr]) for k, itr in groupby(result, itemgetter('holiday_status_id')))
res = {}
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = {}
max_leaves = leaves_taken = 0
if not return_false:
if record.id in grouped_lines:
leaves_taken = -sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'remove'])
max_leaves = sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'add'])
res[record.id]['max_leaves'] = max_leaves
res[record.id]['leaves_taken'] = leaves_taken
res[record.id]['remaining_leaves'] = max_leaves - leaves_taken
return res
def get_days(self, cr, uid, ids, employee_id, return_false, context=None):
cr.execute("""SELECT id, type, number_of_days, holiday_status_id FROM hr_holidays WHERE employee_id = %s AND state='validate' AND holiday_status_id in %s""",
[employee_id, tuple(ids)])
result = sorted(cr.dictfetchall(), key=lambda x: x['holiday_status_id'])
grouped_lines = dict((k, [v for v in itr]) for k, itr in groupby(result, itemgetter('holiday_status_id')))
res = {}
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = {}
@ -74,18 +48,15 @@ class hr_holidays_status(osv.osv):
if record.id in grouped_lines:
leaves_taken = -sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'remove'])
max_leaves = sum([item['number_of_days'] for item in grouped_lines[record.id] if item['type'] == 'add'])
res[record.id]['max_leaves'] = max_leaves
res[record.id]['leaves_taken'] = leaves_taken
res[record.id]['remaining_leaves'] = max_leaves - leaves_taken
return res
def _user_left_days(self, cr, uid, ids, name, args, context=None):
return_false = False
employee_id = False
res = {}
if context and context.has_key('employee_id'):
if not context['employee_id']:
return_false = True
@ -102,10 +73,9 @@ class hr_holidays_status(osv.osv):
res = dict.fromkeys(ids, {'leaves_taken': 0, 'remaining_leaves': 0, 'max_leaves': 0})
return res
# To do: we can add remaining_leaves_category field to display remaining leaves for particular type
_columns = {
'name': fields.char('Leave Type', size=64, required=True, translate=True),
'categ_id': fields.many2one('crm.case.categ', 'Meeting Category', domain="[('object_id.model', '=', 'crm.meeting')]", help='If you link this type of leave with a category in the CRM, it will synchronize each leave asked with a case in this category, to display it in the company shared calendar for example.'),
'categ_id': fields.many2one('crm.case.categ', 'Meeting', domain="[('object_id.model', '=', 'crm.meeting')]", help='If you set a meeting type, OpenERP will create a meeting in the calendar once a leave is validated.'),
'color_name': fields.selection([('red', 'Red'),('blue','Blue'), ('lightgreen', 'Light Green'), ('lightblue','Light Blue'), ('lightyellow', 'Light Yellow'), ('magenta', 'Magenta'),('lightcyan', 'Light Cyan'),('black', 'Black'),('lightpink', 'Light Pink'),('brown', 'Brown'),('violet', 'Violet'),('lightcoral', 'Light Coral'),('lightsalmon', 'Light Salmon'),('lavender', 'Lavender'),('wheat', 'Wheat'),('ivory', 'Ivory')],'Color in Report', required=True, help='This color will be used in the leaves summary located in Reporting\Leaves by Departement'),
'limit': fields.boolean('Allow to Override Limit', help='If you tick this checkbox, the system will allow, for this section, the employees to take more leaves than the available ones.'),
'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the leave type without removing it."),
@ -118,7 +88,6 @@ class hr_holidays_status(osv.osv):
'color_name': 'red',
'active': True,
}
hr_holidays_status()
class hr_holidays(osv.osv):
@ -132,12 +101,23 @@ class hr_holidays(osv.osv):
return ids[0]
return False
def _compute_number_of_days(self, cr, uid, ids, name, args, context=None):
result = {}
for hol in self.browse(cr, uid, ids, context=context):
if hol.type=='remove':
result[hol.id] = -hol.number_of_days_temp
else:
result[hol.id] = hol.number_of_days_temp
return result
_columns = {
'name': fields.char('Description', required=True, size=64),
'state': fields.selection([('draft', 'Draft'), ('confirm', 'Waiting Approval'), ('refuse', 'Refused'), ('validate1', 'Waiting Second Approval'), ('validate', 'Approved'), ('cancel', 'Cancelled')], 'State', readonly=True, help='When the holiday request is created the state is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the state is \'Waiting Approval\'.\
'state': fields.selection([('draft', 'Draft'), ('confirm', 'Waiting Approval'), ('refuse', 'Refused'),
('validate1', 'Waiting Second Approval'), ('validate', 'Approved'), ('cancel', 'Cancelled')],
'State', readonly=True, help='When the holiday request is created the state is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the state is \'Waiting Approval\'.\
If the admin accepts it, the state is \'Approved\'. If it is refused, the state is \'Refused\'.'),
'user_id':fields.related('employee_id', 'user_id', type='many2one', relation='res.users', string='User', store=True),
'date_from': fields.datetime('Start Date', readonly=True, states={'draft':[('readonly',False)]}),
'user_id':fields.many2one('res.users', 'User', states={'draft':[('readonly',False)]}, select=True, readonly=True),
'date_to': fields.datetime('End Date', readonly=True, states={'draft':[('readonly',False)]}),
'holiday_status_id': fields.many2one("hr.holidays.status", "Leave Type", required=True,readonly=True, states={'draft':[('readonly',False)]}),
'employee_id': fields.many2one('hr.employee', "Employee", select=True, invisible=False, readonly=True, states={'draft':[('readonly',False)]}, help='Leave Manager can let this field empty if this leave request/allocation is for every employee'),
@ -145,27 +125,29 @@ class hr_holidays(osv.osv):
#'notes': fields.text('Notes',readonly=True, states={'draft':[('readonly',False)]}),
'manager_id': fields.many2one('hr.employee', 'First Approval', invisible=False, readonly=True, help='This area is automaticly filled by the user who validate the leave'),
'notes': fields.text('Reasons',readonly=True, states={'draft':[('readonly',False)]}),
'number_of_days': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)]}),
'number_of_days_temp': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)]}),
'case_id': fields.many2one('crm.meeting', 'Case'),
'number_of_days': fields.function(_compute_number_of_days, method=True, string='Number of Days', store=True),
'case_id': fields.many2one('crm.meeting', 'Meeting'),
'type': fields.selection([('remove','Leave Request'),('add','Allocation Request')], 'Request Type', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="Choose 'Leave Request' if someone wants to take an off-day. \nChoose 'Allocation Request' if you want to increase the number of leaves available for someone"),
'allocation_type': fields.selection([('employee','Employee Request'),('company','Company Allocation')], 'Allocation Type', required=True, readonly=True, states={'draft':[('readonly',False)]}, help='This field is only for informative purposes, to depict if the leave request/allocation comes from an employee or from the company'),
'parent_id': fields.many2one('hr.holidays', 'Parent'),
'linked_request_ids': fields.one2many('hr.holidays', 'parent_id', 'Linked Requests',),
'department_id':fields.related('employee_id', 'department_id', string='Department', type='many2one', relation='hr.department', readonly=True, store=True),
'category_id': fields.many2one('hr.employee.category', "Category", help='Category Of employee'),
'category_id': fields.many2one('hr.employee.category', "Category", help='Category of Employee'),
'holiday_type': fields.selection([('employee','By Employee'),('category','By Employee Category')], 'Allocation Type', help='By Employee: Allocation/Request for individual Employee, By Employee Category: Allocation/Request for group of employees in category', required=True),
'manager_id2': fields.many2one('hr.employee', 'Second Approval', readonly=True, help='This area is automaticly filled by the user who validate the leave with second level (If Leave type need second validation)')
}
_defaults = {
'employee_id': _employee_get,
'state': 'draft',
'type': 'remove',
'allocation_type': 'employee',
'user_id': lambda obj, cr, uid, context: uid,
'holiday_type': 'employee'
}
_sql_constraints = [
('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))", "You have to select an employee or a category"),
('date_check', "CHECK ( number_of_days_temp > 0 )", "The number of days must be greater than 0 !"),
('date_check2', "CHECK ( (type='add') OR (date_from < date_to))", "The start date must be before the end date !")
]
def _create_resource_leave(self, cr, uid, vals, context=None):
'''This method will create entry in resource calendar leave object at the time of holidays validated '''
@ -178,28 +160,6 @@ class hr_holidays(osv.osv):
leave_ids = obj_res_leave.search(cr, uid, [('holiday_id', 'in', ids)], context=context)
return obj_res_leave.unlink(cr, uid, leave_ids)
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
if 'holiday_type' in vals:
if vals['holiday_type'] == 'employee':
vals.update({'category_id': False})
else:
vals.update({'employee_id': False})
if context.has_key('type'):
vals['type'] = context['type']
if context.has_key('allocation_type'):
vals['allocation_type'] = context['allocation_type']
return super(hr_holidays, self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
if 'holiday_type' in vals:
if vals['holiday_type'] == 'employee':
vals.update({'category_id': False})
else:
vals.update({'employee_id': False})
return super(hr_holidays, self).write(cr, uid, ids, vals, context=context)
def onchange_type(self, cr, uid, ids, holiday_type):
result = {}
if holiday_type == 'employee':
@ -207,9 +167,10 @@ class hr_holidays(osv.osv):
if ids_employee:
result['value'] = {
'employee_id': ids_employee[0]
}
}
return result
# TODO: can be improved using resource calendar method
def _get_number_of_days(self, date_from, date_to):
"""Returns a float equals to the timedelta between two dates given as string."""
@ -220,35 +181,10 @@ class hr_holidays(osv.osv):
diff_day = timedelta.days + float(timedelta.seconds) / 86400
return diff_day
def _update_user_holidays(self, cr, uid, ids):
obj_crm_meeting = self.pool.get('crm.meeting')
for record in self.browse(cr, uid, ids):
if record.state=='validate':
if record.case_id:
obj_crm_meeting.unlink(cr, uid, [record.case_id.id])
if record.linked_request_ids:
list_ids = [ lr.id for lr in record.linked_request_ids]
self.holidays_cancel(cr, uid, list_ids)
self.unlink(cr, uid, list_ids)
return True
def _check_date(self, cr, uid, ids, context=None):
for rec in self.read(cr, uid, ids, ['number_of_days_temp', 'date_from','date_to', 'type']):
if rec['number_of_days_temp'] < 0:
return False
if rec['type'] == 'add':
continue
date_from = time.strptime(rec['date_from'], '%Y-%m-%d %H:%M:%S')
date_to = time.strptime(rec['date_to'], '%Y-%m-%d %H:%M:%S')
if date_from > date_to:
return False
return True
_constraints = [(_check_date, 'Start date should not be larger than end date!\nNumber of Days should be greater than 1!', ['number_of_days_temp'])]
def unlink(self, cr, uid, ids, context=None):
self._update_user_holidays(cr, uid, ids)
self._remove_resouce_leave(cr, uid, ids, context=context)
for rec in self.browse(cr, uid, ids, context=context):
if rec.state<>'draft':
raise osv.except_osv(_('Warning!'),_('You cannot delete a leave which is not in draft state !'))
return super(hr_holidays, self).unlink(cr, uid, ids, context)
def onchange_date_from(self, cr, uid, ids, date_to, date_from):
@ -264,209 +200,115 @@ class hr_holidays(osv.osv):
}
return result
def onchange_date_to(self, cr, uid, ids, date_from, date_to):
return self.onchange_date_from(cr, uid, ids, date_to, date_from)
def onchange_sec_id(self, cr, uid, ids, status, context=None):
warning = {}
if status:
brows_obj = self.pool.get('hr.holidays.status').browse(cr, uid, [status], context=context)[0]
brows_obj = self.pool.get('hr.holidays.status').browse(cr, uid, status, context=context)
if brows_obj.categ_id and brows_obj.categ_id.section_id and not brows_obj.categ_id.section_id.allow_unlink:
warning = {
'title': "Warning for ",
'message': "You won\'t be able to cancel this leave request because the CRM Sales Team of the leave type disallows."
}
}
return {'warning': warning}
def set_to_draft(self, cr, uid, ids, *args):
wf_service = netsvc.LocalService("workflow")
self.write(cr, uid, ids, {
'state': 'draft',
'manager_id': False,
'number_of_days': 0,
})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_create(uid, 'hr.holidays', id, cr)
return True
def holidays_validate2(self, cr, uid, ids, *args):
obj_emp = self.pool.get('hr.employee')
wf_service = netsvc.LocalService("workflow")
vals = {'state':'validate1'}
self.check_holidays(cr, uid, ids)
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
if ids2:
vals['manager_id'] = ids2[0]
else:
raise osv.except_osv(_('Warning !'),_('No user related to the selected employee.'))
# Second Time Validate all the leave requests of the category
for leave_id in self._get_category_leave_ids(cr, uid, ids):
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'second_validate', cr)
return self.write(cr, uid, ids, vals)
def holidays_validate(self, cr, uid, ids, *args):
obj_emp = self.pool.get('hr.employee')
wf_service = netsvc.LocalService("workflow")
data_holiday = self.browse(cr, uid, ids)
self.check_holidays(cr, uid, ids)
vals = {'state':'validate'}
obj_emp = self.pool.get('hr.employee')
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
if ids2:
if data_holiday[0].state == 'validate1':
vals['manager_id2'] = ids2[0]
else:
vals['manager_id'] = ids2[0]
else:
raise osv.except_osv(_('Warning !'), _('No user related to the selected employee.'))
self.write(cr, uid, ids, vals)
manager = ids2 and ids2[0] or False
return self.write(cr, uid, ids, {'state':'validate1', 'manager_id': manager})
def holidays_validate2(self, cr, uid, ids, *args):
self.check_holidays(cr, uid, ids)
obj_emp = self.pool.get('hr.employee')
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
manager = ids2 and ids2[0] or False
self.write(cr, uid, ids, {'state':'validate', 'manager_id2': manager})
data_holiday = self.browse(cr, uid, ids)
for record in data_holiday:
if record.holiday_type == 'employee' and record.type == 'remove':
vals = {
'name': record.name,
'date_from': record.date_from,
'date_to': record.date_to,
'calendar_id': record.employee_id.calendar_id.id,
'company_id': record.employee_id.company_id.id,
'resource_id': record.employee_id.resource_id.id,
'holiday_id': record.id
}
self._create_resource_leave(cr, uid, vals)
elif record.holiday_type == 'category':
# Create leave/allocation request for employees in the category
emp_ids = obj_emp.search(cr, uid, [('category_ids', '=', record.category_id.id)])
leave_ids = []
for emp in obj_emp.browse(cr, uid, emp_ids):
vals = {
'name': record.name,
'type': record.type,
'holiday_type': 'employee',
'holiday_status_id': record.holiday_status_id.id,
'date_from': record.date_from,
'date_to': record.date_to,
'notes': record.notes,
'number_of_days_temp': record.number_of_days_temp,
'parent_id': record.id,
'employee_id': emp.id
}
leave_ids.append(self.create(cr, uid, vals, context=None))
# Confirm and validate all the leave requests of the category
for leave_id in leave_ids:
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'confirm', cr)
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'validate', cr)
return True
def holidays_confirm(self, cr, uid, ids, *args):
obj_hr_holiday_status = self.pool.get('hr.holidays.status')
for record in self.browse(cr, uid, ids):
user_id = False
leave_asked = record.number_of_days_temp
if record.holiday_type == 'employee' and record.type == 'remove':
if record.employee_id and not record.holiday_status_id.limit:
leaves_rest = obj_hr_holiday_status.get_days( cr, uid, [record.holiday_status_id.id], record.employee_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
if leaves_rest < leave_asked:
raise osv.except_osv(_('Warning!'),_('You cannot validate leaves for employee %s while there are too few remaining leave days.') % (record.employee_id.name))
nb = -(record.number_of_days_temp)
elif record.holiday_type == 'category' and record.type == 'remove':
if record.category_id and not record.holiday_status_id.limit:
leaves_rest = obj_hr_holiday_status.get_days_cat( cr, uid, [record.holiday_status_id.id], record.category_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
if leaves_rest < leave_asked:
raise osv.except_osv(_('Warning!'),_('You cannot validate leaves for category %s while there are too few remaining leave days.') % (record.category_id.name))
nb = -(record.number_of_days_temp)
else:
nb = record.number_of_days_temp
if record.holiday_type == 'employee' and record.employee_id:
user_id = record.employee_id.user_id and record.employee_id.user_id.id or uid
self.write(cr, uid, [record.id], {'state':'confirm', 'number_of_days': nb, 'user_id': user_id})
return True
def holidays_refuse(self, cr, uid, ids, *args):
obj_emp = self.pool.get('hr.employee')
wf_service = netsvc.LocalService("workflow")
vals = {'state': 'refuse'}
ids2 = obj_emp.search(cr, uid, [('user_id','=', uid)])
if ids2:
vals['manager_id'] = ids2[0]
# Refuse all the leave requests of the category
for leave_id in self._get_category_leave_ids(cr, uid, ids):
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'refuse', cr)
self.write(cr, uid, ids, vals)
return True
def holidays_cancel(self, cr, uid, ids, *args):
self._update_user_holidays(cr, uid, ids)
self.write(cr, uid, ids, {'state': 'cancel'})
self._remove_resouce_leave(cr, uid, ids)
return True
def holidays_draft(self, cr, uid, ids, *args):
wf_service = netsvc.LocalService("workflow")
for leave_id in self._get_category_leave_ids(cr, uid, ids):
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'draft', cr)
return self.write(cr, uid, ids, {'state': 'draft'})
def check_holidays(self, cr, uid, ids):
holi_status_obj = self.pool.get('hr.holidays.status')
emp_obj = self.pool.get('hr.employee')
meeting_obj = self.pool.get('crm.meeting')
for record in self.browse(cr, uid, ids):
if not record.number_of_days:
raise osv.except_osv(_('Warning!'), _('Wrong leave definition.'))
if record.holiday_type=='employee' and record.employee_id:
leave_asked = record.number_of_days
if leave_asked < 0.00:
if not record.holiday_status_id.limit:
leaves_rest = holi_status_obj.get_days(cr, uid, [record.holiday_status_id.id], record.employee_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
if leaves_rest < -(leave_asked):
raise osv.except_osv(_('Warning!'),_('You Cannot Validate leaves while available leaves are less than asked leaves.'))
elif record.holiday_type == 'category' and record.category_id:
leave_asked = record.number_of_days
if leave_asked < 0.00:
if not record.holiday_status_id.limit:
leaves_rest = holi_status_obj.get_days_cat(cr, uid, [record.holiday_status_id.id], record.category_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
if leaves_rest < -(leave_asked):
raise osv.except_osv(_('Warning!'),_('You Cannot Validate leaves while available leaves are less than asked leaves.'))
else:# This condition will never meet!!
holiday_ids = []
vals = {
'name': record.name,
'holiday_status_id': record.holiday_status_id.id,
'state': 'draft',
'date_from': record.date_from,
'date_to': record.date_to,
'notes': record.notes,
'number_of_days': record.number_of_days,
'number_of_days_temp': record.number_of_days_temp,
'type': record.type,
'allocation_type': record.allocation_type,
'parent_id': record.id,
}
employee_ids = emp_obj.search(cr, uid, [])
for employee in employee_ids:
vals['employee_id'] = employee
user_id = emp_obj.search(cr, uid, [('user_id','=',uid)])
if user_id:
vals['user_id'] = user_id[0]
holiday_ids.append(self.create(cr, uid, vals, context=None))
self.holidays_confirm(cr, uid, holiday_ids)
self.holidays_validate(cr, uid, holiday_ids)
if record.holiday_status_id.categ_id and record.date_from and record.date_to and record.employee_id:
diff_day = self._get_number_of_days(record.date_from, record.date_to)
meeting_obj = self.pool.get('crm.meeting')
vals = {
'name': record.name,
'categ_id': record.holiday_status_id.categ_id.id,
'duration': (diff_day) * 8,
'duration': record.number_of_days_temp * 8,
'note': record.notes,
'user_id': record.user_id.id,
'date': record.date_from,
'end_date': record.date_to,
'date_deadline': record.date_to,
}
case_id = meeting_obj.create(cr, uid, vals)
self.write(cr, uid, ids, {'case_id': case_id})
elif record.holiday_type == 'category':
emp_ids = obj_emp.search(cr, uid, [('category_ids', 'child_of', [record.category_id.id])])
leave_ids = []
for emp in obj_emp.browse(cr, uid, emp_ids):
vals = {
'name': record.name,
'type': record.type,
'holiday_type': 'employee',
'holiday_status_id': record.holiday_status_id.id,
'date_from': record.date_from,
'date_to': record.date_to,
'notes': record.notes,
'number_of_days_temp': record.number_of_days_temp,
'parent_id': record.id,
'employee_id': emp.id
}
leave_ids.append(self.create(cr, uid, vals, context=None))
wf_service = netsvc.LocalService("workflow")
for leave_id in leave_ids:
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'confirm', cr)
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'validate', cr)
wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'second_validate', cr)
return True
def holidays_confirm(self, cr, uid, ids, *args):
self.check_holidays(cr, uid, ids)
return self.write(cr, uid, ids, {'state':'confirm'})
def holidays_refuse(self, cr, uid, ids, *args):
obj_emp = self.pool.get('hr.employee')
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
manager = ids2 and ids2[0] or False
self.write(cr, uid, ids, {'state': 'refuse', 'manager_id2': manager})
self.holidays_cancel(cr, uid, ids)
return True
def holidays_cancel(self, cr, uid, ids, *args):
obj_crm_meeting = self.pool.get('crm.meeting')
for record in self.browse(cr, uid, ids):
# Delete the meeting
if record.case_id:
obj_crm_meeting.unlink(cr, uid, [record.case_id.id])
# If a category that created several holidays, cancel all related
wf_service = netsvc.LocalService("workflow")
for id in record.linked_request_ids or []:
wf_service.trg_validate(uid, 'hr.holidays', id, 'cancel', cr)
return True
def check_holidays(self, cr, uid, ids):
holi_status_obj = self.pool.get('hr.holidays.status')
for record in self.browse(cr, uid, ids):
if record.holiday_type == 'employee' and record.type == 'remove':
if record.employee_id and not record.holiday_status_id.limit:
leaves_rest = holi_status_obj.get_days( cr, uid, [record.holiday_status_id.id], record.employee_id.id, False)[record.holiday_status_id.id]['remaining_leaves']
if leaves_rest < record.number_of_days_temp:
raise osv.except_osv(_('Warning!'),_('You cannot validate leaves for employee %s: too few remaining days (%s).') % (record.employee_id.name, leaves_rest))
return True
hr_holidays()
class resource_calendar_leaves(osv.osv):
@ -478,4 +320,3 @@ class resource_calendar_leaves(osv.osv):
resource_calendar_leaves()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -56,7 +56,7 @@
<field name="type">calendar</field>
<field name="arch" type="xml">
<calendar string="Leave Request" color="name" date_start="date_from" date_stop="date_to">
<field name="holiday_status_id"/>
<field name="holiday_status_id"/>
</calendar>
</field>
</record>
@ -71,7 +71,7 @@
<group col="8" colspan="4">
<field name="name" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}" />
<field name="holiday_type" on_change="onchange_type(holiday_type)" attrs="{'readonly':[('state','!=','draft')]}" width="130" groups="base.group_hr_manager"/>
<group attrs="{'invisible':[('holiday_type','=','employee')]}">
<group attrs="{'invisible':[('holiday_type','=','employee')]}">
<field name="category_id" attrs="{'required':[('holiday_type','=','category')], 'readonly':[('state','!=','draft')]}"/>
</group>
<group attrs="{'invisible':[('holiday_type','=','category')]}">
@ -83,7 +83,7 @@
<field name="holiday_status_id" on_change="onchange_sec_id(holiday_status_id)" context="{'employee_id':employee_id}" />
<field name="department_id"/>
<field name="date_from" on_change="onchange_date_from(date_to, date_from)" required="1"/>
<field name="date_to" on_change="onchange_date_to(date_from, date_to)" required="1"/>
<field name="date_to" on_change="onchange_date_from(date_to, date_from)" required="1"/>
<field name="number_of_days_temp"/>
<newline/>
<field name="manager_id"/>
@ -93,12 +93,11 @@
<newline/>
<field name="state" colspan="2"/>
<group colspan="2" col="6">
<button string="Cancel" name="cancel" states="validate,refuse" type="workflow" icon="gtk-cancel" groups="base.group_hr_manager"/>
<button string="Refuse" name="refuse" states="confirm,validate1" type="workflow" icon="gtk-no" groups="base.group_hr_manager"/>
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" icon="gtk-no" groups="base.group_hr_manager"/>
<button string="Confirm" name="confirm" states="draft" type="workflow" icon="gtk-yes" groups="base.group_hr_user,base.group_hr_manager"/>
<button string="Approve" name="validate" states="confirm" type="workflow" icon="gtk-apply" groups="base.group_hr_manager"/>
<button string="Approved" name="second_validate" states="validate1" type="workflow" icon="gtk-apply" groups="base.group_hr_manager"/>
<button string="Set to Draft" name="set_to_draft" states="cancel" type="object" icon="gtk-convert" groups="base.group_hr_manager"/>
<button string="Set to Draft" name="set_to_draft" states="refuse" type="object" icon="gtk-convert" groups="base.group_hr_manager"/>
</group>
</page>
</notebook>
@ -136,8 +135,7 @@
<newline/>
<field name="state" colspan="2"/>
<group colspan="2" col="6">
<button string="Cancel" name="cancel" states="validate,refuse" type="workflow" icon="gtk-cancel" groups="base.group_hr_manager"/>
<button string="Refuse" name="refuse" states="confirm,validate1" type="workflow" icon="gtk-no" groups="base.group_hr_manager"/>
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" icon="gtk-no" groups="base.group_hr_manager"/>
<button string="Confirm" name="confirm" states="draft" type="workflow" icon="gtk-yes" groups="base.group_hr_user,base.group_hr_manager"/>
<button string="Approve" name="validate" states="confirm" type="workflow" icon="gtk-apply" groups="base.group_hr_manager"/>
<button string="Approved" name="second_validate" states="validate1" type="workflow" icon="gtk-apply" groups="base.group_hr_manager"/>
@ -154,7 +152,7 @@
<field name="model">hr.holidays</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="red:state in ('refuse');blue:state in (' draft');black:state in ('confirm','validate','validate1');gray:state in ('cancel') " string="Leaves" >
<tree colors="red:state in ('refuse');blue:state in ('draft');black:state in ('confirm','validate','validate1')" string="Leaves" >
<field name="employee_id"/>
<field name="department_id" invisible="1"/>
<field name="holiday_status_id"/>
@ -181,7 +179,7 @@
<field name="holiday_status_id" />
<field name="type"/>
<field name="date_from" on_change="onchange_date_from(date_to, date_from)" attrs="{'readonly':[('type','=','add')], 'required':[('type','=','remove')]}"/>
<field name="date_to" on_change="onchange_date_to(date_from, date_to)" attrs="{'readonly':[('type','=','add')], 'required':[('type','=','remove')]}"/>
<field name="date_to" on_change="onchange_date_from(date_to, date_from)" attrs="{'readonly':[('type','=','add')], 'required':[('type','=','remove')]}"/>
<field name="number_of_days_temp"/>
<notebook colspan="4">
<page string="General">
@ -190,10 +188,9 @@
<newline/>
<field name="state" colspan="2"/>
<group colspan="2">
<button string="Cancel" name="cancel" states="validate,refuse,validate1" type="workflow" icon="gtk-cancel"/>
<button string="Confirm" name="confirm" states="draft" type="workflow" icon="gtk-yes"/>
<button string="Approve" name="validate" states="confirm" type="workflow" icon="gtk-apply"/>
<button string="Refuse" name="refuse" states="confirm" type="workflow" icon="gtk-no"/>
<button string="Refuse" name="refuse" states="confirm,validate,draft" type="workflow" icon="gtk-no"/>
<button string="Set to Draft" name="set_to_draft" states="cancel" type="object" icon="gtk-convert"/>
</group>
</page>
@ -203,12 +200,12 @@
</record>
<record model="ir.ui.view" id="view_holiday_simple">
<field name="name">hr.holidays.reprot_tree</field>
<field name="name">hr.holidays.report_tree</field>
<field name="model">hr.holidays</field>
<field name="type">tree</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<tree colors="red:state in ('refuse');blue:state in (' draft');black:state in ('confirm','validate','validate1');gray:state in ('cancel')" string="Leaves Summary">
<tree colors="red:state in ('refuse');blue:state in (' draft');black:state in ('confirm','validate','validate1')" string="Leaves Summary">
<field name="employee_id"/>
<field name="department_id" invisible="1"/>
<field name="type"/>
@ -220,11 +217,9 @@
<field name="manager_id" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="state"/>
<button string="Cancel" name="cancel" states="validate,refuse,validate1" type="workflow" icon="gtk-cancel" groups="base.group_hr_manager"/>
<button string="Confirm" name="confirm" states="draft" type="workflow" icon="gtk-yes" groups="base.group_hr_user,base.group_hr_manager"/>
<button string="Approve" name="validate" states="confirm" type="workflow" icon="gtk-apply" groups="base.group_hr_manager"/>
<button string="Refuse" name="refuse" states="confirm" type="workflow" icon="gtk-no" groups="base.group_hr_manager"/>
<button string="Set to Draft" name="set_to_draft" states="cancel" type="object" icon="gtk-convert" groups="base.group_hr_manager"/>
</tree>
</field>
</record>
@ -235,7 +230,7 @@
<field name="model">hr.holidays</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="red:state in ('refuse');blue:state in (' draft');black:state in ('confirm','validate','validate1');gray:state in ('cancel')">
<tree colors="red:state in ('refuse');blue:state in (' draft');black:state in ('confirm','validate','validate1')">
<field name="employee_id"/>
<field name="department_id" invisible="not context.get('set_visible',False)"/>
<field name="holiday_status_id"/>
@ -299,7 +294,7 @@
<field name="name">Allocation Requests</field>
<field name="res_model">hr.holidays</field>
<field name="view_type">form</field>
<field name="context">{"search_default_my_leaves": 1,'type':'add',"search_default_department_id": department_id}</field>
<field name="context">{"search_default_my_leaves": 1,'default_type':'add',"search_default_department_id": department_id}</field>
<field name="domain">[('type','=','add')]</field>
<field name="view_id" ref="allocation_leave_new"/>
<field name="search_view_id" ref="view_hr_holidays_filter"/>
@ -328,6 +323,7 @@
<field name="view_mode">tree,form</field>
<field name="view_id" eval="view_holiday_simple"/>
<field name="context">{'search_default_my_leaves': 1, 'search_default_group_type': 1}</field>
<field name="domain">[('holiday_type','=','employee')]</field>
<field name="search_view_id" ref="view_hr_holidays_filter"/>
</record>
@ -347,10 +343,6 @@
<search string="Search Leave Type">
<field name="name"/>
<field name="categ_id" widget="selection"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Meeting Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}"/>
</group>
</search>
</field>
</record>
@ -366,22 +358,19 @@
<field name="color_name"/>
<field name="categ_id" widget="selection" groups="base.group_extended"/>
</group>
<notebook colspan="4">
<page string="Details">
<group name="selection" col="4" colspan="4">
<group colspan="2">
<separator string="Validation" />
<newline/>
<field name="active" />
<newline/>
<field name="double_validation"/>
<newline/>
<field name="limit"/>
</group>
<group name="second" colspan="2"/>
</group>
</page>
</notebook>
<notebook colspan="4">
<page string="Details">
<group colspan="2" col="2">
<separator string="Validation" colspan="2"/>
<field name="double_validation"/>
<field name="limit"/>
</group>
<group name="second" colspan="2" col="2">
<separator string="Misc" colspan="2"/>
<field name="active" />
</group>
</page>
</notebook>
</form>
</field>
</record>
@ -393,21 +382,22 @@
<field name="arch" type="xml">
<tree string="Leave Type">
<field name="name"/>
<field name="max_leaves"/>
<field name="leaves_taken"/>
<field name="remaining_leaves"/>
<field name="limit" />
<field name="categ_id" invisible="1"/>
</tree>
</field>
</record>
<record id="view_hr_holidays_status_search" model="ir.ui.view">
<record id="view_hr_holidays_status_search" model="ir.ui.view">
<field name="name">hr.holidays.status.search</field>
<field name="model">hr.holidays.status</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Leave Type">
<field name="name"/>
<field name="categ_id" widget="selection"/>
<field name="name"/>
<field name="categ_id" widget="selection"/>
</search>
</field>
</record>

View File

@ -43,17 +43,9 @@
<field name="wkf_id" ref="wkf_holidays" />
<field name="name">refuse</field>
<field name="kind">function</field>
<field name="action">holidays_refuse()</field>
</record>
<record model="workflow.activity" id="act_cancel">
<field name="wkf_id" ref="wkf_holidays" />
<field name="name">cancel</field>
<field name="flow_stop">True</field>
<field name="kind">stopall</field>
<field name="action">holidays_cancel()</field>
<field name="join_mode">XOR</field>
<field name="action">holidays_refuse()</field>
</record>
<!--
@ -70,7 +62,7 @@
<field name="act_from" ref="act_confirm" />
<field name="act_to" ref="act_validate" />
<field name="signal">validate</field>
<field name="condition">(holiday_status_id.double_validation == False)</field>
<field name="condition">True</field>
</record>
<record model="workflow.transition" id="t3">
@ -81,25 +73,13 @@
<record model="workflow.transition" id="t4">
<field name="act_from" ref="act_validate" />
<field name="act_to" ref="act_cancel" />
<field name="signal">cancel</field>
</record>
<record model="workflow.transition" id="t5">
<field name="act_from" ref="act_refuse" />
<field name="act_to" ref="act_cancel" />
<field name="signal">cancel</field>
</record>
<record model="workflow.transition" id="t7">
<field name="act_from" ref="act_cancel" />
<field name="act_to" ref="act_draft" />
<field name="signal">set_to_draft</field>
<field name="act_to" ref="act_refuse" />
<field name="signal">refuse</field>
</record>
<record model="workflow.transition" id="t8">
<field name="act_from" ref="act_validate1" />
<field name="act_to" ref="act_validate" />
<field name="act_from" ref="act_validate" />
<field name="act_to" ref="act_validate1" />
<field name="signal">second_validate</field>
</record>
@ -110,10 +90,10 @@
</record>
<record model="workflow.transition" id="t11">
<field name="act_from" ref="act_confirm" />
<field name="act_from" ref="act_validate" />
<field name="act_to" ref="act_validate1" />
<field name="condition">(holiday_status_id.double_validation == True)</field>
<field name="signal">validate</field>
<field name="condition">not holiday_status_id.double_validation</field>
<field name="signal" eval="False"/>
</record>
</data>

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
__name__ = "Change signs of old holiday requests"
def migrate(cr, version):
cr.execute("DELETE FROM hr_holidays WHERE number_of_days < 0")
cr.execute("UPDATE hr_holidays SET number_of_days = -number_of_days, type ='remove'")

View File

@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
__name__ = "Convert the Holidays Per User limits into positive leave request"
def migrate(cr, version):
# cr.execute("""SELECT id, employee_id, holiday_status, max_leaves, notes, create_uid
# FROM hr_holidays_per_user;""")
# for record in cr.fetchall():
# cr.execute("""INSERT INTO hr_holidays
# (employee_id, type, allocation_type, name, holiday_status_id,
# state, number_of_days, notes, manager_id) VALUES
# (%s, 'add', 'company', 'imported holiday_per_user', %s,
# 'validated', %s, %s, %s) """, (record[1],record[2],record[3],record[4],record[5]))
return {}

View File

@ -42,7 +42,6 @@
I allocate leave request for employee "Phil Graves".
-
!record {model: hr.holidays, id: hr_holidays_allocateleaveforuser0}:
allocation_type: employee
employee_id: 'hr_employee_philgraves0'
holiday_status_id: hr_holidays_status_sick0
name: Sick Leaves for Phil Graves
@ -64,7 +63,6 @@
I connect as "test_holiday_user1", and create a new leave request for employee "Phil Graves".
-
!record {model: hr.holidays, id: hr_holidays_iwanttoleaveforgotohospital0}:
allocation_type: employee
date_from: '2010-05-20 11:48:00'
date_to: '2010-05-21 11:48:00'
employee_id: 'hr_employee_philgraves0'

View File

@ -726,7 +726,7 @@
<field name="arch" type="xml">
<search string="Search Production">
<group col='9' colspan='4'>
<filter icon="terp-camera_test" string="Ready"
<filter icon="terp-camera_test" string="Ready" name="ready"
domain="[('state','=','ready')]"
help="Non confirmed manufacturing orders"/>
<filter icon="terp-check" string="Current" name="current"
@ -763,7 +763,7 @@
<field name="view_mode">tree,form,calendar,graph,gantt</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="view_mrp_production_filter"/>
<field name="context">{'search_default_current':1}</field>
<field name="context">{'search_default_ready':1}</field>
<field name="help">Manufacturing Orders are usually proposed automatically by OpenERP based on the bill of materials and the procurement rules, but you can also create manufacturing orders manually. OpenERP will handle the consumption of the raw materials (stock decrease) and the production of the finished products (stock increase) when the order is processed.</field>
</record>
<menuitem action="mrp_production_action" id="menu_mrp_production_action"

View File

@ -272,7 +272,7 @@
<menuitem id="menu_stock_sched" name="Schedulers" parent="stock.menu_stock_root" sequence="4"/>
<menuitem action="action_compute_schedulers" id="menu_stock_proc_schedulers" parent="menu_stock_sched" sequence="20" groups="stock.group_stock_manager"/>
<menuitem action="procurement_exceptions" id="menu_stock_procurement_action" parent="menu_stock_sched" sequence="50" groups="stock.group_stock_manager"/>
<menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_configuration" sequence="5" groups="base.group_extended"/>
<menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_configuration" sequence="5"/>
<menuitem action="action_orderpoint_form" id="menu_stock_order_points" parent="menu_stock_procurement" sequence="10"/>
</data>

View File

@ -9,6 +9,7 @@
parent="base.menu_purchase_root" sequence="1" />
<menuitem id="menu_purchase_config_purchase" name="Configuration"
groups="group_purchase_manager"
parent="base.menu_purchase_root" sequence="100"/>
<menuitem

View File

@ -1668,7 +1668,8 @@
<group col="8" colspan="4">
<filter icon="terp-go-today" string="Today" domain="[('date','&lt;=',time.strftime('%%Y-%%m-%%d 23:59:59')),('date','&gt;=',time.strftime('%%Y-%%m-%%d 00:00:00'))]" help="Orders planned for today"/>
<separator orientation="vertical"/>
<filter icon="terp-gtk-go-back-rtl" name="receive" string="To Do" domain="[('state','in',('confirmed','assigned'))]" help="Stock to be received"/>
<filter icon="terp-gtk-go-back-rtl" name="receive" string="To Do" domain="[('state','in',('confirmed','assigned'))]" help="Stock to be delivered (available or not)"/>
<filter icon="terp-check" name="available" string="Available" domain="[('state','in',('assigned',))]" help="Stock available to be delivered"/>
<filter icon="terp-dialog-close" name="received" string="Done" domain="[('state','=','done')]"/>
<separator orientation="vertical"/>
<field name="origin"/>