Added Labels to attendance showing hours worked according to fingerprint data.

Table styles made to exclude the fingerprint column.
Bumped version to 3.2
This commit is contained in:
Tanshu 2012-12-01 01:30:55 +05:30
parent 5f4e96be88
commit 9a8e504e46
8 changed files with 96 additions and 39 deletions

View File

@ -6,51 +6,42 @@
{ {
display: none; display: none;
} }
.table tbody tr.success td { .table tbody tr.Present td:not(.no-bg) {
background-color: #1F7A1F;
}
.table tbody tr.success td {
background-color: #1F7A1F;
}
.table tbody tr.Present td {
background-color: #228B22; background-color: #228B22;
} }
.table tbody tr.Off td { .table tbody tr.Off td:not(.no-bg) {
background-color: #87CEFA; background-color: #87CEFA;
} }
.table tbody tr.Leave td { .table tbody tr.Leave td:not(.no-bg) {
background-color: #CD5C5C; background-color: #CD5C5C;
} }
.table tbody tr.Absent td { .table tbody tr.Absent td:not(.no-bg) {
background-color: #CD0000; background-color: #CD0000;
} }
.table tbody tr.HalfDay td { .table tbody tr.HalfDay td:not(.no-bg) {
background-color: #98FB98; background-color: #98FB98;
} }
.table tbody tr.Double td { .table tbody tr.Double td:not(.no-bg) {
background-color: #006400; background-color: #006400;
} }
.table tbody tr.PaidLeaveAvailed td { .table tbody tr.PaidLeaveAvailed td:not(.no-bg) {
background-color: #EEEE00; background-color: #EEEE00;
} }
.table tbody tr.CasualLeaveAvailed td { .table tbody tr.CasualLeaveAvailed td:not(.no-bg) {
background-color: #800080; background-color: #800080;
} }
.table tbody tr.Overtime td { .table tbody tr.Overtime td:not(.no-bg) {
background-color: #006400; background-color: #006400;
} }
.table tbody tr.OffWorked td { .table tbody tr.OffWorked td:not(.no-bg) {
background-color: #F5DEB3; background-color: #F5DEB3;
} }
.table tbody tr.COff td { .table tbody tr.COff td:not(.no-bg) {
background-color: #F5DEB3; background-color: #F5DEB3;
} }
.table tbody tr.HalfPL td { .table tbody tr.HalfPL td:not(.no-bg) {
background-color: #FFF68F; background-color: #FFF68F;
} }
.table tbody tr.HalfCL td { .table tbody tr.HalfCL td:not(.no-bg) {
background-color: #FF00FF; background-color: #FF00FF;
} }

View File

@ -36,7 +36,9 @@
ng-options="i.AttendanceTypeID as i.Name for i in attendance_types"> </select> ng-options="i.AttendanceTypeID as i.Name for i in attendance_types"> </select>
</td> </td>
<td>{{item.Prints}}</td> <td class="no-bg">{{item.Prints}} <span ng-show="item.Hours.length > 0"
ng-class="{'label': isLabel(), 'label-success': isGood(), 'label-warning': isBad(), 'label-important': isError()}">{{item.Hours}}</span>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -40,7 +40,9 @@
ng-options="i.AttendanceTypeID as i.Name for i in attendance_types"> </select> ng-options="i.AttendanceTypeID as i.Name for i in attendance_types"> </select>
</td> </td>
<td>{{item.Prints}}</td> <td class="no-bg">{{item.Prints}} <span ng-show="item.Hours.length > 0"
ng-class="{'label': isLabel(), 'label-success': !isError(), 'label-important': isError()}">{{item.Hours}}</span>
</td>
<td> <td>
<button ng-show="isDirty()" class="btn btn-primary">Is Dirty</button> <button ng-show="isDirty()" class="btn btn-primary">Is Dirty</button>
</td> </td>

View File

@ -20,6 +20,22 @@ var AttendanceSubCtrl = ['$scope', function ($scope) {
$scope.original = {}; $scope.original = {};
angular.copy($scope.item, $scope.original); angular.copy($scope.item, $scope.original);
$scope.isLabel = function(){
return true;
}
$scope.isError = function(){
return $scope.item.Worked === 'Error';
}
$scope.isGood = function(){
return $scope.item.Worked === true;
}
$scope.isBad = function(){
return $scope.item.Worked === false;
}
$scope.isDirty = function(){ $scope.isDirty = function(){
return !angular.equals($scope.original, $scope.item) return !angular.equals($scope.original, $scope.item)
} }

View File

@ -30,6 +30,22 @@ function EmployeeAttendanceSubCtrl($scope) {
$scope.original = {}; $scope.original = {};
angular.copy($scope.item, $scope.original); angular.copy($scope.item, $scope.original);
$scope.isLabel = function(){
return true;
}
$scope.isError = function(){
return $scope.item.Worked === 'Error';
}
$scope.isGood = function(){
return $scope.item.Worked === true;
}
$scope.isBad = function(){
return $scope.item.Worked === false;
}
$scope.isDirty = function(){ $scope.isDirty = function(){
return !angular.equals($scope.original, $scope.item) return !angular.equals($scope.original, $scope.item)
} }

View File

@ -8,7 +8,8 @@ import transaction
from brewman.models import DBSession from brewman.models import DBSession
from brewman.models.master import AttendanceType, Employee from brewman.models.master import AttendanceType, Employee
from brewman.models.validation_exception import ValidationError from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Attendance, Fingerprint from brewman.models.voucher import Attendance
from brewman.views.fingerprint import get_prints
from brewman.views.services.session import session_period_start, session_period_finish, session_current_date from brewman.views.services.session import session_period_start, session_period_finish, session_current_date
__author__ = 'tanshu' __author__ = 'tanshu'
@ -57,14 +58,10 @@ def attendance_date_report(date):
Attendance.date == date).filter(Attendance.is_valid == True).first() Attendance.date == date).filter(Attendance.is_valid == True).first()
att = 0 if att is None else att.attendance_type att = 0 if att is None else att.attendance_type
start_fp = date + datetime.timedelta(hours=7) prints, hours, worked = get_prints(item.code, date)
finish_fp = date + datetime.timedelta(hours=7, days=1)
prints = DBSession.query(Fingerprint).filter(Fingerprint.employee_code == item.code)\
.filter(Fingerprint.date >= start_fp).filter(Fingerprint.date < finish_fp).order_by(Fingerprint.date).all()
prints = ', '.join([x.date.strftime('%H:%M') for x in prints])
report['Body'].append({'id': item.id, 'Code': item.code, 'Name': item.name, 'Designation': item.designation, report['Body'].append({'id': item.id, 'Code': item.code, 'Name': item.name, 'Designation': item.designation,
'Department': item.costcenter.name, 'AttendanceTypeID': att, 'Prints': prints}) 'Department': item.costcenter.name, 'AttendanceTypeID': att, 'Prints': prints,
'Hours': hours, 'Worked': worked})
return report return report
@ -124,12 +121,9 @@ def employee_attendance(employee, start_date, finish_date):
.filter(Attendance.is_valid == True)\ .filter(Attendance.is_valid == True)\
.first() .first()
att = 0 if att is None else att.attendance_type att = 0 if att is None else att.attendance_type
start_fp = item + datetime.timedelta(hours=7) prints, hours, worked = get_prints(employee.code, item)
finish_fp = item + datetime.timedelta(hours=7, days=1) list.append({'Date': item.strftime('%d-%b-%Y'), 'AttendanceTypeID': att, 'Prints': prints, 'Hours': hours,
prints = DBSession.query(Fingerprint).filter(Fingerprint.employee_code == employee.code)\ 'Worked': worked})
.filter(Fingerprint.date >= start_fp).filter(Fingerprint.date < finish_fp).order_by(Fingerprint.date).all()
prints = ', '.join([x.date.strftime('%H:%M') for x in prints])
list.append({'Date': item.strftime('%d-%b-%Y'), 'AttendanceTypeID': att, 'Prints': prints})
return list return list

View File

@ -2,6 +2,7 @@ import csv
import datetime import datetime
from io import StringIO from io import StringIO
from pyramid.view import view_config from pyramid.view import view_config
from brewman.models import DBSession
from brewman.models.voucher import Fingerprint from brewman.models.voucher import Fingerprint
__author__ = 'tanshu' __author__ = 'tanshu'
@ -34,3 +35,38 @@ def add_fingerprint(row):
except ValueError: except ValueError:
return return
Fingerprint(employee_code=employee_code, date=date).create() Fingerprint(employee_code=employee_code, date=date).create()
def get_prints(employee_code, date):
start_fp = date + datetime.timedelta(hours=7)
finish_fp = date + datetime.timedelta(hours=7, days=1)
prints = DBSession.query(Fingerprint).filter(Fingerprint.employee_code == employee_code)\
.filter(Fingerprint.date >= start_fp).filter(Fingerprint.date < finish_fp).order_by(Fingerprint.date).all()
last = None
for i in range(len(prints), 0, -1):
item = prints[i - 1].date
if last is not None and last - item < datetime.timedelta(minutes=10):
prints.remove(prints[i - 1])
else:
last = item
if len(prints) == 0:
hours = '', ''
elif len(prints) == 2:
hours = prints[1].date - prints[0].date
hours = working_hours(hours)
elif len(prints) == 4:
hours = (prints[1].date - prints[0].date) + (prints[3].date - prints[2].date)
hours = working_hours(hours)
else:
hours = 'Error', 'Error'
return ', '.join([x.date.strftime('%H:%M') for x in prints]) + ' ', hours[0], hours[1]
def working_hours(delta):
minutes = (delta.seconds // 60) % 60
minutes = int(5 * round(float(minutes) / 5))
hours = delta.seconds // 3600
worked = str(hours).zfill(2) + ':' + str(minutes).zfill(2)
return worked, delta.seconds >= 60 * 60 * 9 # 9hrs

View File

@ -16,7 +16,7 @@ requires = [
] ]
setup(name='brewman', setup(name='brewman',
version='0.0', version='3.2',
description='brewman', description='brewman',
long_description=README + '\n\n' + CHANGES, long_description=README + '\n\n' + CHANGES,
classifiers=[ classifiers=[