· 5 years ago · Dec 16, 2020, 08:16 AM
1import time
2
3from itertools import groupby
4from datetime import datetime, timedelta
5
6from odoo import api, fields, models, _
7from odoo.exceptions import UserError, ValidationError
8from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
9from odoo.tools.misc import formatLang
10
11import odoo.addons.decimal_precision as dp
12
13import random
14import json
15
16import hashlib, binascii
17
18
19from odoo import http
20
21
22class SbmHrAttendanceReport(models.Model):
23 _name = 'sbm.hr.attendance.report'
24 _inherit = ['mail.thread']
25 _description = "Sbm Attendance Report"
26 _rec_name = 'display_name'
27
28 @api.model
29 def _getWorkDomain(self):
30 domain = []
31 company_childs = self.env.user.partner_id.parent_id.child_ids
32 company_childs = [x.id for x in company_childs]
33
34
35 if self.env.user.has_group('sbm_hr_base.sbm_hr_groups_see_all_attendance'):
36 domain.append(('id', 'in', company_childs))
37 domain.append(('type', '=', 'site'))
38 elif self.env.user.has_group('sbm_hr_base.sbm_hr_groups_see_site_admin_attendance'):
39 domain.append(('id', '=', self.env.user.employee_ids[0].address_id.id))
40 return domain
41
42 name = fields.Integer(required=True)
43 display_name = fields.Char(store=True, compute='_compute_display_name')
44 work_address_id = fields.Many2one('res.partner', required=True, string='Work Address', domain = _getWorkDomain)
45 start_date = fields.Date(required=True)
46 end_date = fields.Date(required=True)
47 rejected = fields.Boolean(default=False)
48 lines = fields.One2many('sbm.hr.attendance.report.lines', 'report_id')
49
50 state = fields.Selection([
51 ('draft', 'Draft'),
52 ('process', 'Process'),
53 ('submited', 'Submited'),
54 ('done', 'Done'),
55 ('cancel', 'Cancel'),
56 ], string='State', copy=False, index=True, readonly=True, default='draft')
57
58 @api.model
59 def create(self, values):
60 values['name'] = self.env['ir.sequence'].next_by_code('seq.sbm.hr.attendance.report')
61 create_obj = super(SbmHrAttendanceReport, self).create(values)
62 return create_obj
63
64 @api.depends('name')
65 def _compute_display_name(self):
66 for record in self:
67 if record.name:
68 now = datetime.now()
69 year = now.strftime("%y")
70 roman = ['_','I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII']
71 year = now.strftime("%y")
72 month = roman[int(now.strftime("%m"))]
73 record.display_name = 'SBM/HR/AR/'+str(year)+'/'+str(month)+'/'+str(record.name)
74
75 def set_process(self):
76
77 office_hour = self.env['sbm.attendance.office.hour'].search([('address_id','=',self.work_address_id.id),('date','>=',self.start_date),('date','<=',self.end_date)])
78 lines = self.env['sbm.hr.attendance.report.lines']
79 to_lines = {}
80
81 for oh in office_hour:
82 to_lines['report_id'] = self.id
83 to_lines['office_hour_id'] = oh.id
84 number_ext = 1
85 for ex in oh.extra_hour_ids[:4]:
86 if ex.att_type == 'in':
87 to_lines['extra_'+ex.att_type+str(number_ext)] = ex.log_id.id
88 elif ex.att_type == 'out':
89 to_lines['extra_'+ex.att_type+str(number_ext)] = ex.log_id.id
90 number_ext = 2
91 lines.create(to_lines)
92
93 to_lines = {}
94 self.write({'state':'process'})
95
96 def set_submit(self):
97 self.write({'state':'submited'})
98
99 def set_done(self):
100 self.write({'state':'done'})
101
102 def set_cancel(self):
103 self.write({'state':'cancel'})
104
105 def export_excel(self):
106 return {
107 'type' : 'ir.actions.act_url',
108 'url': '/export_report_attendance?&id=%s'%(self.id),
109 'target': 'new',
110 }
111
112class SbmHrAttendanceReportLines(models.Model):
113 _name = 'sbm.hr.attendance.report.lines'
114 # _inherit = ['mail.thread']
115 _description = "Sbm Attendance Report Lines"
116
117 ref = fields.Char()
118 report_id = fields.Many2one('sbm.hr.attendance.report', required=True, ondelete="cascade", string="report", readonly=True)
119 office_hour_id = fields.Many2one('sbm.attendance.office.hour', required=True, string="Office Hour")
120 extra_in1 = fields.Many2one('sbm.attendance.log', string="Ext In 1")
121 extra_out1 = fields.Many2one('sbm.attendance.log', string="Ext Out 1")
122 extra_in2 = fields.Many2one('sbm.attendance.log', string="Ext In 2")
123 extra_out2 = fields.Many2one('sbm.attendance.log', string="Ext Out 2")
124
125 # related
126 employee_id = fields.Many2one('hr.employee', string="Employee", related="office_hour_id.employee_id", store=True)
127 normal_in = fields.Many2one('sbm.attendance.log', readonly=True, related="office_hour_id.normal_in", string="In")
128 normal_out = fields.Many2one('sbm.attendance.log', readonly=True, related="office_hour_id.normal_out", string="Out")
129
130
131 attend_leave_id = fields.Many2one('sbm.hr.attend.leaves', related="office_hour_id.attend_leave_id", string="att leave")
132 trip_id = fields.Many2one('sbm.trip', related="office_hour_id.trip_id", string="trip")
133 leave_id = fields.Many2one('hr.holidays', related="office_hour_id.leave_id", string="leave")
134
135 # compute
136 start_time = fields.Datetime(compute='_compute_time')
137 end_time = fields.Datetime(compute='_compute_time')
138
139 ot_ref_id1 = fields.Many2one('sbm.overtime', compute="_compute_ot_ref_id1", store=True, readonly=False, string="Overtime Referensi 1")
140 ot_ref_id2 = fields.Many2one('sbm.overtime', compute="_compute_ot_ref_id2", store=True, readonly=False, string="Overtime Referensi 2")
141
142 normal_work_hour = fields.Char(related="office_hour_id.normal_work_hour")
143 extra_work_hour1 = fields.Char(compute="_compute_ext_work_hour1", string="Ext Work Hour 1")
144 extra_work_hour2 = fields.Char(compute="_compute_ext_work_hour2", string="Ext Work Hour 2")
145
146 is_late = fields.Boolean(default=False, related="office_hour_id.is_late")
147 normal_lunch = fields.Char(related="office_hour_id.lunch")
148 total_normal_work_hour = fields.Char(related="office_hour_id.total_normal_work_hour")
149 total_extra_work_hour1 = fields.Char(compute="_compute_total_extra_work_hour1")
150 extra_fooding1 = fields.Integer(compute="_compute_extra_fooding1")
151
152 total_extra_work_hour2 = fields.Char(compute="_compute_total_extra_work_hour2")
153 ot_rest1 = fields.Integer(compute="_compute_ot_rest1")
154 ot_rest2 = fields.Integer(compute="_compute_ot_rest2")
155
156 ot1_calculate_1 = fields.Float(compute='_compute_ot1_calculate_1')
157 ot1_calculate_2 = fields.Float(compute='_compute_ot1_calculate_2')
158 ot1_calculate_3 = fields.Float(compute='_compute_ot1_calculate_3')
159 ot1_calculate_4 = fields.Float(compute='_compute_ot1_calculate_4')
160 ot1_calculate_total = fields.Float(compute='_compute_ot1_calculate_total')
161
162 related_note = fields.Text(compute='_compute_related_note')
163
164 work_order_id1 = fields.Many2one('mrp.production.group', compute='_compute_work_order_id1', store=True)
165 work_order_id2 = fields.Many2one('mrp.production.group', compute='_compute_work_order_id2', store=True)
166 meal_allowance_lunch = fields.Float(related="office_hour_id.meal_allowance")
167 off_work = fields.Boolean(related="office_hour_id.off_work")
168 unpresent = fields.Boolean(related="office_hour_id.unpresent", store=True)
169 day_name = fields.Char(related="office_hour_id.day_name")
170 attend = fields.Boolean(related="office_hour_id.attend")
171
172 work_day = fields.Integer(compute='_compute_work_day')
173
174 color = fields.Char(compute="_compute_color")
175
176 def _compute_color(self):
177
178 for record in self:
179 res = None
180 if record.off_work:
181 res = 'red'
182
183 record.color = res
184
185 def _compute_work_day(self):
186 for record in self:
187 work_time = self.env['resource.calendar.attendance'].search([
188 ('calendar_id','=',record.employee_id.calendar_id.id),
189 ('date_to','=',False),
190 ('date_from','=',False)
191 ],order='hour_from asc')
192 record.work_day = len(work_time)/2
193
194 def view_report_line(self):
195 view_id = self.env.ref('sbm_hr_base.view_sbm_attendance_report_lines_form').id
196 return {
197 'name': _('Operation Details'),
198 'type': 'ir.actions.act_window',
199 'view_type': 'form',
200 'view_mode': 'form',
201 'res_model': "sbm.hr.attendance.report.lines",
202 'views': [(view_id, 'form')],
203 'view_id': view_id,
204 'target': 'new',
205 'res_id': self.ids[0],
206 'context': self.env.context}
207
208 def clearIn(self):
209 self.office_hour_id.write({'normal_in':False})
210
211 def clearOut(self):
212 self.office_hour_id.write({'normal_out':False})
213
214 def split_hour_to_float(self, hour):
215 split_total_extra_work_hour1 = hour.split(":")
216 total_extra_work_hour1 = 0
217 if len(split_total_extra_work_hour1) > 1:
218 total_extra_work_hour1 = float(split_total_extra_work_hour1[0])+(float(split_total_extra_work_hour1[1])/60)
219 else:
220 total_extra_work_hour1 = float(split_total_extra_work_hour1[0])
221 return total_extra_work_hour1
222
223 def _compute_ot1_calculate_total(self):
224 for record in self:
225 # =(X12*1.5)+(Y12*2)+(Z12*3)+(AA12*4)
226 record.ot1_calculate_total = (record.ot1_calculate_1*1.5)+(record.ot1_calculate_2*2)+(record.ot1_calculate_3*3)+(record.ot1_calculate_4*4)
227
228 def _compute_ot1_calculate_1(self):
229 for record in self:
230 ot1_calculate_1 = 0
231
232 total_extra_work_hour = self.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2)
233
234 if record.off_work:
235 ot1_calculate_1 = 0
236 elif total_extra_work_hour >= 1:
237 ot1_calculate_1 = 1
238 else:
239 ot1_calculate_1 = total_extra_work_hour
240
241 record.ot1_calculate_1 = ot1_calculate_1
242
243 def _compute_ot1_calculate_2(self):
244 for record in self:
245 ot1_calculate_2 = 0
246 total_extra_work_hour = self.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2)
247 if record.off_work:
248 work_time = self.env['resource.calendar.attendance'].search([
249 ('calendar_id','=',record.employee_id.calendar_id.id),
250 ('date_to','=',False),
251 ('date_from','=',False)
252 ],order='hour_from asc')
253
254 if record.work_day == 5:
255 if total_extra_work_hour >= 8:
256 ot1_calculate_2 = 8
257 else:
258 ot1_calculate_2 = total_extra_work_hour
259 elif record.work_day == 6:
260 if total_extra_work_hour >= 7:
261 ot1_calculate_2 = 7
262 else:
263 ot1_calculate_2 = total_extra_work_hour
264 elif record.ot1_calculate_1:
265
266 ot1_calculate_2 = total_extra_work_hour - record.ot1_calculate_1
267
268 record.ot1_calculate_2 = ot1_calculate_2
269
270 def _compute_ot1_calculate_3(self):
271 for record in self:
272 ot1_calculate_3 = 0
273 if record.off_work and record.ot1_calculate_2:
274
275 total_extra_work_hour = self.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2)
276 if record.work_day == 5:
277 if total_extra_work_hour >= 9:
278 ot1_calculate_3 = 1
279 elif total_extra_work_hour > 8 and total_extra_work_hour < 9:
280 ot1_calculate_3 = total_extra_work_hour - 8
281
282 elif record.work_day == 6:
283 if total_extra_work_hour >= 8:
284 ot1_calculate_3 = 1
285 elif total_extra_work_hour > 7 and total_extra_work_hour < 8:
286 ot1_calculate_3 = total_extra_work_hour - 7
287 record.ot1_calculate_3 = ot1_calculate_3
288
289 def _compute_ot1_calculate_4(self):
290 for record in self:
291 ot1_calculate_4 = 0
292 if record.off_work and record.ot1_calculate_2 and record.ot1_calculate_3:
293 total_extra_work_hour = self.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2)
294 ot1_calculate_4_temp = total_extra_work_hour - (record.ot1_calculate_2+record.ot1_calculate_3)
295 if ot1_calculate_4_temp > 0:
296 ot1_calculate_4 = ot1_calculate_4_temp
297 record.ot1_calculate_4 = ot1_calculate_4
298
299 @api.depends('total_extra_work_hour1')
300 def _compute_extra_fooding1(self):
301 for record in self:
302 res = 0
303
304 if record.employee_id.level_id and record.employee_id.address_id:
305 site_meal = self.env['sbm.site.meal'].search([('work_address_id','=',record.employee_id.address_id.id),('job_level_id', '=', record.employee_id.level_id.id),('active','=',True), ('state','=','done')],limit=1)
306 if site_meal:
307 total_extra_work_hour1 = self.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2)
308 meal = int(total_extra_work_hour1/4)
309
310 res = meal * site_meal.extra_fooding
311
312 record.extra_fooding1 = res
313 # def _compute_total_fooding(self):
314 # for record in self:
315 # record.total_fooding = record.extra_fooding1 + record.meal_allowance_lunch
316
317 @api.depends('ot_rest1','extra_work_hour1', 'extra_in1')
318 def _compute_total_extra_work_hour1(self):
319 for record in self:
320 res = 0
321 if record.extra_in1 and record.extra_work_hour1 and not record.extra_work_hour1 == "0":
322 extra_work_hour1 = datetime.strptime(record.extra_work_hour1, "%H:%M")
323 ot_rest1 = record.ot_rest1
324
325 res = (extra_work_hour1 + timedelta(hours=-ot_rest1)).time().strftime("%H:%M")
326
327 record.total_extra_work_hour1 = res
328 @api.depends('ot_rest2','extra_work_hour2', 'extra_in2')
329 def _compute_total_extra_work_hour2(self):
330 for record in self:
331 res = 0
332 if record.extra_in2 and record.extra_work_hour2 and not record.extra_work_hour2 == "0":
333 extra_work_hour2 = datetime.strptime(record.extra_work_hour2, "%H:%M")
334 ot_rest2 = record.ot_rest2
335
336 res = (extra_work_hour2 + timedelta(hours=-ot_rest2)).time().strftime("%H:%M")
337 record.total_extra_work_hour2 = res
338
339 @api.depends('extra_work_hour1','extra_in1', 'extra_out1')
340 def _compute_ot_rest1(self):
341 for record in self:
342 res = 0
343 if record.extra_work_hour1 and not record.extra_work_hour1 == '0' :
344 if record.ot_ref_id1.category != 'no rest':
345 rest = self.env['ir.config_parameter'].search([('key','=','hr.rest')],limit=1)
346
347 rest = json.loads(str(rest.value))
348 extra_in1 = (datetime.strptime(record.extra_in1.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7))
349 extra_out1 = (datetime.strptime(record.extra_out1.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7))
350
351 diff_date = extra_in1.date() - extra_out1.date()
352
353 extra_in1_hour = int(extra_in1.strftime('%H') )
354 extra_out1_hour = int(extra_out1.strftime('%H') )
355
356 if diff_date:
357 extra_out1_hour = extra_out1_hour + 24
358
359 for r in rest:
360 if r >= extra_in1_hour and r <= extra_out1_hour:
361 res = res + 1
362
363 record.ot_rest1 = res
364
365
366
367 @api.depends('extra_work_hour2','extra_in2', 'extra_out2')
368 def _compute_ot_rest2(self):
369 for record in self:
370 res = 0
371 if record.extra_work_hour2 and not record.extra_work_hour2 == '0' :
372 if record.ot_ref_id2.category != 'no rest':
373 rest = self.env['ir.config_parameter'].search([('key','=','hr.rest')],limit=1)
374
375 rest = json.loads(str(rest.value))
376 extra_in2 = (datetime.strptime(record.extra_in2.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7))
377 extra_out2 = (datetime.strptime(record.extra_out2.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7))
378
379 diff_date = extra_in2.date() - extra_out2.date()
380
381 extra_in2_hour = int(extra_in2.strftime('%H') )
382 extra_out2_hour = int(extra_out2.strftime('%H') )
383
384 if diff_date:
385 extra_out2_hour = extra_out2_hour + 24
386
387 for r in rest:
388 if r >= extra_in2_hour and r <= extra_out2_hour:
389 res = res + 1
390
391 record.ot_rest2 = res
392
393
394
395 @api.depends('ot_ref_id1')
396 def _compute_work_order_id1(self):
397 for record in self:
398 if record.ot_ref_id1:
399 record.work_order_id1 = record.ot_ref_id1.manufacture_order_id
400
401 @api.depends('ot_ref_id2')
402 def _compute_work_order_id2(self):
403 for record in self:
404 if record.ot_ref_id2:
405 record.work_order_id2 = record.ot_ref_id2.manufacture_order_id
406
407
408 @api.depends('extra_in1')
409 def _compute_ot_ref_id1(self):
410 for record in self:
411 if record.extra_in1:
412 extra_hour = self.env['sbm.attendance.extra_hour'].search([('office_hour_id','=',record.office_hour_id.id),('log_id','=',record.extra_in1.id)], limit=1)
413 if extra_hour:
414 record.ot_ref_id1 = extra_hour.hr_overtime_id.id
415 else:
416 record.ot_ref_id1 = record.ot_ref_id1
417
418 @api.depends('extra_in2')
419 def _compute_ot_ref_id2(self):
420 for record in self:
421 if record.extra_in2:
422 extra_hour = self.env['sbm.attendance.extra_hour'].search([('office_hour_id','=',record.office_hour_id.id),('log_id','=',record.extra_in2.id)], limit=1)
423 if extra_hour:
424 record.ot_ref_id2 = extra_hour.hr_overtime_id.id
425 else:
426 record.ot_ref_id2 = record.ot_ref_id2
427
428
429
430 @api.depends('extra_in1', 'extra_out1')
431 def _compute_ext_work_hour1(self):
432 for record in self:
433 res = "0"
434 if record.extra_in1 and record.extra_out1:
435 res = datetime.strptime(record.extra_out1.log_time, "%Y-%m-%d %H:%M:%S") - datetime.strptime(record.extra_in1.log_time, "%Y-%m-%d %H:%M:%S")
436 minute = int(datetime.strptime(str(res), "%H:%M:%S").strftime('%M'))
437 floating = self.env['ir.config_parameter'].search([('key','=','hr.police.ot.floating')],limit=1)
438
439 floating = json.loads(str(floating.value))
440
441 for f in floating:
442 if minute >= f['start'] and minute <= f['end']:
443
444 Hour = int(datetime.strptime(str(res), "%H:%M:%S").strftime('%H'))
445 if f['result'] >= 60 :
446 Hour = Hour+1
447 f['result'] = 0
448 res = str(Hour)+':'+str(f['result'])
449 break
450
451 record.extra_work_hour1 = res
452
453 @api.depends('extra_in2', 'extra_out2')
454 def _compute_ext_work_hour2(self):
455 for record in self:
456 res = "0"
457 if record.extra_in2 and record.extra_out2:
458 res = datetime.strptime(record.extra_out2.log_time, "%Y-%m-%d %H:%M:%S") - datetime.strptime(record.extra_in2.log_time, "%Y-%m-%d %H:%M:%S")
459 minute = int(datetime.strptime(str(res), "%H:%M:%S").strftime('%M'))
460 floating = self.env['ir.config_parameter'].search([('key','=','hr.police.ot.floating')],limit=1)
461
462 floating = json.loads(str(floating.value))
463
464 for f in floating:
465 if minute >= f['start'] and minute <= f['end']:
466
467 Hour = int(datetime.strptime(str(res), "%H:%M:%S").strftime('%H'))
468 if f['result'] >= 60 :
469 Hour = Hour+1
470 f['result'] = 0
471 res = str(Hour)+':'+str(f['result'])
472 break
473
474 record.extra_work_hour2 = res
475
476 def _compute_time(self):
477 for record in self:
478 date = record.office_hour_id.date
479 date_time = datetime.strptime(date+" 17:00:01", "%Y-%m-%d %H:%M:%S")
480 start_time =( date_time + timedelta(days=-1)).strftime("%Y-%m-%d %H:%M:%S")
481 end_time = (date_time + timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
482
483 record.start_time = start_time
484 record.end_time = end_time
485
486
487 def filter_extra(self, extra, report):
488 res = self.search(
489 [ "|",'|','|','|','|',
490 ('extra_in1','=',extra),
491 ('extra_in2','=',extra),
492 ('extra_out1','=',extra),
493 ('extra_out2','=',extra),
494 ('normal_in','=',extra),
495 ('normal_out','=',extra),
496 # ('report_id','=',report)
497 ]
498 )
499 # cek lg nanti
500
501 if not res:
502 res = False
503
504 return res
505
506
507 @api.multi
508 @api.onchange('extra_in1')
509 def _onchange_extra_in1(self):
510
511 if self.extra_in1:
512 data = self.filter_extra(self.extra_in1.id, self.report_id.id)
513
514 if data:
515 self.extra_in1 = False
516 return {'warning': {
517 'title': _('Warning'),
518 'message': _('absen ini sudah di pakai !')
519 }
520 }
521 date = datetime.strptime(self.extra_in1.log_time, "%Y-%m-%d %H:%M:%S")
522 overtime = self.env['sbm.overtime'].search([('employee_ids','in',self.extra_in1.employee_id.id), ('state','in',['approved']), ('date','=',date)])
523
524 if not overtime:
525
526 self.extra_in1 = False
527 return {'warning': {
528 'title': _('Warning'),
529 'message': _('Tanggal ini tidak ada di overtime !')
530 }
531 }
532
533 self.ot_ref_id1 = overtime
534 return {}
535
536
537
538
539
540 @api.multi
541 @api.onchange('extra_in2')
542 def _onchange_extra_in2(self):
543
544
545 if self.extra_in2:
546 if self.extra_in1:
547 self.extra_in2 = False
548 return {'warning': {
549 'title': _('Warning'),
550 'message': _('extra_in1 harus di isi!')
551 }
552 }
553
554 data = self.filter_extra(self.extra_in2.id, self.report_id.id)
555 if data:
556 self.extra_in2 = False
557 return {'warning': {
558 'title': _('Warning'),
559 'message': _('absen ini sudah di pakai !')
560 }
561 }
562
563 date = datetime.strptime(self.extra_in2.log_time, "%Y-%m-%d %H:%M:%S")
564 overtime = self.env['sbm.overtime'].search([('employee_ids','in',self.extra_in2.employee_id.id), ('state','=','approved'), ('date','=',date)])
565
566 if not overtime:
567 self.extra_in2 = False
568 return {'warning': {
569 'title': _('Warning'),
570 'message': _('Tanggal ini tidak ada di overtime !')
571 }
572 }
573 return {}
574
575 @api.multi
576 @api.onchange('extra_out1')
577 def _onchange_extra_out1(self):
578
579
580 if self.extra_out1:
581 data = self.filter_extra(self.extra_out1.id, self.report_id.id)
582 if data:
583 self.extra_out1 = False
584 return {'warning': {
585 'title': _('Warning'),
586 'message': _('absen ini sudah di pakai !')
587 }
588 }
589 return {}
590
591 @api.multi
592 @api.onchange('extra_out2')
593 def _onchange_extra_out2(self):
594
595
596 if self.extra_out2:
597 data = self.filter_extra(self.extra_out2.id, self.report_id.id)
598 if data:
599 self.extra_out2 = False
600 return {'warning': {
601 'title': _('Warning'),
602 'message': _('absen ini sudah di pakai !')
603 }
604 }
605 return {}
606
607
608 @api.multi
609 def write(self, values):
610 extra_in1 = values.get('extra_in1', False)
611 extra_in2 = values.get('extra_in2', False)
612 extra_out1 = values.get('extra_out1', False)
613 extra_out2 = values.get('extra_out2', False)
614 report_id = values.get('report_id', False)
615
616
617 if extra_in1:
618
619 data = self.filter_extra(extra_in1, report_id)
620 if data:
621 log = self.env['sbm.attendance.log'].search([('id','=',extra_in1)], limit=1)
622 logtime = (datetime.strptime(log.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7)).strftime("%Y-%m-%d %H:%M:%S")
623 raise ValidationError(_('Warning !\n '+logtime+' Duplicate Data'))
624
625 result = super(SbmHrAttendanceReportLines, self).write(values)
626
627 return result
628
629
630 @api.depends('attend_leave_id', 'trip_id', 'leave_id')
631 def _compute_related_note(self):
632 for record in self:
633 res = ''
634
635 if record.attend_leave_id:
636 res = res + 'Have Attend Leave '+record.attend_leave_id.display_name+' Actual Out '+record.attend_leave_id.actual_out+'\n'
637
638 if record.trip_id:
639 for tr in record.trip_id.partner_ids:
640 res = res + 'Have Trip '+record.trip_id.display_name+' To Customer '+ tr.name+'\n'
641
642 if record.leave_id:
643 res = res + 'Have Leave '+record.leave_id.display_name+'\n'
644
645 if record.work_order_id1:
646 if record.work_order_id1.work_location == "customer-site":
647 work_location = " Work Location "+record.work_order_id1.work_location+" "+record.work_order_id1.work_location
648 elif record.work_order_id1.work_location == "warehous":
649 work_location = " Work Location "+record.work_order_id1.work_location+" "+record.work_order_id1.wh_id.name
650 res = res + 'Have work_order_id1 '+record.work_order_id1.name+work_location+'\n'
651
652 if record.work_order_id2:
653 if record.work_order_id2.work_location == "customer-site":
654 work_location = " Work Location "+record.work_order_id2.work_location+" "+record.work_order_id2.work_location
655 elif record.work_order_id2.work_location == "warehous":
656 work_location = " Work Location "+record.work_order_id2.work_location+" "+record.work_order_id2.wh_id.name
657 res = res + 'Have work_order_id2 '+record.work_order_id2.name+work_location+'\n'
658
659 record.related_note = res
660
661import base64
662from odoo.addons.web.controllers.main import serialize_exception,content_disposition
663import xlwt
664import xlsxwriter
665from io import BytesIO
666import StringIO
667class ExportReportAttendanceHttp(http.Controller):
668
669 # @http.route('/export_report_attendance/', type='http', auth="public")
670 # def export_report_attendance(self, id, **kw):
671
672 # data = http.request.env['sbm.hr.attendance.report'].sudo().search([('id', '=', id)], limit=1) # search data attendance report berdasarkan id
673
674 # workbook = xlwt.Workbook() # create WorkBook
675 # worksheet = workbook.add_sheet('Report Absen') # Menambahkan Sheet Pertama
676
677 # style = xlwt.easyxf("align: horiz center")
678
679 # # font
680 # font = xlwt.Font()
681 # font.bold = True
682
683 # style.font = font
684
685 # # borders
686 # borders = xlwt.Borders()
687 # borders.bottom = 6
688 # borders.top = xlwt.Borders.THIN
689 # borders.left = 6
690 # borders.right = 2
691 # style.borders = borders
692
693 # row = 0 # di mulai dari baris 0
694 # col = 0 # di mulai dari kolom 0
695
696 # # mengumpulkan nama kolom menjadi list
697 # column = [
698 # 'Koreksi',
699 # 'No. PO/SPK',
700 # 'Nilai PO/SPK',
701 # 'Site',
702 # 'Nama',
703 # 'Jabatan',
704 # 'Date',
705 # # 'Month',
706 # # 'Year',
707 # 'Hari',
708 # 'Normal In',
709 # # 'in_minute',
710 # 'Normal Out',
711 # # 'out_minute',
712 # 'Perusahaan',
713 # 'Lokasi',
714 # 'Ist',
715 # 'Kerja',
716 # '5HK',
717 # 'Ke 3',
718 # 'In',
719 # 'Out',
720 # 'OT',
721 # 'I*',
722 # 'II',
723 # 'III',
724 # 'IV',
725 # 'TUL Jam',
726 # 'Actual',
727 # 'H',
728 # 'OT',
729 # 'S',
730 # 'I',
731 # 'C',
732 # 'A',
733 # 'D',
734 # 'Lk',
735 # 'Penempatan',
736 # 'Project',
737 # 'TA',
738 # 'Tlat',
739 # 'Pjs',
740 # 'UG',
741 # 'Special Site',
742 # 'Parhari',
743 # 'U.OT',
744 # 'U TLK Penempatan',
745 # 'Proyek',
746 # 'Telat',
747 # 'Pjs',
748 # 'U UG',
749 # 'UG Special',
750 # 'U.Mkn',
751 # 'Dibayar',
752 # 'Ket',
753 # 'HK',
754 # 'Hr Kalender',
755 # 'R UM',
756 # 'Note',
757 # 'U TLK Penempatan',
758 # 'Proyek',
759 # 'Pjs',
760 # 'R UG',
761 # 'U Special Site'
762 # ]
763 # # 256 * Jumlah_karakter
764 # worksheet.col(column.index('Nama')).width = 256 * 50 # mengatur lebar kolom nama
765 # worksheet.col(column.index('Site')).width = 256 * 50 # mengatur lebar kolom Site
766 # worksheet.col(column.index('Date')).width = 256 * 25 # mengatur lebar kolom Tanggal
767 # worksheet.col(column.index('Normal In')).width = 256 * 25 # mengatur lebar kolom Normal In
768 # worksheet.col(column.index('Normal Out')).width = 256 * 25 # mengatur lebar kolom Normal Out
769 # worksheet.col(column.index('In')).width = 256 * 25 # mengatur lebar kolom In
770 # worksheet.col(column.index('Out')).width = 256 * 25 # mengatur lebar kolom Out
771 # worksheet.col(column.index('Koreksi')).width = 256 * 25 # mengatur lebar kolom Koreksi
772 # worksheet.col(column.index('No. PO/SPK')).width = 256 * 25 # mengatur lebar kolom No. PO/SPK
773 # worksheet.col(column.index('Nilai PO/SPK')).width = 256 * 25 # mengatur lebar kolom Nilai PO/SPK
774 # worksheet.col(column.index('Jabatan')).width = 256 * 50 # mengatur lebar kolom Jabatan
775 # worksheet.col(column.index('Perusahaan')).width = 256 * 50 # mengatur lebar kolom Perusahaan
776 # worksheet.col(column.index('Lokasi')).width = 256 * 50 # mengatur lebar kolom Lokasi
777 # worksheet.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
778 # worksheet.col(column.index('Special Site')).width = 256 * 50 # mengatur lebar kolom Special Site
779 # worksheet.col(column.index('U TLK Penempatan')).width = 256 * 50 # mengatur lebar kolom U TLK Penempatan
780 # worksheet.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
781 # worksheet.col(column.index('UG Special')).width = 256 * 50 # mengatur lebar kolom UG Special
782
783 # for col_d in column: #looping list kolom
784 # worksheet.write(row, col, col_d, style=style) # menulis nama kolom di work sheet 1
785 # col+=1 # tambah kolom
786
787 # summary = {} # dictionary untuk merata ratakan field yang di butuhkan
788 # row+=1 # baris tambah 1
789 # data_style = xlwt.easyxf("align: horiz center")
790 # for record in data.lines: # looping report line
791
792 # employee = summary.get(record.employee_id.name) # mencari key nama karyawan di dictionary rata rata
793 # if not employee: # jika tidak ada
794 # summary[record.employee_id.name] = {} # buat dictionary dengan key nama karyawan value dictionary
795 # summary[record.employee_id.name]['OT'] = 0 # bikin Key OT
796 # summary[record.employee_id.name]['I*'] = 0 # bikin Key I*
797 # summary[record.employee_id.name]['II'] = 0 # bikin Key II
798 # summary[record.employee_id.name]['III'] = 0 # bikin Key III
799 # summary[record.employee_id.name]['IV'] = 0 # bikin Key IV
800 # summary[record.employee_id.name]['TUL Jam'] = 0 # bikin key Tul Jam
801 # summary[record.employee_id.name]['U.Mkn'] = 0 # bikin key U.Mkn
802 # worksheet.write(row, column.index('Site'), record.employee_id.address_id.name) # Menulis Site di sheet 1
803 # worksheet.write(row, column.index('Nama'), record.employee_id.name) # Menulis nama karyawan di sheet 1
804
805 # if record.employee_id.job_id:
806 # worksheet.write(row, column.index('Jabatan'), record.employee_id.job_id.name) # Menulis Jabatan di sheet 1
807
808 # worksheet.write(row, column.index('Date'), record.office_hour_id.date, data_style) # Menulis tanggal di sheet 1
809 # worksheet.write(row, column.index('Hari'), record.day_name, data_style) # Menulis Hari di sheet 1
810 # if record.normal_in: # cek ada normal in
811 # normal_in = (datetime.strptime(record.normal_in.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7)).strftime("%Y-%m-%d %H:%M:%S") # convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
812 # worksheet.write(row, column.index('Normal In'), normal_in, data_style) # Menulis Normal In di sheet 1
813 # worksheet.write(row, column.index('In'), normal_in, data_style) # Menulis In di sheet 1
814 # if record.normal_out: # cek ada normal out
815 # normal_out = (datetime.strptime(record.normal_out.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7)).strftime("%Y-%m-%d %H:%M:%S")# convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
816 # worksheet.write(row, column.index('Out'), normal_out, data_style) # Menulis Normal Out di sheet 1
817 # worksheet.write(row, column.index('Normal Out'), normal_out, data_style) # Menulis Normal Out di sheet 1
818
819 # worksheet.write(row, column.index('Ist'), record.normal_lunch, data_style) # Menulis Normal Ist di sheet 1
820 # if record.total_normal_work_hour:# cek total normal work hour
821 # worksheet.write(row, column.index('Kerja'), record.total_normal_work_hour, data_style) # Menulis Kerja di sheet 1
822 # OT = record.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2) # menjumlahkan untuk OT total
823 # worksheet.write(row, column.index('OT'), OT, data_style) # Menulis OT di sheet 1
824
825 # worksheet.write(row, column.index('I*'), record.ot1_calculate_1, data_style) # Menulis I* di sheet 1
826 # worksheet.write(row, column.index('II'), record.ot1_calculate_2, data_style) # Menulis II di sheet 1
827 # worksheet.write(row, column.index('III'), record.ot1_calculate_3, data_style) # Menulis III di sheet 1
828 # worksheet.write(row, column.index('IV'), record.ot1_calculate_4, data_style) # Menulis IV di sheet 1
829 # worksheet.write(row, column.index('TUL Jam'), record.ot1_calculate_total, data_style) # Menulis TUL Jam di sheet 1
830 # worksheet.write(row, column.index('U.Mkn'), record.meal_allowance_lunch, data_style) # Menulis U.Mkn di sheet 1
831
832 # summary[record.employee_id.name]['OT'] = summary[record.employee_id.name]['OT'] + OT # menjumlahkan Total OT per employee
833 # summary[record.employee_id.name]['I*'] = summary[record.employee_id.name]['I*'] + record.ot1_calculate_1 # menjumlahkan Total I* per employee
834 # summary[record.employee_id.name]['II'] = summary[record.employee_id.name]['II'] + record.ot1_calculate_2 # menjumlahkan Total II per employee
835 # summary[record.employee_id.name]['III'] = summary[record.employee_id.name]['III'] + record.ot1_calculate_3 # menjumlahkan Total III per employee
836 # summary[record.employee_id.name]['IV'] = summary[record.employee_id.name]['IV'] + record.ot1_calculate_4 # menjumlahkan Total IV per employee
837 # summary[record.employee_id.name]['TUL Jam'] = summary[record.employee_id.name]['TUL Jam'] + record.ot1_calculate_total # menjumlahkan Total Tul Jam per employee
838 # summary[record.employee_id.name]['U.Mkn'] = summary[record.employee_id.name]['U.Mkn'] + record.meal_allowance_lunch # menjumlahkan Total U.Mkn per employee
839
840 # if record.unpresent: # cek kehadiran
841 # worksheet.write(row, column.index('A'), 1, data_style) # tulis alpha 1 di sheet 1
842
843 # row+=1 # baris bertambah berdasarkan looping
844
845 # worksheet2 = workbook.add_sheet('Summary Absen') # membuat sheet 2
846
847 # row = 0 # baris kembali ke 0
848 # col = 0 # kolom kembali ke 0
849 # for col_d in column: # looping kolom
850 # worksheet2.write(row, col, col_d) # create nama kolom
851 # col+=1 # kolom bertambah 1
852
853 # row+=1 # baris tambah 1
854 # for val in sorted(summary.items()): # looping hasil penjumlahan di dict summary dan di sortir key nya
855 # worksheet2.write(row, column.index('Nama'), val[0])
856 # worksheet2.write(row, column.index('OT'), val[1]['OT'])
857
858 # worksheet2.write(row, column.index('I*'), val[1]['I*'])
859 # worksheet2.write(row, column.index('II'), val[1]['II'])
860 # worksheet2.write(row, column.index('III'), val[1]['III'])
861 # worksheet2.write(row, column.index('IV'), val[1]['IV'])
862 # worksheet2.write(row, column.index('TUL Jam'), val[1]['TUL Jam'])
863 # worksheet2.write(row, column.index('U.Mkn'), val[1]['U.Mkn'])
864 # row+=1
865
866 # output = StringIO.StringIO()
867 # workbook.save(output)
868 # filecontent = output.getvalue()
869 # return http.request.make_response(filecontent,
870 # [('Content-Type', 'application/octet-stream'),
871 # ('Content-Disposition', content_disposition(data.display_name+'.xls'))])
872
873
874 # @http.route('/export_report_attendance/', type='http', auth="public")
875 # def export_report_attendance(self, id, **kw):
876 # data = http.request.env['sbm.hr.attendance.report'].sudo().search([('id', '=', id)], limit=1) # search data attendance report berdasarkan id
877 # output = StringIO.StringIO()
878 # column = [
879 # 'Koreksi',
880 # 'No. PO/SPK',
881 # 'Nilai PO/SPK',
882 # 'Site',
883 # 'Nama',
884 # 'Jabatan',
885 # 'Date',
886 # # 'Month',
887 # # 'Year',
888 # 'Hari',
889 # 'Normal In',
890 # # 'in_minute',
891 # 'Normal Out',
892 # # 'out_minute',
893 # 'Perusahaan',
894 # 'Lokasi',
895 # 'Ist',
896 # 'Kerja',
897 # '5HK',
898 # 'Ke 3',
899 # 'In',
900 # 'Out',
901 # 'OT',
902 # 'I*',
903 # 'II',
904 # 'III',
905 # 'IV',
906 # 'TUL Jam',
907 # 'Actual',
908 # 'H',
909 # 'OT',
910 # 'S',
911 # 'I',
912 # 'C',
913 # 'A',
914 # 'D',
915 # 'Lk',
916 # 'Penempatan',
917 # 'Project',
918 # 'TA',
919 # 'Tlat',
920 # 'Pjs',
921 # 'UG',
922 # 'Special Site',
923 # 'Parhari',
924 # 'U.OT',
925 # 'U TLK Penempatan',
926 # 'Proyek',
927 # 'Telat',
928 # 'Pjs',
929 # 'U UG',
930 # 'UG Special',
931 # 'U.Mkn',
932 # 'Dibayar',
933 # 'Ket',
934 # 'HK',
935 # 'Hr Kalender',
936 # 'R UM',
937 # 'Note',
938 # 'U TLK Penempatan',
939 # 'Proyek',
940 # 'Pjs',
941 # 'R UG',
942 # 'U Special Site'
943 # ]
944 # column_dict = [{'header':x} for x in column]
945 # workbook = xlsxwriter.Workbook(output)
946 # worksheet = workbook.add_worksheet("a")
947 # print len(column_dict),"<<<<<<<<<<<"
948
949 # worksheet.add_table('A1:BZ10',{'data': [],
950 # 'columns': column_dict})
951 # # worksheet.write('A1', 'Hello')
952 # workbook.close()
953 # filecontent = output.getvalue()
954
955 # return http.request.make_response(filecontent,
956 # [('Content-Type', 'application/octet-stream'),
957 # ('Content-Disposition', content_disposition(data.display_name+'.xls'))])
958
959
960 def report_absen_sheet(self, workbook, data):
961 worksheet = workbook.add_sheet('Report Absen') # Menambahkan Sheet Pertama
962 # H = 1
963 # V = 3
964 # HF = H + 3
965 # VF = V + 3
966 # worksheet.panes_frozen = True
967 # worksheet.horz_split_pos = H
968 # worksheet.vert_split_pos = V
969 # worksheet.horz_split_first_visible = HF
970 # worksheet.vert_split_first_visible = VF
971 style = xlwt.easyxf("align: horiz center")
972 leave_category = http.request.env['hr.holidays.status'].sudo().daftar_category
973 # font
974 font = xlwt.Font()
975 font.bold = True
976
977 style.font = font
978
979 # borders
980 borders = xlwt.Borders()
981 borders.bottom = 6
982 borders.top = xlwt.Borders.THIN
983 borders.left = 6
984 borders.right = 2
985 style.borders = borders
986
987 row = 0 # di mulai dari baris 0
988 col = 0 # di mulai dari kolom 0
989
990 # mengumpulkan nama kolom menjadi list
991 column = [
992 'Koreksi',
993 'No. PO/SPK',
994 'Nilai PO/SPK',
995 'Site',
996 'Nama',
997 'Jabatan',
998 'Date',
999 # 'Month',
1000 # 'Year',
1001 'Hari',
1002 'Normal In',
1003 # 'in_minute',
1004 'Normal Out',
1005 # 'out_minute',
1006 'Perusahaan',
1007 'Lokasi',
1008 'Ist',
1009 'Kerja',
1010 '5HK',
1011 'Ke 3',
1012 'In',
1013 'Out',
1014 'OT',
1015 'I*',
1016 'II',
1017 'III',
1018 'IV',
1019 'TUL Jam',
1020 'Actual',
1021 'H',
1022 'OT',
1023 'A'
1024 ]
1025
1026 for lc in leave_category:
1027 column.append(lc[0][0])
1028
1029 column = column + [
1030 'Lk',
1031 'Penempatan',
1032 'Project',
1033 'TA',
1034 'Tlat',
1035 'Pjs',
1036 'UG',
1037 'Special Site',
1038 'Parhari',
1039 'U.OT',
1040 'U TLK Penempatan',
1041 'Proyek',
1042 'Telat',
1043 'Pjs',
1044 'U UG',
1045 'UG Special',
1046 'U.Mkn',
1047 'Dibayar',
1048 'Ket',
1049 'HK',
1050 'Hr Kalender',
1051 'R UM',
1052 'Note',
1053 'U TLK Penempatan',
1054 'Proyek',
1055 'Pjs',
1056 'R UG',
1057 'U Special Site'
1058 ]
1059 # 256 * Jumlah_karakter
1060 worksheet.col(column.index('Nama')).width = 256 * 50 # mengatur lebar kolom nama
1061 worksheet.col(column.index('Site')).width = 256 * 50 # mengatur lebar kolom Site
1062 worksheet.col(column.index('Date')).width = 256 * 25 # mengatur lebar kolom Tanggal
1063 # worksheet.col(column.index('Normal In')).width = 256 * 25 # mengatur lebar kolom Normal In
1064 # worksheet.col(column.index('Normal Out')).width = 256 * 25 # mengatur lebar kolom Normal Out
1065 # worksheet.col(column.index('In')).width = 256 * 25 # mengatur lebar kolom In
1066 # worksheet.col(column.index('Out')).width = 256 * 25 # mengatur lebar kolom Out
1067 # worksheet.col(column.index('Koreksi')).width = 256 * 25 # mengatur lebar kolom Koreksi
1068 # worksheet.col(column.index('No. PO/SPK')).width = 256 * 25 # mengatur lebar kolom No. PO/SPK
1069 # worksheet.col(column.index('Nilai PO/SPK')).width = 256 * 25 # mengatur lebar kolom Nilai PO/SPK
1070 # worksheet.col(column.index('Jabatan')).width = 256 * 50 # mengatur lebar kolom Jabatan
1071 worksheet.col(column.index('Perusahaan')).width = 256 * 50 # mengatur lebar kolom Perusahaan
1072 # worksheet.col(column.index('Lokasi')).width = 256 * 50 # mengatur lebar kolom Lokasi
1073 # worksheet.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
1074 # worksheet.col(column.index('Special Site')).width = 256 * 50 # mengatur lebar kolom Special Site
1075 # worksheet.col(column.index('U TLK Penempatan')).width = 256 * 50 # mengatur lebar kolom U TLK Penempatan
1076 # worksheet.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
1077 # worksheet.col(column.index('UG Special')).width = 256 * 50 # mengatur lebar kolom UG Special
1078
1079
1080 for col_d in column: #looping list kolom
1081 worksheet.write(row, col, col_d, style=style) # menulis nama kolom di work sheet 1
1082 col+=1 # tambah kolom
1083
1084 summary = {} # dictionary untuk merata ratakan field yang di butuhkan
1085 row+=1 # baris tambah 1
1086 data_style = xlwt.easyxf("align: horiz center")
1087
1088 number_style = data_style
1089 number_style.num_format_str = '#,##0'
1090
1091 for record in data.lines: # looping report line
1092
1093 employee = summary.get(record.employee_id.name) # mencari key nama karyawan di dictionary rata rata
1094 if not employee: # jika tidak ada
1095 summary[record.employee_id.name] = {} # buat dictionary dengan key nama karyawan value dictionary
1096 summary[record.employee_id.name]['OT'] = 0 # bikin Key OT
1097 summary[record.employee_id.name]['I*'] = 0 # bikin Key I*
1098 summary[record.employee_id.name]['II'] = 0 # bikin Key II
1099 summary[record.employee_id.name]['III'] = 0 # bikin Key III
1100 summary[record.employee_id.name]['IV'] = 0 # bikin Key IV
1101 summary[record.employee_id.name]['TUL Jam'] = 0 # bikin key Tul Jam
1102 summary[record.employee_id.name]['U.Mkn'] = 0 # bikin key U.Mkn
1103 summary[record.employee_id.name]['Actual'] = "00:00" #
1104 summary[record.employee_id.name]['H'] = 0 #
1105 summary[record.employee_id.name]['A'] = 0 #
1106 summary[record.employee_id.name]['TA'] = 0 #
1107 summary[record.employee_id.name]['Tlat'] = 0 #
1108 summary[record.employee_id.name]['Telat'] = 0 #
1109 summary[record.employee_id.name]['Parhari'] = 0 #
1110 summary[record.employee_id.name]['extra_fooding'] = 0 #
1111 summary[record.employee_id.name]['Trip'] = 0 #
1112 summary[record.employee_id.name]['attend'] = 0
1113 summary[record.employee_id.name]['Keterangan'] = ""
1114
1115 for lc in leave_category:
1116 summary[record.employee_id.name][lc[0][0]] = 0
1117
1118
1119 summary[record.employee_id.name]['Site'] = record.employee_id.address_id.name
1120 worksheet.write(row, column.index('Site'), record.employee_id.address_id.name) # Menulis Site di sheet 1
1121 worksheet.write(row, column.index('Nama'), record.employee_id.name) # Menulis nama karyawan di sheet 1
1122
1123 if record.employee_id.job_id:
1124 summary[record.employee_id.name]['Jabatan'] = record.employee_id.job_id.position_id.name
1125 worksheet.write(row, column.index('Jabatan'), record.employee_id.job_id.position_id.name) # Menulis Jabatan di sheet 1
1126 else:
1127 summary[record.employee_id.name]['Jabatan'] = ""
1128 number_date = (datetime.strptime(record.office_hour_id.date, "%Y-%m-%d") + timedelta(hours=7)).strftime("%d") # convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
1129 date_att = (datetime.strptime(record.office_hour_id.date, "%Y-%m-%d") + timedelta(hours=7)).strftime("%d %b %Y") # convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
1130 worksheet.write(row, column.index('Date'), date_att, data_style) # Menulis tanggal di sheet 1
1131 worksheet.write(row, column.index('Hari'), record.day_name, data_style) # Menulis Hari di sheet 1
1132 if record.normal_in: # cek ada normal in
1133 normal_in = (datetime.strptime(record.normal_in.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7)).strftime("%H:%M") # convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
1134 worksheet.write(row, column.index('Normal In'), normal_in, data_style) # Menulis Normal In di sheet 1
1135 worksheet.write(row, column.index('In'), normal_in, data_style) # Menulis In di sheet 1
1136 if record.normal_out: # cek ada normal out
1137 normal_out = (datetime.strptime(record.normal_out.log_time, "%Y-%m-%d %H:%M:%S") + timedelta(hours=7)).strftime("%H:%M")# convert tanggal biar sesuai dengan yang di ingin kan, tambah 7 untuk mengikuti zona waktu indonesia barat
1138 worksheet.write(row, column.index('Out'), normal_out, data_style) # Menulis Normal Out di sheet 1
1139 worksheet.write(row, column.index('Normal Out'), normal_out, data_style) # Menulis Normal Out di sheet 1
1140 if record.normal_lunch:
1141 worksheet.write(row, column.index('Ist'), record.normal_lunch, data_style) # Menulis Normal Ist di sheet 1
1142 if record.total_normal_work_hour:# cek total normal work hour
1143 worksheet.write(row, column.index('Kerja'), record.total_normal_work_hour, data_style) # Menulis Kerja di sheet 1
1144 OT = record.split_hour_to_float(record.total_extra_work_hour1+record.total_extra_work_hour2) # menjumlahkan untuk OT total
1145 worksheet.write(row, column.index('OT'), OT, data_style) # Menulis OT di sheet 1
1146
1147 worksheet.write(row, column.index('I*'), record.ot1_calculate_1, data_style) # Menulis I* di sheet 1
1148 worksheet.write(row, column.index('II'), record.ot1_calculate_2, data_style) # Menulis II di sheet 1
1149 worksheet.write(row, column.index('III'), record.ot1_calculate_3, data_style) # Menulis III di sheet 1
1150 worksheet.write(row, column.index('IV'), record.ot1_calculate_4, data_style) # Menulis IV di sheet 1
1151 worksheet.write(row, column.index('TUL Jam'), record.ot1_calculate_total, data_style) # Menulis TUL Jam di sheet 1
1152 worksheet.write(row, column.index('U.Mkn'), record.meal_allowance_lunch, number_style) # Menulis U.Mkn di sheet 1
1153
1154 site_meal = http.request.env['sbm.site.meal'].sudo().search([('job_level_id', '=', record.employee_id.level_id.id), ('work_address_id', '=', record.employee_id.address_id.id)], limit=1)
1155 if record.normal_in or record.normal_out:
1156 worksheet.write(row, column.index('H'), 1, data_style) # Menulis H di sheet 1
1157 summary[record.employee_id.name]['H'] = summary[record.employee_id.name]['H'] + 1
1158
1159 if not record.normal_in or not record.normal_out:
1160 worksheet.write(row, column.index('TA'), 1, data_style) # Menulis H di sheet 1
1161 summary[record.employee_id.name]['TA'] = summary[record.employee_id.name]['TA'] + 1
1162 summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+"ta "
1163 if site_meal:
1164 worksheet.write(row, column.index('Parhari'), site_meal.meat_value, number_style) # Menulis H di sheet 1
1165 summary[record.employee_id.name]['Parhari'] = summary[record.employee_id.name]['Parhari'] + site_meal.meat_value
1166 elif record.attend_leave_id:
1167 worksheet.write(row, column.index('H'), 1, data_style) # Menulis H di sheet 1
1168 summary[record.employee_id.name]['H'] = summary[record.employee_id.name]['H'] + 1
1169
1170 if record.is_late:
1171 worksheet.write(row, column.index('Tlat'), 1, data_style)
1172 summary[record.employee_id.name]['Tlat'] = summary[record.employee_id.name]['Tlat'] + 1
1173 if record.normal_in and record.normal_out:
1174 summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+"t "
1175 if site_meal:
1176 worksheet.write(row, column.index('Telat'), site_meal.late_penalty, number_style)
1177 summary[record.employee_id.name]['Telat'] = summary[record.employee_id.name]['Telat'] + site_meal.late_penalty
1178 if record.trip_id:
1179 summary[record.employee_id.name]['Trip'] = summary[record.employee_id.name]['Trip'] + 1 # menjumlahkan Total Trip per employee
1180 worksheet.write(row, column.index('Lk'), site_meal.late_penalty, number_style)
1181 summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+"lk "
1182 summary[record.employee_id.name]['OT'] = summary[record.employee_id.name]['OT'] + OT # menjumlahkan Total OT per employee
1183 summary[record.employee_id.name]['extra_fooding'] = summary[record.employee_id.name]['extra_fooding'] + record.extra_fooding1 # menjumlahkan Total OT per employee
1184 summary[record.employee_id.name]['I*'] = summary[record.employee_id.name]['I*'] + record.ot1_calculate_1 # menjumlahkan Total I* per employee
1185 summary[record.employee_id.name]['II'] = summary[record.employee_id.name]['II'] + record.ot1_calculate_2 # menjumlahkan Total II per employee
1186 summary[record.employee_id.name]['III'] = summary[record.employee_id.name]['III'] + record.ot1_calculate_3 # menjumlahkan Total III per employee
1187 summary[record.employee_id.name]['IV'] = summary[record.employee_id.name]['IV'] + record.ot1_calculate_4 # menjumlahkan Total IV per employee
1188 summary[record.employee_id.name]['TUL Jam'] = summary[record.employee_id.name]['TUL Jam'] + record.ot1_calculate_total # menjumlahkan Total Tul Jam per employee
1189 summary[record.employee_id.name]['U.Mkn'] = summary[record.employee_id.name]['U.Mkn'] + record.meal_allowance_lunch # menjumlahkan Total U.Mkn per employee
1190 if record.attend:
1191 summary[record.employee_id.name]['attend'] = summary[record.employee_id.name]['attend'] + 1
1192 # summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+"ta "
1193 if record.normal_work_hour:
1194 worksheet.write(row, column.index('Actual'), record.normal_work_hour, data_style) # Menulis Actual di sheet 1
1195 actual = float((summary[record.employee_id.name]['Actual']).replace(":",".")) + float(record.normal_work_hour[:-3].replace(":","."))
1196 summary[record.employee_id.name]['Actual'] = str(actual).replace(".",":") # menjumlahkan Actual per employee
1197
1198 if record.unpresent: # cek kehadiran
1199 worksheet.write(row, column.index('A'), 1, data_style) # tulis alpha 1 di sheet 1
1200 summary[record.employee_id.name]['A'] = summary[record.employee_id.name]['A'] + 1 # menjumlahkan Total ALPHA per employee
1201 summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+"a "
1202
1203 if record.related_note:
1204 worksheet.write(row, column.index('Perusahaan'), record.related_note, data_style) # tulis alpha 1 di sheet 1
1205 if record.leave_id:
1206 status_leave = record.leave_id.holiday_status_id.category[0]
1207 worksheet.write(row, column.index(status_leave), 1, data_style) # tulis alpha 1 di sheet 1
1208 summary[record.employee_id.name][status_leave] = summary[record.employee_id.name][status_leave] + 1 # menjumlahkan Total ALPHA per employee
1209 summary[record.employee_id.name]['Keterangan'] = summary[record.employee_id.name]['Keterangan'] + number_date+status_leave+" "
1210 row+=1 # baris bertambah berdasarkan looping
1211
1212 self.sumarry_absen_ver2(workbook, summary, data, column)
1213 return True
1214
1215 def sumarry_absen_ver1(self, workbook, summary, column=None):
1216
1217 style = xlwt.easyxf("align: horiz center")
1218
1219 # font
1220 font = xlwt.Font()
1221 font.bold = True
1222
1223 style.font = font
1224
1225 # borders
1226 borders = xlwt.Borders()
1227 borders.bottom = 6
1228 borders.top = xlwt.Borders.THIN
1229 borders.left = 6
1230 borders.right = 2
1231 style.borders = borders
1232
1233 data_style = xlwt.easyxf("align: horiz center")
1234
1235 number_style = data_style
1236 number_style.num_format_str = '#,##0'
1237
1238 worksheet2 = workbook.add_sheet('Summary Absen') # membuat sheet 2
1239 worksheet2.col(column.index('Nama')).width = 256 * 50 # mengatur lebar kolom nama
1240 worksheet2.col(column.index('Site')).width = 256 * 50 # mengatur lebar kolom Site
1241 # worksheet2.col(column.index('Date')).width = 256 * 25 # mengatur lebar kolom Tanggal
1242 # worksheet2.col(column.index('Normal In')).width = 256 * 25 # mengatur lebar kolom Normal In
1243 # worksheet2.col(column.index('Normal Out')).width = 256 * 25 # mengatur lebar kolom Normal Out
1244 # worksheet2.col(column.index('In')).width = 256 * 25 # mengatur lebar kolom In
1245 # worksheet2.col(column.index('Out')).width = 256 * 25 # mengatur lebar kolom Out
1246 # worksheet2.col(column.index('Koreksi')).width = 256 * 25 # mengatur lebar kolom Koreksi
1247 # worksheet2.col(column.index('No. PO/SPK')).width = 256 * 25 # mengatur lebar kolom No. PO/SPK
1248 # worksheet2.col(column.index('Nilai PO/SPK')).width = 256 * 25 # mengatur lebar kolom Nilai PO/SPK
1249 # worksheet2.col(column.index('Jabatan')).width = 256 * 50 # mengatur lebar kolom Jabatan
1250 # worksheet2.col(column.index('Perusahaan')).width = 256 * 50 # mengatur lebar kolom Perusahaan
1251 # worksheet2.col(column.index('Lokasi')).width = 256 * 50 # mengatur lebar kolom Lokasi
1252 # worksheet2.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
1253 # worksheet2.col(column.index('Special Site')).width = 256 * 50 # mengatur lebar kolom Special Site
1254 # worksheet2.col(column.index('U TLK Penempatan')).width = 256 * 50 # mengatur lebar kolom U TLK Penempatan
1255 # worksheet2.col(column.index('Penempatan')).width = 256 * 50 # mengatur lebar kolom Penempatan
1256 # worksheet2.col(column.index('UG Special')).width = 256 * 50 # mengatur lebar kolom UG Special
1257
1258
1259 row = 1 # baris kembali ke 0
1260 col = 0 # kolom kembali ke 0
1261 for col_d in column: # looping kolom
1262 worksheet2.write(row, col, col_d, style=style) # create nama kolom
1263 col+=1 # kolom bertambah 1
1264
1265 row+=1 # baris tambah 1
1266 for val in sorted(summary.items()): # looping hasil penjumlahan di dict summary dan di sortir key nya
1267 worksheet2.write(row, column.index('Nama'), val[0])
1268 worksheet2.write(row, column.index('OT'), val[1]['OT'])
1269 worksheet2.write(row, column.index('I*'), val[1]['I*'])
1270 worksheet2.write(row, column.index('II'), val[1]['II'])
1271 worksheet2.write(row, column.index('III'), val[1]['III'])
1272 worksheet2.write(row, column.index('IV'), val[1]['IV'])
1273 worksheet2.write(row, column.index('TUL Jam'), val[1]['TUL Jam'])
1274 worksheet2.write(row, column.index('U.Mkn'), val[1]['U.Mkn'], number_style)
1275 worksheet2.write(row, column.index('Actual'), val[1]['Actual'])
1276 worksheet2.write(row, column.index('H'), val[1]['H'])
1277 worksheet2.write(row, column.index('A'), val[1]['A'])
1278 worksheet2.write(row, column.index('TA'), val[1]['TA'])
1279 worksheet2.write(row, column.index('Tlat'), val[1]['Tlat'],number_style)
1280 worksheet2.write(row, column.index('Telat'), val[1]['Telat'], number_style)
1281 worksheet2.write(row, column.index('Parhari'), val[1]['Parhari'], number_style)
1282 row+=1
1283
1284
1285
1286
1287 def sumarry_absen_ver2(self, workbook, summary,data, column=None):
1288
1289 style = xlwt.easyxf("align: horiz center")
1290
1291 # font
1292 font = xlwt.Font()
1293 font.bold = True
1294
1295 style.font = font
1296
1297 # borders
1298 borders = xlwt.Borders()
1299 borders.bottom = 6
1300 borders.top = xlwt.Borders.THIN
1301 borders.left = 6
1302 borders.right = 2
1303 style.borders = borders
1304
1305 data_style = xlwt.easyxf("align: horiz center")
1306
1307 number_style = data_style
1308 number_style.num_format_str = '#,##0'
1309 column = ['No', 'Site', 'Karyawan', 'Jabatan', 'H', 'OT']
1310 leave_category = http.request.env['hr.holidays.status'].sudo().daftar_category
1311 for lc in leave_category:
1312 column.append(lc[0][0])
1313 column = column + ['A', 'TL', 'TA', 'Jam Telat', 'UM', 'UM OT', 'Pot.Telat', 'TLK', 'PJS', 'Dibayar', 'Keterangan', 'HK']
1314 worksheet2 = workbook.add_sheet('Summary Absen') # membuat sheet 2
1315 worksheet2.col(column.index('Karyawan')).width = 256 * 50 # mengatur lebar kolom nama
1316 worksheet2.col(column.index('Site')).width = 256 * 50 # mengatur lebar kolom Site
1317
1318 row = 4 # baris kembali ke 0
1319 col = 0 # kolom kembali ke 0
1320 for col_d in column: # looping kolom
1321 worksheet2.write(row, col, col_d, style=style) # create nama kolom
1322 col+=1 # kolom bertambah 1
1323
1324 row+=1 # baris tambah 1
1325 no = 1
1326 total_dibayar = 0
1327 for val in sorted(summary.items()): # looping hasil penjumlahan di dict summary dan di sortir key nya
1328 dibayar = val[1]['U.Mkn']+val[1]['extra_fooding']
1329 total_dibayar = total_dibayar + dibayar
1330 worksheet2.write(row, column.index('No'),no)
1331 worksheet2.write(row, column.index('Site'),val[1]['Site'])
1332 worksheet2.write(row, column.index('Karyawan'), val[0])
1333 worksheet2.write(row, column.index('Jabatan'), val[1]['Jabatan'])
1334 worksheet2.write(row, column.index('H'), val[1]['H'])
1335 worksheet2.write(row, column.index('OT'), val[1]['OT'])
1336 worksheet2.write(row, column.index('A'), val[1]['A'])
1337 worksheet2.write(row, column.index('TA'), val[1]['TA'])
1338 worksheet2.write(row, column.index('Jam Telat'), val[1]['Tlat'])
1339 worksheet2.write(row, column.index('Pot.Telat'), val[1]['Telat'], number_style)
1340 worksheet2.write(row, column.index('UM'), val[1]['Parhari'], number_style)
1341 worksheet2.write(row, column.index('UM OT'), val[1]['extra_fooding'], number_style)
1342 worksheet2.write(row, column.index('Dibayar'), dibayar, number_style)
1343 worksheet2.write(row, column.index('TL'), val[1]['Trip'])
1344 worksheet2.write(row, column.index('Keterangan'), val[1]['Keterangan'])
1345 worksheet2.write(row, column.index('HK'), val[1]['attend'])
1346 for lc in leave_category:
1347 worksheet2.write(row, column.index(lc[0][0]), val[1][lc[0][0]])
1348
1349 # worksheet2.write(row, column.index('TUL Jam'), val[1]['TUL Jam'])
1350 # worksheet2.write(row, column.index('U.Mkn'), val[1]['U.Mkn'], number_style)
1351 # worksheet2.write(row, column.index('Actual'), val[1]['Actual'])
1352 # worksheet2.write(row, column.index('H'), val[1]['H'])
1353 # worksheet2.write(row, column.index('A'), val[1]['A'])
1354 # worksheet2.write(row, column.index('TA'), val[1]['TA'])
1355 # worksheet2.write(row, column.index('Tlat'), val[1]['Tlat'],number_style)
1356 # worksheet2.write(row, column.index('Telat'), val[1]['Telat'], number_style)
1357 # worksheet2.write(row, column.index('Parhari'), val[1]['Parhari'], number_style)
1358 row+=1
1359 no+=1
1360
1361 style = xlwt.easyxf("align: horiz center")
1362 font = xlwt.Font()
1363 font.bold = True
1364 font.height = 200
1365 style.font = font
1366 start_date = datetime.strptime(data.start_date, '%Y-%m-%d').strftime('%d %b %Y')
1367 end_date = datetime.strptime(data.end_date, '%Y-%m-%d').strftime('%d %b %Y')
1368 worksheet2.write_merge(0, 0, 0, 21, 'DAFTAR UANG MAKAN PT. SUPRABAKTI MANDIRI', style=style)
1369 worksheet2.write_merge(1, 1, 0, 21, str(start_date)+" SAMPAI "+str(end_date), style=style)
1370 style.num_format_str = '#,##0'
1371 # borders
1372 borders = xlwt.Borders()
1373 borders.bottom = 3
1374 borders.top = xlwt.Borders.THIN
1375 borders.left = 1
1376 borders.right = 2
1377 style.borders = borders
1378 worksheet2.write_merge(3, 3, 1, 2, total_dibayar, style=style)
1379
1380
1381 @http.route('/export_report_attendance/', type='http', auth="public")
1382 def export_report_attendance(self, id, **kw):
1383
1384 data = http.request.env['sbm.hr.attendance.report'].sudo().search([('id', '=', id)], limit=1) # search data attendance report berdasarkan id
1385
1386 workbook = xlwt.Workbook() # create WorkBook
1387 self.report_absen_sheet(workbook, data)
1388
1389 output = StringIO.StringIO()
1390 workbook.save(output)
1391 filecontent = output.getvalue()
1392 return http.request.make_response(filecontent,
1393 [('Content-Type', 'application/octet-stream'),
1394 ('Content-Disposition', content_disposition(data.display_name+'.xls'))])
1395