Added settings table to store user settings.

Added settings page, view, route and controller.
Added lock_date setting to prevent changes to voucher upto and including that date.

The sql for this update is:

CREATE TABLE settings (
	"SettingID" UUID NOT NULL,
	"Name" VARCHAR(255) NOT NULL,
	"Data" BYTEA,
	PRIMARY KEY ("SettingID"),
	UNIQUE ("Name")
);

INSERT INTO auth_roles ("RoleID", "Name") VALUES ('d52de0be-9388-4b0b-a359-7e122ab6e53a', 'Lock Date');

Signed-off-by: Tanshu <tanshu@gmail.com>
This commit is contained in:
Tanshu 2013-07-08 01:33:02 +05:30
parent 30a38f7ed9
commit d187c1ee2f
13 changed files with 176 additions and 14 deletions

@ -86,6 +86,8 @@ def main(global_config, **settings):
config.add_route('api_message', '/api/Message')
config.add_route('api_tag_list', '/api/Tags')
config.add_route('settings', '/Settings')
config.add_route('api_lock_date', '/api/LockDate')
add_route(config, 'attendance', '/Attendance', has_list=False, variable='date')

@ -13,6 +13,7 @@ def initialize_sql(engine):
# from brewman.models.voucher import Attendance, Batch, Fingerprint, Inventory, Journal, Product, SalaryDeduction, Voucher, VoucherType
# from brewman.models.master import Product, AttendanceType, CostCenter, Employee, Ledger, LedgerBase, LedgerType, ProductGroup
# from brewman.models.auth import Client, Group, Role, User, role_group, user_group
# from .master import DbSetting
DBSession.configure(bind=engine)
Base.metadata.bind = engine
# Base.metadata.create_all(engine)

@ -1,11 +1,12 @@
import uuid
from sqlalchemy import UniqueConstraint, Column, Integer, Unicode, Numeric, Boolean, ForeignKey, func, DateTime, desc
from sqlalchemy import UniqueConstraint, Column, Integer, Unicode, Numeric, Boolean, ForeignKey, func, DateTime, desc, PickleType
from sqlalchemy.orm import relationship
from brewman.models import Base, DBSession
from brewman.models.guidtype import GUID
__author__ = 'tanshu'
class Product(Base):
__tablename__ = 'entities_products'
__tableagrs__ = (UniqueConstraint('Name', 'Units'))
@ -267,7 +268,7 @@ class Employee(LedgerBase):
self.joining_date = joining_date
self.leaving_date = leaving_date
super().__init__(code=code, name=name, type=10, is_active=is_active, is_reconcilable=False,
costcenter_id=costcenter_id)
costcenter_id=costcenter_id)
def create(self):
code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0]
@ -383,4 +384,31 @@ class LedgerType:
list = cls.list()
for item in list:
if item.id == id:
return item
return item
class DbSetting(Base):
__tablename__ = 'settings'
id = Column('SettingID', GUID(), primary_key=True, default=uuid.uuid4)
name = Column('Name', Unicode(255), unique=True, nullable=False)
data = Column('Data', PickleType)
def __init__(self, id=None, name=None, data=None):
self.id = id
self.name = name
self.data = data
@classmethod
def by_id(cls, id):
if not isinstance(id, uuid.UUID):
id = uuid.UUID(id)
return DBSession.query(cls).filter(cls.id == id).first()
@classmethod
def by_name(cls, name):
return DBSession.query(cls).filter(cls.name == name).first()
@classmethod
def list(cls):
return DBSession.query(cls).order_by(cls.name).all()

@ -1,6 +1,6 @@
CACHE MANIFEST
# version 2013-06-24.1
# version 2013-06-30.1
CACHE:
/partial/404.html

@ -0,0 +1,12 @@
<form method="post" autocomplete="off" class="form-horizontal">
<legend>Settings</legend>
<div class="control-group">
<label for="txtLockDate" class="control-label">Lock Date</label>
<div class="controls">
<datepicker id="txtLockDate" model="lockDate" ng-model="lockDate"></datepicker>
<button class="btn btn-primary" ng-click="setLockDate()">Set</button>
<button class="btn btn-danger" ng-click="clearLockDate()">Clear</button>
</div>
</div>
</form>

@ -11,6 +11,13 @@ var HomeCtrl = ['$scope', '$location', 'messages', 'Message', function ($scope,
$scope.chosen = result.Type;
});
}
$scope.getTags = function (tag) {
Message.query({type: $scope.Type, tag: tag}, function (result) {
$scope.info = result.Threads;
$scope.tags = result.Tags;
$scope.chosen = result.Type;
});
}
}];
HomeCtrl.resolve = {
messages: ['$q', '$route', 'Message', function ($q, $route, Message) {

@ -92,6 +92,8 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
when('/Message', {templateUrl: '/partial/message-detail.html', controller: MessageCtrl, resolve: MessageCtrl.resolve}).
when('/Message/:id', {templateUrl: '/partial/message-detail.html', controller: MessageCtrl, resolve: MessageCtrl.resolve}).
when('/Settings', {templateUrl: '/partial/settings.html', controller: SettingsCtrl, resolve: SettingsCtrl.resolve}).
otherwise({templateUrl: '/partial/404.html'});
$locationProvider.html5Mode(true).hashPrefix('!');
}])

@ -0,0 +1,32 @@
'use strict';
var SettingsCtrl = ['$scope', '$http', 'lockDate', function ($scope, $http, lockDate) {
$scope.lockDate = lockDate.data['Lock Date'];
$scope.setLockDate = function () {
$http({method: 'POST', url: '/api/LockDate', params: {Date: $scope.lockDate}}).
success(function (data) {
$scope.lockDate = data['Lock Date'];
$scope.toasts.push({Type: 'Success', Message: ''});
}).
error(function (errorMessage) {
$scope.toasts.push({Type: 'Error', Message: errorMessage});
});
};
$scope.clearLockDate = function () {
$http({method: 'POST', url: '/api/LockDate', params: {Clear: ''}}).
success(function (data) {
$scope.lockDate = data['Lock Date'];
$scope.toasts.push({Type: 'Success', Message: ''});
}).
error(function (errorMessage) {
$scope.toasts.push({Type: 'Error', Message: errorMessage});
});
};
}]
SettingsCtrl.resolve = {
lockDate: ['$http', function ($http) {
return $http.get('/api/LockDate', {});
}]
};

@ -40,6 +40,7 @@
<script src="/script/growl-service.js"></script>
<script src="/script/home.js"></script>
<script src="/script/login.js"></script>
<script src="/script/settings.js"></script>
<script src="/script/message.js"></script>
<script src="/script/journal.js"></script>
@ -179,7 +180,7 @@
<li><a href="/Users">Users</a></li>
<li><a href="/Groups">Groups</a></li>
<li><a href="/Clients">Clients</a></li>
<li><a href="/AccountsTesting/Maintenance/Split.aspx">Split Data</a></li>
<li><a href="/Settings">Settings</a></li>
</ul>
</li>
<ul class="nav" ng-hide="auth.isAuthenticated">

@ -7,12 +7,12 @@ import transaction
from brewman import groupfinder
from brewman.models import DBSession
from brewman.models.auth import User
from brewman.models.master import LedgerBase, CostCenter
from brewman.models.master import LedgerBase, CostCenter, DbSetting
from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher, VoucherType, Batch, Inventory
from brewman.views.services.voucher.issue import issue_create_voucher, issue_update_voucher
from brewman.views.services.voucher.journal import journal_update_voucher, journal_create_voucher
from brewman.views.services.voucher.purchase import purchase_create_voucher, purchase_update_voucher
from .issue import issue_create_voucher, issue_update_voucher
from .journal import journal_update_voucher, journal_create_voucher
from .purchase import purchase_create_voucher, purchase_update_voucher
__author__ = 'tanshu'
@ -54,6 +54,9 @@ def journal_get(request):
def voucher_post(request):
user = User.by_id(uuid.UUID(authenticated_userid(request)))
voucher = Voucher.by_id(uuid.UUID(request.matchdict['id']))
lock_date = get_lock_date()
if lock_date >= voucher.date:
raise ValidationError("Vouchers upto {0} have been locked.".format(lock_date.strftime('%d-%b-%Y')))
voucher.posted = True
voucher.poster_id = user.id
transaction.commit()
@ -76,6 +79,12 @@ def check_delete_permissions(request, voucher):
response = Response("You are not allowed (0) vouchers".format(VoucherType.by_id(voucher.type).name))
response.status_int = 403
return response
lock_date = get_lock_date()
if lock_date >= voucher.date:
response = Response("Vouchers upto {0} have been locked.".format(lock_date.strftime('%d-%b-%Y')))
response.status_int = 403
return response
@view_config(request_method='DELETE', route_name='api_voucher_id', renderer='json')
@ -245,3 +254,9 @@ def get_edit_url(request, voucher):
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

@ -1,14 +1,15 @@
import datetime
import uuid
from pyramid.security import authenticated_userid
from pyramid.view import view_defaults, view_config
import transaction
from brewman.models.auth import User
from brewman.models.validation_exception import TryCatchFunction
from brewman.models.validation_exception import TryCatchFunction, ValidationError
from brewman.models.voucher import Voucher
from brewman.views.services.session import session_current_date_set
from brewman.views.services.voucher import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher
from brewman.views.services.voucher.purchase_return import purchase_return_create_voucher
from brewman.views.services.voucher.salary_deduction import salary_deduction_create_voucher
from . import voucher_info, journal_create_voucher, purchase_create_voucher, issue_create_voucher, get_lock_date
from .purchase_return import purchase_return_create_voucher
from .salary_deduction import salary_deduction_create_voucher
__author__ = 'tanshu'
@ -19,6 +20,9 @@ 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.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
@view_config(request_param='type=Journal', permission='Journal')
def journal(self):
@ -55,6 +59,9 @@ 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.json['Type'] in ['Journal', 'Payment', 'Receipt']:
voucher = journal_create_voucher(self.json, self.user)
elif self.json['Type'] in ['Purchase']:

@ -1,3 +1,4 @@
import datetime
import uuid
from pyramid.response import Response
from pyramid.security import authenticated_userid
@ -8,7 +9,7 @@ from brewman.models.auth import User
from brewman.models.validation_exception import ValidationError, TryCatchFunction
from brewman.models.voucher import Voucher
from brewman.views.services.session import session_current_date_set
from brewman.views.services.voucher import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher
from . import voucher_info, issue_update_voucher, purchase_update_voucher, journal_update_voucher, get_lock_date
from brewman.views.services.voucher.purchase_return import purchase_return_update_voucher
from brewman.views.services.voucher.salary_deduction import salary_deduction_update_voucher
@ -22,6 +23,9 @@ 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.voucher_date = datetime.datetime.strptime(self.json['Date'], '%d-%b-%Y')
permissions = groupfinder(self.user.id, self.request)
if self.voucher.posted and not 'Edit Posted Vouchers' in permissions:
@ -32,6 +36,10 @@ 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')))
response.status_int = 403
self.error = response
else:
self.error = None

@ -0,0 +1,47 @@
import datetime
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.master import DbSetting
from brewman.models.validation_exception import TryCatchFunction
@view_config(route_name='settings', renderer='brewman:templates/angular_base.mako', permission='Authenticated')
def html(request):
return {}
@view_config(request_method='POST', route_name='api_lock_date', request_param='Date', 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')
if lock_date is not None:
lock_date.data = date
else:
lock_date = DbSetting(name='Lock Date', data=date)
DBSession.add(lock_date)
transaction.commit()
return {'Lock Date': date.strftime('%d-%b-%Y')}
@view_config(request_method='POST', route_name='api_lock_date', request_param='Clear', renderer='json',
permission='Lock Date')
@TryCatchFunction
def clear_lock_date(request):
lock_date = DbSetting.by_name('Lock Date')
if lock_date is not None and lock_date.data is not None:
lock_date.data = None
transaction.commit()
return {'Lock Date': ''}
@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': ''}