コード例 #1
0
    def get_valid_contract(self, cr, uid, ids, date, context=None):
        res = {}

        _query_ = """
            SELECT employee_id, min(id), count(*) FROM hr_contract
            WHERE
                employee_id in (%(employee)s) AND
                (
                SELECT CASE
                WHEN not date_end is Null THEN
                    (date_start, date_end)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    date_start <= DATE '%(date)s'
                END
                )
            GROUP BY
                employee_id
            """ % {
            'employee': ','.join(map(str, ids)),
            'date': tu.dt2s(date),
        }
        cr.execute(_query_)
        emp_con = cr.fetchall()
        for (emp_id, con_id, c) in emp_con:
            if c > 1:
                raise RuntimeError('More than one contract at same time for'
                                   ' employee with id=%i' % emp_id)
            else:
                res[emp_id] = con_id
        return res
コード例 #2
0
    def get_valid_contract(self, cr, uid, ids, date, context=None):
        res = {}

        _query_ = """
            SELECT employee_id, min(id), count(*) FROM hr_contract
            WHERE
                employee_id in (%(employee)s) AND
                (
                SELECT CASE
                WHEN not date_end is Null THEN
                    (date_start, date_end)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    date_start <= DATE '%(date)s'
                END
                )
            GROUP BY
                employee_id
            """ % {
                'employee': ','.join(map(str, ids)),
                'date': tu.dt2s(date),
                }
        cr.execute(_query_)
        emp_con = cr.fetchall()
        for (emp_id, con_id, c) in emp_con:
            if c > 1:
                raise RuntimeError('More than one contract at same time for'
                                   ' employee with id=%i' % emp_id)
            else:
                res[emp_id] = con_id
        return res
コード例 #3
0
    def _get_holidays(self, cr, uid, ids, field_name, arg, context=None):
        """
        Generate list of attendance associated to the this journal.
        """
        res = {}
	data = self.read(cr, uid, ids, ['employee_id', 'date', 'turn_start', 'turn_end'], context=context)
	for d in data:
            turn_start = d['turn_start']
            turn_end = d['turn_end']
            employee_id = d['employee_id'][0]
	    date = d['date']
	    _id = d['id']
            if turn_start:
                date_start, date_end = turn_start, turn_end
            else:
                date_start, date_end = date, tu.dt2s(tu.d(date) +
                                                         tu.timedelta(days=1))

            sql_req= """
            SELECT H.id AS func_id
            FROM hr_holidays as H
            WHERE
              (H.employee_id = %d OR H.employee_id is Null) AND
              (H.date_from, H.date_to) OVERLAPS
              ('%s'::timestamp, '%s'::timestamp)
            """ % (employee_id, date_start, date_end)
            cr.execute(sql_req)
            sql_res = cr.fetchall()

            if len(sql_res) > 0:
                res[_id] = map(lambda (i,): i, sql_res)
            else:
                res[_id] = []
        return res
コード例 #4
0
    def compute(self, cr, uid, ids, context=None):
        lines_to_compute = []
        for payroll in self.browse(cr, uid, ids, context=context):
            if payroll.state == "draft":
                self.pool.get("hr.aa.journal").build(
                    cr, uid, tu.dt2s(tu.d(payroll.date_from)), tu.dt2s(tu.d(payroll.date_to)), context=context
                )
                lines_to_compute += [l.id for l in payroll.line_ids]
        import cProfile

        cProfile.runctx(
            'self.pool.get("hr.aa.payroll.line").compute(cr, uid, lines_to_compute)',
            {"self": self, "cr": cr, "uid": uid, "lines_to_compute": lines_to_compute},
            None,
            "/tmp/compute.pstats",
        )
        return True
コード例 #5
0
 def _get_day_end(self, cr, uid, ids, field_name, arg, context=None):
     res = {}
     dtc = lambda sd: tu.dt(sd.sign_out_id.name)
     for day in self.browse(cr, uid, ids):
         if day.attendance_ids:
             res[day.id] = tu.dt2s(max(map(lambda i: tu.dt(i.name),
                                           day.attendance_ids)))
         else:
             res[day.id] = False
     return res
コード例 #6
0
    def _get_turn_date(self, cr, uid, ids, field_name, arg, context=None):
        res = self._get_turn_start(cr, uid, ids, field_name, arg,
                                  context=context)
        if not res:
            return False

        for k in res:
            if res[k]:
                res[k] = tu.dt2s(
                    tu.datetime.combine(tu.dt(res[k]).date(), tu.time(0)))

        return res
コード例 #7
0
    def get_valid_holidays(self, cr, uid, ids, date, context=None):
        res = {}

        _query_ = """
            SELECT employee_id, id, state
            FROM hr_holidays
            WHERE
                employee_id in (%(employee)s) AND
                (
                SELECT CASE
                WHEN not date_to is Null THEN
                    (date_from, date_to)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    date_from <= DATE '%(date)s'
                END
                )
            UNION
            SELECT E.e, H.id, H.state
            FROM hr_holidays as H,
                 (VALUES %(employee_x)s) as E(e)
            WHERE
                H.employee_id is Null AND
                (
                SELECT CASE
                WHEN not H.date_to is Null THEN
                    (H.date_from, H.date_to)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    H.date_from <= DATE '%(date)s'
                END
                )
            """ % {
            'employee': ','.join(map(str, ids)),
            'employee_x': '(' + '),('.join(map(str, ids)) + ')',
            'date': tu.dt2s(date),
        }
        cr.execute(_query_)
        emp_hol = cr.fetchall()
        for (emp_id, hol_id, state) in emp_hol:
            if not emp_id in res:
                res[emp_id] = {
                    'draft': [],
                    'confirm': [],
                    'refuse': [],
                    'validate': [],
                    'cancel': []
                }
            res[emp_id][state].append(hol_id)
        return res
コード例 #8
0
    def _inv_attendance(self, cr, uid, ids, field_name, value, arg, context=None):
        """
        Store attendance from a journal. Assign employee id and set the correct
        datetime.
        """
        jou_id = ids
        for no_se, att_id, val in value:
            if val:
                # Who is the associated journal?
                if jou_id == 0:
                    if not isinstance(ids, int):
                        raise osv.except_osv(_('Error'),
                                             _('I expect process attendance just for one journal'))
                    jou_id = ids
                jou = self.browse(cr, uid, jou_id)

                # Check date if not out of turn time.
                if not jou._date_overlaps(tu.dt(val['name']))[jou.id]:
                    an = tu.datetime.combine(tu.d(jou.date).date(), tu.dt(val['name']).time())
                    if not jou._date_overlaps(an)[jou.id]:
                        an = tu.datetime.combine(tu.d(jou.date).date() + tu.timedelta(days=1), tu.dt(val['name']).time())
                    val['name'] = tu.dt2s(an)
                    if not (jou._date_overlaps(tu.dt(val['name']))):
                        raise osv.except_osv(_('Error'),
                                             _('Attendance don\'t belong to this journal'))

        # Sort entries
        att_ids = []
        values = []
        for no_se, att_id, val in value:
            if val:
                att_ids.append(att_id)
                values.append(val) 
        att_ids.sort()
        values.sort(key=lambda i: i['name'])
        attval = dict(zip(att_ids, values))

        # Store new or modification
        for att_id, val in zip(att_ids, values):
            if val:
                if att_id == 0:
                   val['employee_id'] = jou.employee_id.id
                   self.pool.get('hr.attendance').create(cr, uid, val)
                else:
                   self.pool.get('hr.attendance').write(cr, uid, att_id, val)

        # Delete entries
        for no_se, att_id, val in value:
            if not val:
                self.pool.get('hr.attendance').unlink(cr, uid, att_id)
コード例 #9
0
    def get_valid_holidays(self, cr, uid, ids, date, context=None):
        res = {}

        _query_ = """
            SELECT employee_id, id, state
            FROM hr_holidays
            WHERE
                employee_id in (%(employee)s) AND
                (
                SELECT CASE
                WHEN not date_to is Null THEN
                    (date_from, date_to)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    date_from <= DATE '%(date)s'
                END
                )
            UNION
            SELECT E.e, H.id, H.state
            FROM hr_holidays as H,
                 (VALUES %(employee_x)s) as E(e)
            WHERE
                H.employee_id is Null AND
                (
                SELECT CASE
                WHEN not H.date_to is Null THEN
                    (H.date_from, H.date_to)
                    overlaps
                    (DATE '%(date)s', DATE '%(date)s')
                ELSE
                    H.date_from <= DATE '%(date)s'
                END
                )
            """ % {
                'employee': ','.join(map(str, ids)),
                'employee_x': '(' + '),('.join(map(str, ids)) + ')',
                'date': tu.dt2s(date),
        }
        cr.execute(_query_)
        emp_hol = cr.fetchall()
        for (emp_id, hol_id, state) in emp_hol:
            if not emp_id in res: res[emp_id] = {'draft': [], 'confirm': [],
                                                 'refuse': [], 'validate': [],
                                                 'cancel': []}
            res[emp_id][state].append(hol_id)
        return res
コード例 #10
0
    def _get_turn_start(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        for journal in self.browse(cr, uid, ids):
            if journal.turn_id:
		wd_l = [ str(tu.d(journal.date).weekday()), '' ]
                ts = filter(lambda i:
                                i.dayofweek in wd_l,
                                journal.turn_id.timesheet_id)
                if len(ts) == 1:
                    res[journal.id] = tu.dt2s(tu.d(journal.date) +
                                        tu.timedelta(hours=ts[0].hour_from))
                elif len(ts) > 1:
                    raise osv.except_osv(_('Error'), _('Overlaped turn for the journal %s.') % journal.name)
                else:
                    res[journal.id] = False
            else:
                res[journal.id] = False
        return res
コード例 #11
0
    def build(self, cr, uid, date_from, date_to, context=None):
        emp_pool = self.pool.get('hr.employee')
        con_pool = self.pool.get('hr.contract')
        journal_ids = []
        for time in tu.daterange(tu.dt(date_from), tu.dt(date_to) + tu.timedelta(days=1)):
            journal_date = tu.dt2s(time)
            emp_ids = emp_pool.search(cr, uid, [], context=context)
            con_ids = emp_pool.get_valid_contract(cr, uid, emp_ids, time)

            for (emp_id, con_id) in con_ids.items():
                emp = emp_pool.browse(cr, uid, emp_id, context=context)
                con = con_pool.browse(cr, uid, con_id, context=context)

                contract_hours = (
                    str(time.weekday()) in [ ts.dayofweek for ts in
                                                con.turn_id.timesheet_id ]
                    ) * con.working_hours_per_day

                journal = {
                    'name': emp.name + time.strftime(' (%d/%m/%Y)'),
                    'date': journal_date,
                    'employee_id': emp_id,
                    'turn_id': con.turn_id.id,
                    'department_id': con.department_id.id,
                    'contract_hours': contract_hours,
                }
                jids = self.search(cr, uid, [
                    ('employee_id', '=', journal['employee_id']),
                    ('date', '=', journal['date']),
                ])
                if len(jids) == 0:
                    journal_ids.append(self.create(cr, uid, journal, context=context))
                else:
                    logger.notifyChannel('hr.aa.journal',
                                 netsvc.LOG_INFO,
                                 'Yet exists journal \'%s\'' %
                                 journal['name'])

        self.compute(cr, uid, journal_ids, context=context)
        return len(journal_ids)
コード例 #12
0
 def _get_turn_start(self, cr, uid, ids, field_name, arg, context=None):
     res = {}
     conts = self._get_contract(cr, uid, ids, 'contract', None, context=context)
     items = conts.items()
     if len(items) == 0: return False
     att_ids, con_ids = tuple(map(list, zip(*items)))
     cons = self.pool.get('hr.contract').browse(cr, uid, con_ids)
     atts = self.pool.get('hr.attendance').browse(cr, uid, att_ids)
     for (att, cont) in zip(atts, cons):
         turns = [ (tu.dt(att.date) +
                    tu.timedelta(days = int(i.dayofweek) - tu.dt(att.date).weekday(), hours=i.hour_from),
                    tu.dt(att.date) +
                    tu.timedelta(days = int(i.dayofweek) - tu.dt(att.date).weekday(), hours=i.hour_to + 24*(i.hour_to < i.hour_from)))
                  for i in  cont.turn_id.timesheet_id ]
         turns = filter(lambda (f,t):
                          f - tu.timedelta(hours=6) <= tu.dt(att.datetime) and
                          tu.dt(att.datetime) <= t + tu.timedelta(hours=6), turns)
         if len(turns) > 0:
             res[att.id] = tu.dt2s(turns[0][0])
         else:
             res[att.id] = False
     return res
コード例 #13
0
    def load_attendances(self, cr, uid, ids=None,
             clean_at_end = None,
             complete_attendance = None,
             create_unknown_employee = None,
             ignore_sign_inout = None,
             tolerance = None,
             context=None):
        AC = AttendanceCreator(cr, uid, context=context)
        card_err = {}
        empl_err = {}
        empl_id = {}
        err = []
        c = 0
	emp_obj=self.pool.get('hr.employee')
	empl_ids = emp_obj.search(cr,uid,[])
	empl_ids = emp_obj.browse(cr,uid,empl_ids)
	for empl in empl_ids:
		empl_id[empl.matricule]=empl.matricule
        if ids==None:
            ids = self.search(cr, uid, [])

	from datetime import datetime
        import csv
	DEBUGFILE = open('/tmp/clock.%s.csv' % datetime.today(), 'w')
	DEBUGCSV  = csv.writer(DEBUGFILE)

        for clock in self.browse(cr, uid, ids):
            C = clock_class[clock.model](clock.uri, timeout=clock.timeout)
	    uri=clock.uri
	    uri = uri.replace('/','').split(':')
	    assert(len(uri) == 3)
	    assert(uri[0] == 'udp')
            server_address = uri[1]
	    server_port = int(uri[2])
	    template="""<?xml version="1.0" standalone="no"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
 <GetAttLog>
 <ArgComKey xsi:type="xsd:integer">0</ArgComKey>
 <Arg>
 <PIN xsi:type="xsd:integer">ALL</PIN>
 </Arg>

 </GetAttLog>
 </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>"""

	    headers = {'Content-type':'text/xml', 'SOAPAction':'uri:zksoftware'}
	    logger.notifyChannel('server-address', netsvc.LOG_DEBUG,server_address)
	    logger.notifyChannel('server-port', netsvc.LOG_DEBUG,server_port)

	    connection = httplib.HTTPConnection(server_address, server_port)
	    connection.request("POST", "/iWsService", template,headers)
	    response = connection.getresponse()
	    dom = parseString(response.read())
	    print dom
	    logs=[]

#            if not C.connect():
#                err.append("Can't connect with clock '%s'." % clock.name)
#                continue

	    for node in dom.getElementsByTagName('Row'):
	        items={}
	        for rows in node.childNodes:
	            for elements in node.childNodes:
	                for value in elements.childNodes:
	                    items[elements.nodeName]=value.toxml()
	                    logs.append(items)
	    n=1
	    for log in logs:
	        n=n+1
	        logger.notifyChannel('wizard.clock_reader', netsvc.LOG_DEBUG,
                                          'Item: %i'%n)
	        for key, value in log.iteritems() :
	            if key=='Status':
	                action=value
	            if key=='WorkCode':
	                workcode=value
	            if key=='Verified':
	                method=value
	            if key=='PIN':
	                card_id=int(value)
	            if key=='DateTime':
	                dt=value
	        if action==0:
	            action='sign_in'
	        else:
	            action='sign_out'
#            for n, card_id, method, action, dt in C.attendances():
                DEBUGCSV.writerow((n,card_id, workcode, action, dt))

#                assert isinstance(dt, tu.datetime)

                # Verifico que esta tarjeta no me haya traido problemas
                # previamente.
                if card_id in card_err:
                    logger.notifyChannel('wizard.clock_reader', netsvc.LOG_DEBUG,
                                          '_read_clock: Card %i in the black list.'%card_id)
                    continue

                # Verificar si un empleado usa esa tarjeta
                if not card_id in empl_id:
                    try:
                        empl_id[card_id] = AC.employee_id(card_id)

                    except MultipleAssignedCardError, m:
                        card_err[card_id] = str(m)
                        continue

                    except NotAssignedCardError, m:
                        if setSome(create_unknown_employee,
                                   clock.create_unknown_employee):
                            empl_id[card_id] = AC.create_employee(card_id)
                        else:
                            card_err[card_id] = str(m)
                            continue

                # Verifico que este empleado no me haya traido problemas
                # previamente.
                    logger.notifyChannel('wizard.clock_reader', netsvc.LOG_DEBUG,
                                    '_read_clock: Employee %i in the black list.' %
                                                                   empl_id[card_id])
                    continue

                # Si esta todo bien con el empleado, cargo la asistencia.
                if AC.exists_attendance(empl_id[card_id], dt, action):
                    logger.notifyChannel('clock_reader.clock', netsvc.LOG_DEBUG,
                               'read: Attendance %i:%s:%s(%s) yet loaded.' %
                                    (empl_id[card_id], tu.dt2s(dt), action, method))
                    continue

                # Ignore action
                if setSome(ignore_sign_inout, clock.ignore_sign_inout):
                    cr.execute("""
                        select A1.name, A1.action
                        from hr_attendance as A1
                            left outer join
                            hr_attendance as A2
                            on A1.employee_id=A2.employee_id AND A1.name < A2.name
                        where A2.name is Null and A1.employee_id = %i
                        """ % empl_id[card_id])
                    action = cr.fetchall()
	            if action==0:
	                action='sign_in'
                    else:
	                action='sign_out'
#                    if len(action) == 1:
#                        action=action[0]
#                        action = _negative_action[action[1]]
#                    else:
#                        action='sign_in'

                r = AC.create_attendance(empl_id[card_id], dt, action, method,
                                     tolerance=setSome(tolerance,
                                                       clock.tolerance),
                                     complete_attendance=setSome(complete_attendance,
                                                                clock.complete_attendance))

                if r != AttendanceCreator.ERROR:
                    c = c + 1
                else:
                    logger.notifyChannel('clock_reader.clock',
                         netsvc.LOG_INFO,
                         'read: Append employee %s to the black list.' %
                         str(empl_id[card_id]))
                    empl_err[empl_id[card_id]] = str(m)
コード例 #14
0
 def _get_date(self, cr, uid, ids, field_name, arg, context=None):
     res = map(lambda a: (a.id,
                          tu.dt2s(tu.datetime.combine(tu.dt(a.name).date(),tu.time(0)))),
         self.browse(cr, uid, ids))
     return dict(res)