Feature: Added lock date from before/after and rolling lock dates.

This commit is contained in:
Amritanshu 2013-11-26 13:55:04 +05:30
parent 7ec55eb0aa
commit 8d5d7e6601
8 changed files with 180 additions and 54 deletions

View File

@ -92,7 +92,7 @@ def main(global_config, **settings):
config.add_route('api_tag_list', '/api/Tags')
config.add_route('settings', '/Settings')
config.add_route('api_lock_date', '/api/LockDate')
config.add_route('api_lock_info', '/api/LockInfo')
add_route(config, 'attendance', '/Attendance', has_list=False, variable='date')
config.add_route('api_attendance_types', '/api/AttendanceTypes')

View File

@ -2,23 +2,76 @@
<h2>Settings</h2>
<div class="form-group">
<label for="txtLockDate" class="col-md-2 control-label">Lock Date</label>
<label class="col-md-2 control-label">Lock Dates</label>
<div class="col-md-6">
<div class="col-md-2">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="lockInfo.Start.Locked"> Lock older
</label>
</div>
</div>
<div class="col-md-2" ng-hide="!lockInfo.Start.Locked">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="lockInfo.Start.Rolling"> IsRolling
</label>
</div>
</div>
<div class="col-md-6" ng-hide="!lockInfo.Start.Locked || !lockInfo.Start.Rolling">
<div class="input-group">
<input class="form-control" id="txtLockDate" type="text" datepicker-popup="dd-MMM-yyyy"
ng-model="lockDate"/>
<input class="form-control" type="number" ng-model="lockInfo.Start.Days" placeholder="Days"/>
</div>
</div>
<div class="col-md-6" ng-hide="!lockInfo.Start.Locked || lockInfo.Start.Rolling">
<div class="input-group">
<input class="form-control" type="text" datepicker-popup="dd-MMM-yyyy"
ng-model="lockInfo.Start.Date"/>
<span class="input-group-btn">
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
<div class="col-md-2">
<button class="btn btn-block btn-primary" ng-click="setLockDate()">Set</button>
</div>
<div class="form-group">
<div class="col-md-2 col-md-offset-2">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="lockInfo.Finish.Locked"> Lock newer
</label>
</div>
</div>
<div class="col-md-2" ng-hide="!lockInfo.Finish.Locked">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="lockInfo.Finish.Rolling"> IsRolling
</label>
</div>
</div>
<div class="col-md-6" ng-hide="!lockInfo.Finish.Locked || !lockInfo.Finish.Rolling">
<div class="input-group">
<input class="form-control" type="number" ng-model="lockInfo.Finish.Days" placeholder="Days"/>
</div>
</div>
<div class="col-md-6" ng-hide="!lockInfo.Finish.Locked || lockInfo.Finish.Rolling">
<div class="input-group">
<input class="form-control" type="text" datepicker-popup="dd-MMM-yyyy"
ng-model="lockInfo.Finish.Date"/>
<span class="input-group-btn">
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-2 col-md-offset-2">
<button class="btn btn-block btn-primary" tan-click="setLockDate()">Set</button>
</div>
<div class="col-md-2">
<button class="btn btn-block btn-danger" ng-click="clearLockDate()">Clear</button>
<button class="btn btn-block btn-danger" tan-click="clearLockDate()">Clear</button>
</div>
</div>
<div class="form-group">

View File

@ -1,15 +1,27 @@
'use strict';
var SettingsCtrl = ['$scope', '$http', 'dateFilter', '$modal', 'lockDate', 'Product', function ($scope, $http, dateFilter, $modal, lockDate, Product) {
$scope.lockDate = lockDate.data['Lock Date'];
var SettingsCtrl = ['$scope', '$http', 'dateFilter', '$modal', 'lockInfo', 'Product', function ($scope, $http, dateFilter, $modal, lockInfo, Product) {
$scope.lockInfo = lockInfo.data;
$scope.rebaseDate = '';
$scope.setLockDate = function () {
if (angular.isDate($scope.lockDate)) {
$scope.lockDate = dateFilter($scope.lockDate, 'dd-MMM-yyyy');
if ($scope.lockInfo.Start.Locked) {
if ($scope.lockInfo.Start.Rolling) {
$scope.lockInfo.Start.Days = parseInt($scope.lockInfo.Start.Days, 10);
} else if (angular.isDate($scope.lockInfo.Start.Date)) {
$scope.lockInfo.Start.Date = dateFilter($scope.lockInfo.Start.Date, 'dd-MMM-yyyy');
}
}
$http({method: 'POST', url: '/api/LockDate', params: {Date: $scope.lockDate}}).
if ($scope.lockInfo.Finish.Locked) {
if ($scope.lockInfo.Finish.Rolling) {
$scope.lockInfo.Finish.Days = parseInt($scope.lockInfo.Finish.Days, 10);
} else if (angular.isDate($scope.lockInfo.Finish.Date)) {
$scope.lockInfo.Finish.Date = dateFilter($scope.lockInfo.Finish.Date, 'dd-MMM-yyyy');
}
}
return $http.post('/api/LockInfo', $scope.lockInfo).
success(function (data) {
$scope.lockDate = data['Lock Date'];
$scope.lockInfo = data;
$scope.toasts.push({Type: 'Success', Message: ''});
}).
error(function (errorMessage) {
@ -18,9 +30,9 @@ var SettingsCtrl = ['$scope', '$http', 'dateFilter', '$modal', 'lockDate', 'Prod
};
$scope.clearLockDate = function () {
$http({method: 'POST', url: '/api/LockDate', params: {Clear: ''}}).
return $http.delete('/api/LockInfo').
success(function (data) {
$scope.lockDate = data['Lock Date'];
$scope.lockInfo = data;
$scope.toasts.push({Type: 'Success', Message: ''});
}).
error(function (errorMessage) {
@ -114,8 +126,10 @@ var SettingsCtrl = ['$scope', '$http', 'dateFilter', '$modal', 'lockDate', 'Prod
}];
SettingsCtrl.resolve = {
lockDate: ['$http', function ($http) {
return $http.get('/api/LockDate', {});
lockInfo: ['$http', function ($http) {
return $http.get('/api/LockInfo', {}).then(function (data, status, headers, config) {
return data;
});
}]
};

View File

@ -13,35 +13,66 @@ def html(request):
return {}
@view_config(request_method='POST', route_name='api_lock_date', request_param='Date', renderer='json',
permission='Lock Date')
@view_config(request_method='POST', route_name='api_lock_info', renderer='json', permission='Lock Date')
@TryCatchFunction
def set_lock_date(request):
date = datetime.datetime.strptime(request.GET['Date'], '%d-%b-%Y')
lock_date = DbSetting.by_name('Lock Date')
def set_lock_info(request):
start_locked = request.json_body['Start']['Locked']
finish_locked = request.json_body['Finish']['Locked']
data = {'Start': {'Locked': start_locked}, 'Finish': {'Locked': finish_locked}}
if start_locked:
rolling = request.json_body['Start']['Rolling']
data['Start']['Rolling'] = rolling
if rolling:
data['Start']['Days'] = request.json_body['Start']['Days']
else:
data['Start']['Date'] = datetime.datetime.strptime(request.json_body['Start']['Date'], '%d-%b-%Y')
if finish_locked:
rolling = request.json_body['Finish']['Rolling']
data['Finish']['Rolling'] = rolling
if rolling:
data['Finish']['Days'] = request.json_body['Finish']['Days']
else:
data['Finish']['Date'] = datetime.datetime.strptime(request.json_body['Finish']['Date'], '%d-%b-%Y')
lock_date = DbSetting.by_name('Lock Info')
if lock_date is not None:
lock_date.data = date
lock_date.data = data
else:
lock_date = DbSetting(name='Lock Date', data=date)
lock_date = DbSetting(name='Lock Info', data=data)
DBSession.add(lock_date)
transaction.commit()
return {'Lock Date': date.strftime('%d-%b-%Y')}
return {}
@view_config(request_method='POST', route_name='api_lock_date', request_param='Clear', renderer='json',
permission='Lock Date')
@view_config(request_method='DELETE', route_name='api_lock_info', renderer='json', permission='Lock Date')
@TryCatchFunction
def clear_lock_date(request):
lock_date = DbSetting.by_name('Lock Date')
def clear_lock_info(request):
lock_date = DbSetting.by_name('Lock Info')
if lock_date is not None and lock_date.data is not None:
lock_date.data = None
transaction.commit()
return {'Lock Date': ''}
return {}
@view_config(request_method='GET', route_name='api_lock_date', renderer='json', permission='Authenticated')
def get_lock_date(request):
lock_date = DbSetting.by_name('Lock Date')
if lock_date is not None and lock_date.data is not None:
return {'Lock Date': lock_date.data.strftime('%d-%b-%Y')}
return {'Lock Date': ''}
@view_config(request_method='GET', route_name='api_lock_info', renderer='json', permission='Authenticated')
def get_lock_info(request):
data = DbSetting.by_name('Lock Info')
if data is None:
return {'Start': {'Locked': False}, 'Finish': {'Locked': False}}
data = data.data
info = {'Start': {'Locked': data['Start']['Locked']}, 'Finish': {'Locked': data['Finish']['Locked']}}
if data['Start']['Locked']:
data['Start']['Rolling'] = data['Start']['Rolling']
if data['Start']['Rolling']:
info['Start']['Days'] = data['Start']['Days']
else:
info['Start']['Date'] = data['Start']['Date'].strftime('%d-%b-%Y')
if data['Finish']['Locked']:
data['Finish']['Rolling'] = data['Finish']['Rolling']
if data['Finish']['Rolling']:
info['Finish']['Days'] = data['Finish']['Days']
else:
info['Finish']['Date'] = data['Finish']['Date'].strftime('%d-%b-%Y')
return info

View File

@ -1,13 +1,17 @@
from datetime import date, datetime, timedelta, time
import pkg_resources
from pyramid.httpexceptions import HTTPForbidden, HTTPFound
from pyramid.response import FileResponse, Response
from pyramid.view import view_config
from brewman.models.master import DbSetting
@view_config(route_name='home', renderer='brewman:templates/angular_base.mako')
@view_config(request_method='GET', route_name='login', renderer='brewman:templates/angular_base.mako')
def home(request):
return {}
@view_config(context=HTTPForbidden, renderer='brewman:templates/angular_base.mako')
def forbidden(request):
if 'X-Requested-With' in request.headers and request.headers['X-Requested-With'] == 'XMLHttpRequest':
@ -17,8 +21,31 @@ def forbidden(request):
else:
return HTTPFound(location=request.route_url('login'))
@view_config(route_name='favicon')
def favicon(request):
package, resource = 'brewman:static/favicon.ico'.split(':',1)
package, resource = 'brewman:static/favicon.ico'.split(':', 1)
icon = pkg_resources.resource_filename(package, resource)
return FileResponse(icon, request=request)
return FileResponse(icon, request=request)
def get_lock_info():
data = DbSetting.by_name('Lock Info')
if data is None:
return None, None
data = data.data
if not data['Start']['Locked']:
start = None
elif data['Start']['Rolling']:
start = datetime.combine(date.today(),time()) - timedelta(days=data['Start']['Days'])
else:
start = data['Start']['Date']
if not data['Finish']['Locked']:
finish = None
elif data['Finish']['Rolling']:
finish = datetime.combine(date.today(),time()) + timedelta(days=data['Finish']['Days'])
else:
finish = data['Finish']['Date']
return start, finish

View File

@ -269,10 +269,3 @@ def get_edit_url(request, voucher):
return request.route_url('salary_deduction_id', id=voucher.id)
else:
return '#'
def get_lock_date():
lock_date = DbSetting.by_name('Lock Date')
if lock_date is not None and lock_date.data is not None:
return lock_date.data
return None

View File

@ -6,8 +6,9 @@ import transaction
from brewman.models.auth import User
from brewman.models.validation_exception import TryCatchFunction, ValidationError
from brewman.models.voucher import Voucher
from brewman.views import get_lock_info
from brewman.views.services.session import session_current_date_set
from . import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher, get_lock_date
from . import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher
from .purchase_return import purchase_return_create_voucher
from .salary_deduction import salary_deduction_create_voucher
@ -20,7 +21,7 @@ class save_voucher(object):
self.request = request
self.user = User.by_id(uuid.UUID(authenticated_userid(request)))
self.json = request.json_body
self.lock_date = get_lock_date()
self.start, self.finish = get_lock_info()
self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
@ -59,8 +60,10 @@ class save_voucher(object):
@TryCatchFunction
def save(self):
if self.lock_date >= self.voucher_date:
raise ValidationError("Vouchers upto {0} have been locked.".format(self.lock_date.strftime('%d-%b-%Y')))
if self.start is not None and self.start > self.voucher_date:
raise ValidationError("Vouchers before {0} have been locked.".format(self.start.strftime('%d-%b-%Y')))
elif self.finish is not None and self.finish < self.voucher_date:
raise ValidationError("Vouchers after {0} have been locked.".format(self.finish.strftime('%d-%b-%Y')))
if self.json['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_create_voucher(self.json, self.user)

View File

@ -8,8 +8,9 @@ from brewman import groupfinder
from brewman.models.auth import User
from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher
from brewman.views import get_lock_info
from brewman.views.services.session import session_current_date_set
from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher, get_lock_date
from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher
from brewman.views.services.voucher.salary_deduction import salary_deduction_update_voucher
@ -23,7 +24,7 @@ class update_voucher(object):
self.user = User.by_id(uuid.UUID(authenticated_userid(request)))
self.voucher = Voucher.by_id(uuid.UUID(request.matchdict.get('id', None)))
self.json = request.json_body
self.lock_date = get_lock_date()
self.start, self.finish = get_lock_info()
self.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
@ -36,8 +37,12 @@ class update_voucher(object):
response = Response("You are not allowed to edit other user's vouchers")
response.status_int = 403
self.error = response
elif self.lock_date >= self.voucher_date or self.lock_date >= self.voucher.date:
response = Response("Vouchers upto {0} have been locked.".format(self.lock_date.strftime('%d-%b-%Y')))
elif self.start is not None and (self.start > self.voucher_date or self.start > self.voucher.date):
response = Response("Vouchers before {0} have been locked.".format(self.start.strftime('%d-%b-%Y')))
response.status_int = 403
self.error = response
elif self.finish is not None and (self.finish < self.voucher_date or self.finish < self.voucher.date):
response = Response("Vouchers after {0} have been locked.".format(self.finish.strftime('%d-%b-%Y')))
response.status_int = 403
self.error = response
else: