B
    Նc_                 @   s   d dl mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZ d dlZd dlmZ G dd deZdS )    )OrderedDict)ladonize)SUCCESS_CODEMESSAGE_CODErequest_valid
user_photostamp2datetimedatetime2stamponline_employee_newinterface_responseget_describeSYSTEM_EXCEPTIONDATA_EXCEPTIONpagingdate_periodsave_captureget_first_dayget_last_dayN)gettext_lazyc               @   s   e Zd ZdZeeeeeeeeeeeeeeddd Zeeeeeeeeddd Z	eeeeeeeeeeed	dd Z
eeeeeeeeedd	d
 ZdS )BioTimeAppClockInu   
    【Clock In】
    )Zrtypec       +   
   C   s  ddl }ddl}ddlm} ddlm} ddlm}m} ddl	m
} ddlm} ddlm} dd	lm} t|	}|rp|jdkrd
}td}dtd}ttd
|||S |r|sd
}td}dtd}ttd
|||S yd|dkrt|}|d }|dd}|r>d|}n&t|}|d d }|d d d }W nL tk
r } z,d
}d|}dtd}ttd
|||S d}~X Y nX |jr||||}|rttd
d
d
|S |}|rDddlm} | } || t|t|}!|j |!}"t!||!d}|"| " }#t#|#}#|#dkrbdtd}ttd
d
d
|S ndtd}ttd
d
d
|S |j  }$|j$% dkr|$}|r@yj|j&r|j  }%|j'(|j)|| |j  }&|&|% j*}'n,|j  }%t+|j)|| |j  }&|&|% j*}'W nN tk
r> } z.ddl,}(|(-  dtd}ttd
d
||S d}~X Y nX |. }|r|j/j0|dj1dd d!})|)rv|)d }ndtd"}ttd
d
|t2S |||}|sdtd#|j3 }ttd
d$d%|S | }*|j)|*_)||*_4||*_5|j6j7|*_8d&|*_9||*_:|p d'|*_;|rt|pd|*_<|r*t|p,d|*_=||*_>||*_?d(|*_@d)|*_A|$|*_B|*C  ttDtE||d*d
d+S dtd}dtd}ttd
d
||S dS ),u  
        Upload transaction
        @param punch_time:      punch time(stamp)
        @param punch_type:      punch type( BioTimeAppManualLog -> category)
        @param work_code:       work code( BioTimeAppManualLog -> work_code)
        @param capture:         punch photo (base64)
        @param longitude:       longitude(GPS)
        @param latitude:        latitude(GPS)
        @param location:        locationi
        @param source:          data source(1: IOS， 2：Android)
        @param device_token:    Token for push message
        @param language:
        @param token:
        @rtype:
            success:
                {"code": 1, "error": "", "describe": "", "message": "", "data":{"location":"", "punch_time":"punch time(stamp)"}}
            fail:
                {"code": -10001, "error": "", "describe": "exception state", "message": "Pop-up message", "data":""}
        r   N)Transaction)TerminalWorkCode)timezonecountry_timezones)valid_distance_check)settings)tasks)has_schedule Zapp_punch_status_disabledz{0}Z app_punch_status_must_be_enabledZlongitude_or_latitude_missingZapp_clockIn_gps_required)   ZCountryCodeZFormattedAddressLinesz - ZmCountryCodeZmAddressLines0Zapp_clockIn_invalid_gps)tzwhere)tz<   Zapp_clockIn_invalid_punch_time)Z
postgresqlZapp_clockIn_upload_failed)idcodeT)flatZapp_clockIn_invalid_workcodeZno_employee_scheduleerrordescribee      ZApp   )location
punch_time
successful)Fcodecsdatetime&mysite.iclock.models.model_transactionr   Z#mysite.iclock.models.model_workcoder   Zpytzr   r   mysite.mobile.utilsr   Zdjango.confr   Zmysite.mobiler   Zmysite.att.utilsr   r
   Zapp_punch_status_formatr   r   jsonloadsgetjoin	ExceptionZACTIVE_APP_LOCATIONr!   ZtzNameAtfloatnowr   Ztotal_secondsabsZDATABASE_ENGINElowerZACTIVE_CELERYZsave_clock_captureZdelayemp_codeZsecondsr   	traceback	print_excstripobjectsfiltervalues_listr   Z
first_nameempr-   companyr$   
company_idverify_type	work_codepunch_state	longitudelatitudegps_locationmobileterminal_snsourceZupload_timeZsaver   dumps)+selfr-   
punch_typerI   ZcapturerK   rL   r,   rP   device_tokenlanguagetokenr/   r0   r   r   r   r   r   r   r   r   rE   r'   r(   messageZcountry_codeZformattedaddresslineseresultZstamp_punch_timer!   Zgps_tzr"   Z
local_timeZtransfer_timer;   startendZdurationr?   ZwcsZtsn r\   ;G:\easytimepro\master/mysite/mobile\services\app_clockin.pyupload_transaction   s    













z$BioTimeAppClockIn.upload_transactionc          
      s8  ddl m} ddlm} ddlm} ddl}	yt|}t|}
|
j	j
j}|jj|
j|j|j|jdddd d	d
ddd}|r|d|d}t|  fdd|D }ng }|	j }|jj|
j|d}|j|ddd }ddlm} g }|rx|D ]}d}y|jj|jd }|j}W n   Y nX |jrx|	j|j|j}td}t|t|d|j dd}|!| |j"r|	j|j|j"}td}t|t|d|j#dd}|!| qW ng }|| }t$|dd dd}t%t&t'(|ddS  t)k
r2 } z ddl*}|+  t%t,dd|t-S d}~X Y nX dS )u  
        get transaction log
        @param current_day:    (stamp)
        @param source:          data source(1: IOS， 2：Android)
        @param device_token:    Token for push message
        @param language:
        @param token:
        @rtype:
            success:
                {"code": 1, "error": "", "describe": "", "message": "", "data":[{"punch_time": 1513699200, "punch_type": "0", "source": 3, "describe": "source/terminal_sn/gps_location"}, ]}
                source(transaction source): (1, terminal), (2,manual log), (3, APP)
            fail:
                {"code": -10001, "error": "", "describe": "exception state", "message": "Pop-up message", "data":""}
        r   )get_func_key)r   )OutdoorTrackN)emp_idZpunch_time__yearZpunch_time__monthZpunch_time__dayz-punch_timer+   r-   rH   rP   rO   rM   )keyrG   c          
      sL   g | ]D}t |d   |d d|d p*dt|d |d |d ddqS )r   r   r      r+      F)r-   rS   rP   r(   outdoor)r	   r7   r   ).0r)typesr\   r]   
<listcomp>   s   z6BioTimeAppClockIn.pull_transaction.<locals>.<listcomp>)employee_idrG   )date)ClientDetailsr   )r$   timeInterval_field_checkInT)r-   rS   rP   r(   re   timeInterval_field_checkOutc             S   s   | d S )Nr-   r\   )kr\   r\   r]   <lambda>       z4BioTimeAppClockIn.pull_transaction.<locals>.<lambda>)rb   reverser.   ).mysite.att.att_paramr_   Zmysite.iclock.modelsr   mysite.att.modelsr`   r0   r   r
   
departmentrF   r$   rB   rC   ZyearZmonthZdayorder_byrD   dictr;   %mysite.att.models.model_clientdetailsrl   	client_idfirstaddresscheckincombinerk   r3   r	   strcheckin_addressappendcheckoutcheckout_addresssortedr   r   r5   rQ   r9   r?   r@   r   r   )rR   current_dayrP   rT   rU   rV   r_   r   r`   r0   rE   rG   Ztschoicesdatatodayemp_outdoorrl   Zoutdoor_punch_displayrg   r(   client_detailscheck_in_date_timerJ   Zoutdoor_item_check_incheck_out_date_timeZoutdoor_item_check_outZfinal_punches_displayZ final_punches_display_order_wiserX   r?   r\   )rh   r]   pull_transaction   sl    







z"BioTimeAppClockIn.pull_transactionc	       <   
   C   s  ddl m}	m}
 ddlm} ddlm} ddl}ddlm	} t
|}t|}|j}|jjj}|jj}g }y| }||jdd }|d	|d	|d
}d}|d | }|| }|s|| }|rd||d< |	ddd|d}nL|dkr|j|d< |jj|d< |	ddd|d}n|j|d< |	ddd|d}||ddd}|
|}g }|r`dd |D }ttt||| ddS ddlm} ddl}ddlm} ddlm} dd lm } |j!j"||d!j#d"d#d$} |j$ }!|!|jd%d }"|j!j"| ||"|!fd&%d'}#g }$|#r|d|d(}%t&|%}&t' }'xl|#D ]d}(|(j(d)})|)|'krPg |'|)< |)t)|(j(|&*|(j+d|(j,t-|(j,|(j.|(j/d*d+}*|'|) 0|* q.W d,d |'1 D }$|j!j"| |d-}+|+j"|"|!fd.}+dd/l2m3}, |+rt' }-x|+D ]}(d}.y|,j!j"|(j4d05 }/|/j6}.W n   Y nX |(j7d)}0|0|-kr8g |-|0< |(j8r|j9|(j7|(j8}1t:d1}2|0t)|1t;|2d2|(j<d#d+}3|-|0 0|3 |(j=r|j9|(j7|(j=}4t:d3}2|0t)|4t;|2d2|(j>d#d+}3|-|0 0|3 qW d4d |-1 D }|$| }5|t?}6x$|5D ]}7|6|7d5  @|7d6  qW d7d |61 D }8tA|8|d5d#d8}9ttt|9|| ddS  tBk
r }: z ddlC};|;D  ttEdd|:tFS d}:~:X Y nX dS )9u9  
        get all transaction
        @param pin:            emp_code, return employee list when emp_code is null
        @param current_day:
        @param page_num:        page number（15items/page）
        @param search_item      search employee by emp_code or name
        @param source:          data source(1: IOS， 2：Android)
        @param device_token:   Token for push message
        @param language:
        @param token:
        @rtype:
            pin is not null ,success
                {"code": 1,"error":"", "describe":"", "message":"", "data":[{"pin": "emp_code", "name":"first_name", "photo":"photo address"}, ]}
            pin is null ,success:
                {"code": 1,"error":"", "describe":"", "message":"", "data":[{"punch_time": "punch time(stamp)", "punch_type":"punch type", "source":1, "describe": "terminal_sn"}, ]}
                source(transaction source): (1, terminal), (2,manual log), (3, APP)
            fail:
                {"code": -10001, "error": "", "describe": "exception state", "message": "Pop-up message", "data":""}
        r   )get_sqlp_query)r_   )employee_transaction_pagingN)defaultdicti)Zdaysz%Y-%m-%d %H:%M:%S)r   previous_daycompany_hex_id   r   z%{0}%r>   sqlZ&transaction_employee_search_by_empCoderN   )ZsqlidZappparamsrc   ra   ru   Ztransaction_departmentZtransaction_employeeZdesc)Z	sort_nameZ
sort_orderc             S   s(   g | ] }|d  |d t |d  dqS )r   r   )pinnameZphoto)r   )rf   rg   r\   r\   r]   ri   9  s    z:BioTimeAppClockIn.pull_all_transaction.<locals>.<listcomp>r   )r   )
itemgetter)r`   )Employee)r>   rG   r$   T)r&      )ra   rG   Zpunch_time__rangez-punch_time)rb   rG   z%Y-%m-%dF)categoryr-   rS   rP   r(   re   c             S   s   g | ]\}}||d qS ))r   itemsr\   )rf   rb   valr\   r\   r]   ri   W  s    )rj   rG   )Zdate__range)rl   )r$   rm   r+   rn   c             S   s   g | ]\}}||d qS ))r   r   r\   )rf   rb   r   r\   r\   r]   ri   y  s    r   r   c             S   s(   g | ] \}}|t |d d dddqS )c             S   s   | d S )Nr-   r\   )ro   r\   r\   r]   rp     rq   zCBioTimeAppClockIn.pull_all_transaction.<locals>.<listcomp>.<lambda>T)rb   rr   )r   r   )r   )rf   r   r   r\   r\   r]   ri     s   )rb   rr   )GZmysite.sql_utilsr   r   rs   r_   r2   r   r0   collectionsr   r   r
   app_roleru   rF   r$   Zhex_idrA   Z	timedeltastrftimer4   r   r   r5   rQ   r1   r   operatorr   Z$mysite.att.models.model_outdoortrackr`   Z&mysite.personnel.models.model_employeer   rB   rC   rD   r;   rv   rw   r   r-   r	   r7   rJ   rP   r   rO   rM   r   r   rx   rl   ry   rz   r{   rk   r|   r}   r3   r~   r   r   r   listextendr   r9   r?   r@   r   r   )<rR   r   r   Zpage_numZsearch_itemrP   rT   rU   rV   r   r   r_   r   r0   r   rE   r   rG   r   Zoutdoorpunch_datar   r   Z	PAGE_SIZEZbeginr[   r   Zrowsr   r   r   r`   r   Zemployeer   Zlast_seven_daysZemployee_transZ employee_office_transaction_datar   rh   Zvalsrg   r   itemr   rl   Zoutdoor_valsr(   r   rk   r   rJ   Zoutdoor_itemr   Zoverall_punch_historyZtempelemZfinal_punch_dataZfinal_punch_data_order_wiserX   r?   r\   r\   r]   pull_all_transaction   s    











z&BioTimeAppClockIn.pull_all_transactionc             C   s  ddl m}m}m}	m}
 ddlm} |dkrFd|}tt	dd|t
S |}t|}d\}}|dkrtt|}t|}n|d	krtd
|\}}t|}|jj|j||ddj||
|	d|dd||
|	d|dd||
|	d|dd||
|	d|dd||
|	d|ddd}|r.|d ndddddd}t|d t|d t|d t|d t|d |d}ttt|ddS )u  
        get exception summary
        @param current_day:
        @param period:            time period(1：month 2：week)
        @param source:          data source(1: IOS， 2：Android)
        @param device_token:    Token for push messag
        @param language:
        @param token:
        @rtype:
            success
                {"code":1,"error":"",""describe:"","data":{"late_count":Late times,"early_leave_count":Leave early times,
                "absent_count":Absent times,"leave_count":Leave times,"overtime_count":Overtime times,"current_day":Current day(stamp)}
            fail:
                {"code": -10001, "error": "", "describe": "exception state", "message": "Pop-up message", "data":""}
        r   )CountValueWhenCase)PayloadBase)r   rc   zperiod --> {0} error.r   ) r   )r   )rc   rd   )ra   Zatt_date__gteZatt_date__ltera   r   )Zlate__gtthen)Zearly_leave__gtr   )Z
absent__gtr   )Z	leave__gtr   )Zovertime__total_ot__gtr   )
late_countearly_leave_countabsent_countleave_countovertime_countr   r   r   r   r   )r   r   r   r   r   r   r.   )Zdjango.db.modelsr   r   r   r   rt   r   r4   r   r   r   r   r   r   r   r
   rB   rC   r$   valuesZannotateintr   r5   rQ   )rR   r   ZperiodrP   rT   rU   rV   r   r   r   r   r   r(   Zstamp_currentrZ   r[   rE   Zobj_querysetr   Z
attendancer\   r\   r]   pull_exception_summary  s<    






z(BioTimeAppClockIn.pull_exception_summaryN)__name__
__module____qualname____doc__r   r   r   r~   r^   r   r   r   r\   r\   r\   r]   r      s   * M$ r   )r   r   Zmysite.ladon.ladonizerr   r2   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r5   Zdjango.utils.translationr   r3   objectr   r\   r\   r\   r]   <module>   s
   H