Employee list/add/edit done.

This commit is contained in:
Tanshu 2012-10-17 13:27:14 +05:30
parent 83a87c799d
commit f627fb1303
12 changed files with 268 additions and 202 deletions

View File

@ -1,5 +1,5 @@
import uuid
from sqlalchemy import UniqueConstraint, Column, Integer, Unicode, Numeric, Boolean, ForeignKey, func, DateTime
from sqlalchemy import UniqueConstraint, Column, Integer, Unicode, Numeric, Boolean, ForeignKey, func, DateTime, desc
from sqlalchemy.orm import relationship
from brewman.models import Base, DBSession
from brewman.models.guidtype import GUID
@ -26,7 +26,6 @@ class Product(Base):
batches = relationship('Batch', backref='product')
inventories = relationship('Inventory', backref='product')
ledger = relationship('Ledger', primaryjoin="Ledger.id==Product.ledger_id")
def __init__(self, code=None, name=None, units=None, fraction=None, fraction_units=None, yeild=None,
@ -247,14 +246,14 @@ class Employee(LedgerBase):
attendances = relationship('Attendance', backref='employe', cascade=None, cascade_backrefs=False)
def __init__(self, code=None, name=None, type=None, parent_ledger_id=None, is_active=None, costcenter_id=None,
designation=None, salary=None, service_points=None, joining_date=None, leaving_date=None):
def __init__(self, code=None, name=None, is_active=None, costcenter_id=None, designation=None, salary=None,
service_points=None, joining_date=None, leaving_date=None):
self.designation = designation
self.salary = salary
self.service_points = service_points
self.joining_date = joining_date
self.leaving_date = leaving_date
super().__init__(code, name, type, parent_ledger_id, is_active, costcenter_id)
super().__init__(code, name, 10, is_active, costcenter_id)
def create(self):
code = DBSession.query(func.max(LedgerBase.code)).filter(LedgerBase.type == self.type).one()[0]
@ -266,6 +265,11 @@ class Employee(LedgerBase):
DBSession.add(self)
return self
@classmethod
def list(cls):
return DBSession.query(Employee).order_by(desc(Employee.is_active)).order_by(Ledger.costcenter_id).order_by(
Employee.designation).order_by(Employee.name).all()
class Ledger(LedgerBase):
__mapper_args__ = {'polymorphic_identity': ''}

View File

@ -1,52 +1,52 @@
<form method="post" class="form-horizontal" ng-controller="AccountCtrl">
<legend>Account Detail</legend>
<div class="control-group">
<label for="txtCode" class="control-label">Code</label>
<form method="post" class="form-horizontal" ng-controller="AccountCtrl">
<legend>Account Detail</legend>
<div class="control-group">
<label for="txtCode" class="control-label">Code</label>
<div class="controls">
<input type="text" id="txtCode" class="non-search-box" disabled="disabled" ng-model="account.Code"/>
</div>
<div class="controls">
<input type="text" id="txtCode" class="non-search-box" disabled="disabled" ng-model="account.Code"/>
</div>
<div class="control-group">
<label for="txtName" class="control-label">Name</label>
</div>
<div class="control-group">
<label for="txtName" class="control-label">Name</label>
<div class="controls">
<input type="text" id="txtName" ng-model="account.Name"/>
</div>
<div class="controls">
<input type="text" id="txtName" ng-model="account.Name"/>
</div>
</div>
<div class="control-group">
<label for="ddlType" class="control-label">Type</label>
<div class="control-group">
<label for="ddlType" class="control-label">Type</label>
<div class="controls">
<select id="ddlType" class="select-box" ng-model="account.Type"
ng-options="l.AccountTypeID as l.Name for l in account_types"> </select>
<div class="controls">
<select id="ddlType" class="select-box" ng-model="account.Type"
ng-options="l.AccountTypeID as l.Name for l in account_types"> </select>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" ng-model="account.IsActive"> Is Active
</label>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" ng-model="account.IsActive"> Is Active
</label>
</div>
</div>
<div class="control-group">
<label for="ddlCostCenter" class="control-label">Cost Center</label>
<div class="control-group">
<label for="ddlCostCenter" class="control-label">Cost Center</label>
<div class="controls">
<select id="ddlCostCenter" class="select-box" ng-model="account.CostCenter.CostCenterID"
ng-options="l.CostCenterID as l.Name for l in cost_centers"> </select>
<div class="controls">
<select id="ddlCostCenter" class="select-box" ng-model="account.CostCenter.CostCenterID"
ng-options="l.CostCenterID as l.Name for l in cost_centers"> </select>
</div>
</div>
</div>
<div class=" control-group" id="add">
<div class=" control-group" id="add">
<div class="controls">
<button ng-click="save()">Save</button>
</div>
<div class="controls">
<button ng-click="save()">Save</button>
</div>
</form>
</div>
</form>

View File

@ -0,0 +1,77 @@
<form method="post" class="form-horizontal" ng-controller="EmployeeCtrl">
<legend>Employee Detail</legend>
<div class="control-group">
<label for="txtCode" class="control-label">Code</label>
<div class="controls">
<input type="text" id="txtCode" class="non-search-box" disabled="disabled" ng-model="employee.Code"/>
</div>
</div>
<div class="control-group">
<label for="txtName" class="control-label">Name</label>
<div class="controls">
<input type="text" id="txtName" ng-model="employee.Name"/>
</div>
</div>
<div class="control-group">
<label for="txtDesignation" class="control-label">Designation</label>
<div class="controls">
<input type="text" id="txtDesignation" ng-model="employee.Designation"/>
</div>
</div>
<div class="control-group">
<label for="txtSalary" class="control-label">Salary</label>
<div class="controls">
<input type="text" id="txtSalary" ng-model="employee.Salary"/>
</div>
</div>
<div class="control-group">
<label for="txtServicePoints" class="control-label">Service Points</label>
<div class="controls">
<input type="text" id="txtServicePoints" ng-model="employee.ServicePoints"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" ng-model="employee.IsActive"> Is Active
</label>
</div>
</div>
<div class="control-group">
<label for="ddlCostCenter" class="control-label">Cost Center</label>
<div class="controls">
<select id="ddlCostCenter" class="select-box" ng-model="employee.CostCenter.CostCenterID"
ng-options="l.CostCenterID as l.Name for l in cost_centers"> </select>
</div>
</div>
<div class="control-group">
<label for="txtJoiningDate" class="control-label">Joining Date</label>
<div class="controls">
<datepicker id="txtJoiningDate" model="employee" prop="JoiningDate" ng-model="employee.JoiningDate"></datepicker>
</div>
</div>
<div class="control-group" ng-hide="employee.IsActive">
<label for="txtLeavingDate" class="control-label">Leaving Date</label>
<div class="controls">
<datepicker id="txtLeavingDate" model="employee" prop="LeavingDate" ng-model="employee.LeavingDate"></datepicker>
</div>
</div>
<div class=" control-group" id="add">
<div class="controls">
<button ng-click="save()">Save</button>
</div>
</div>
</form>

View File

@ -0,0 +1,28 @@
<legend>Employees <a href="/Employee" class="btn btn-success pull-right">Add <i class="icon-plus icon-white"></i></a>
</legend>
<table id="gvGrid" class="clean-table">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Designation</th>
<th>Salary</th>
<th>Service Points</th>
<th>Department</th>
<th>Joining Date</th>
<th>Leaving Date</th>
</tr>
</thead>
<tbody id="tbodyMain">
<tr ng-repeat="item in info">
<td>{{item.Code}}</td>
<td><a href="{{item.Url}}">{{item.Name}}</a></td>
<td>{{item.Designation}}</td>
<td>{{item.Salary}}</td>
<td>{{item.ServicePoints}}</td>
<td>{{item.CostCenter}}</td>
<td>{{item.JoiningDate}}</td>
<td>{{item.LeavingDate}}</td>
</tr>
</tbody>
</table>

View File

@ -21,6 +21,14 @@ overlord_service.factory('Account', ['$resource', function ($resource) {
});
}]);
// TODO: Replace hardcoded url with route_url
overlord_service.factory('Employee', ['$resource', function ($resource) {
return $resource('/Employee/:id',
{id:'@LedgerID'}, {
query:{method:'GET', params:{list:true}, isArray:true}
});
}]);
// TODO: Replace hardcoded url with route_url
overlord_service.factory('Ledger', ['$resource', function ($resource) {
return $resource('/Ledger/:id');

View File

@ -0,0 +1,29 @@
function EmployeeListCtrl($scope, Employee) {
$scope.info = Employee.query();
}
function EmployeeCtrl($scope, $routeParams, $location, Employee, CostCenter) {
$scope.employee = Employee.get({id: $routeParams.id});
$scope.cost_centers = CostCenter.query();
$scope.save = function () {
$scope.employee.$save(function (u, putResponseHeaders) {
$scope.toasts.push({Type:'Success', Message:u.Code});
$location.path('/Employees')
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});
};
$scope.delete = function () {
$scope.employee.$delete(function (u, putResponseHeaders) {
$scope.toasts.push({Type:'Success', Message:''});
$location.path('/Employees')
}, function (data, status) {
$scope.toasts.push({Type:'Error', Message:data.data});
});
};
$('#txtName').focus();
}

View File

@ -42,6 +42,10 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
when('/Account', {templateUrl:'/partial/account-detail.html', controller:AccountCtrl}).
when('/Account/:id', {templateUrl:'/partial/account-detail.html', controller:AccountCtrl}).
when('/Employees', {templateUrl:'/partial/employee-list.html', controller:EmployeeListCtrl}).
when('/Employee', {templateUrl:'/partial/employee-detail.html', controller:EmployeeCtrl}).
when('/Employee/:id', {templateUrl:'/partial/employee-detail.html', controller:EmployeeCtrl}).
when('/CostCenters', {templateUrl:'/partial/cost-center-list.html', controller:CostCenterListCtrl}).
when('/CostCenter', {templateUrl:'/partial/cost-center-detail.html', controller:CostCenterCtrl}).
when('/CostCenter/:id', {templateUrl:'/partial/cost-center-detail.html', controller:CostCenterCtrl}).

View File

@ -46,6 +46,7 @@
${h.ScriptLink(request, 'unposted.js')}
${h.ScriptLink(request, 'account.js')}
${h.ScriptLink(request, 'employee.js')}
${h.ScriptLink(request, 'user.js')}
${h.ScriptLink(request, 'cost-center.js')}
${h.ScriptLink(request, 'product.js')}

View File

@ -1,44 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
metal:use-macro="base">
<tal:block metal:fill-slot="content">
<article tal:attributes="class pagecontentclass">
<section>
<h2 class="ribbon-header">Cost Centers</h2>
<table id="gvGrid" class="clean-table">
<thead>
<tr>
<th class="LedgerID hide">LedgerID</th>
<th class="Code hide">Code</th>
<th class="Name">Name</th>
<th class="Designation">Designation</th>
<th class="IsActive">Is Active?</th>
<th class="CostCenterID hide">CostCenterID</th>
<th class="CostCenter">Cost Center</th>
<th class="JoiningDate">Joining Date</th>
<th class="LeavingDate">Leaving Date</th>
</tr>
</thead>
<tbody id="tbodyMain">
<tr tal:repeat="item list">
<td class="LedgerID hide">${item.id}</td>
<td class="Code hide">${item.code}</td>
<td class="Name"><a href="${request.route_url('employee_id', id=item.id)}">${item.name}</a></td>
<td class="Designation">${item.designation}</td>
<td class="IsActive">${item.is_active}</td>
<td class="CostCenterID hide">${item.costcenter_id}</td>
<td class="CostCenter">${item.costcenter.name}</td>
<td class="JoiningDate">${'' if item.joining_date is None else item.joining_date.strftime('%d-%b-%Y')}</td>
<td class="LeavingDate">${'' if item.leaving_date is None else item.leaving_date.strftime('%d-%b-%Y')}</td>
</tr>
</tbody>
<tfoot id="tfootMain">
</tfoot>
</table>
</section>
</article>
<!-- /Page content -->
</tal:block>
</html>

View File

@ -1,8 +1,7 @@
<ul class="nav">
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Employees <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="${request.route_url('employee_list')}">List</a></li>
<li><a href="${request.route_url('employee')}">Add</a></li>
<li><a href="${request.route_url('employee_list')}">Employees</a></li>
<li><a href="${request.route_url('attendance')}">Attendance</a></li>
<li><a href="${request.route_url('employee_attendance')}">Employee Attendance</a></li>
<li><a href="/AccountsTesting/Employees/AttendanceRecord.aspx">Attendance Record</a></li>

View File

@ -1,60 +0,0 @@
import transaction
from brewman.models import DBSession
from pyramid.view import view_config
from pyramid.response import Response
from brewman.views.top_parts import slidernivo, breadcrumb, slider3d, slideraccordion, slidercarousel, sliderstatic, randomslider
from brewman.views.widgets import footer, widget_gallery, tweets, contact_widget, archive, categories, recent_posts, comments, blog_roll, events
@view_config(route_name='blog', renderer='brewman:templates/blog.pt')
def blog(request):
return {'title':'Hops n Grains - Blog',
'pageclass': "page-blog page-sidebar-right",
'pagecontentclass': "page-content grid_8",
'top_block': breadcrumb(request, "Blog", "A lot of interesting articles."),
'widget1': tweets(request),
'wid1': "grid_4",
'widget2': categories(request),
'wid2': "grid_4",
'widget3': contact_widget(request),
'wid3': "grid_4",
'widget_comments': events(request),
'widget_categories': categories(request),
'widget_gallery': widget_gallery(request),
'widget_archive': archive(request),
'widget_blog_roll': blog_roll(request),
'footer': footer(request)}
@view_config(route_name='blog_post', renderer='brewman:templates/blog_post.pt')
def blog_post(request):
id = int(request.matchdict['id'])
dbsession = DBSession()
article = dbsession.query(Article).filter(Article.id==id).one()
return {'title':'Hops n Grains - Blog',
'pageclass': "page-blogpost page-sidebar-right",
'pagecontentclass': "page-content grid_8",
'article': article,
'top_block': breadcrumb(request, "Blog post", "This page shows you a blog post example."),
'widget1': tweets(request),
'wid1': "grid_4",
'widget2': categories(request),
'wid2': "grid_4",
'widget3': contact_widget(request),
'wid3': "grid_4",
'footer': footer(request)}
@view_config(route_name='blog_add', renderer='brewman:templates/blog_add.pt')
def blog_add(request):
return {'title':'Hops n Grains - Blog',
'pageclass': "page-blogpost page-sidebar-right",
'pagecontentclass': "page-content grid_8",
'top_block': breadcrumb(request, "Blog post", "This page shows you a blog post example."),
'widget1': tweets(request),
'wid1': "grid_4",
'widget2': categories(request),
'wid2': "grid_4",
'widget3': contact_widget(request),
'wid3': "grid_4",
'footer': footer(request)}

View File

@ -1,7 +1,6 @@
import datetime
import uuid
from pyramid.httpexceptions import HTTPFound
from pyramid.renderers import render
from pyramid.security import authenticated_userid
from pyramid.view import view_config
@ -10,80 +9,101 @@ import transaction
from brewman.helpers import Literal
from brewman.models import DBSession
from brewman.models.master import CostCenter, Employee, AttendanceType, LedgerType
from brewman.models.master import CostCenter, Employee, AttendanceType
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Attendance
@view_config(request_method='GET', route_name='employee_id', renderer='brewman:templates/employee/edit.pt',
@view_config(route_name='employee_list', renderer='brewman:templates/angular_base.mako')
@view_config(request_method='GET', route_name='employee_id', renderer='brewman:templates/angular_base.mako', xhr=False,
permission='EmployeesUpdate')
@view_config(request_method='GET', route_name='employee', renderer='brewman:templates/employee/edit.pt',
permission='EmployeesCreate')
def employee_edit(request):
id = request.matchdict.get('id', None)
if id is None:
item = Employee('(Auto)', '')
else:
item = Employee.by_id(uuid.UUID(id))
print(item.code)
return {'title': 'Edit / Add Employee',
'pageclass': "page-blogpost page-sidebar-right",
'pagecontentclass': "page-content grid_12",
'page_header': '',
'item': item,
'types': LedgerType.list(),
'cost_centers': CostCenter.list()}
@view_config(request_method='GET', route_name='employee', renderer='brewman:templates/angular_base.mako', xhr=False,
permission='EmployeesUpdate')
def html(request):
return {}
@view_config(request_method='POST', route_name='employee_id', permission='EmployeesUpdate')
@view_config(request_method='POST', route_name='employee', permission='EmployeesCreate')
def employee_submit(request):
@view_config(request_method='POST', route_name='employee_id', renderer='json', xhr=True, permission='EmployeesUpdate')
@view_config(request_method='POST', route_name='employee', renderer='json', xhr=True, permission='EmployeesUpdate')
def save_update(request):
try:
id = request.matchdict.get('id', None)
if id is None:
is_active = True if request.POST.has_key('is_active') else False
joining_date = datetime.datetime.strptime(request.POST['joining_date'], '%d-%b-%Y')
leaving_date = None if is_active else datetime.datetime.strptime(request.POST['leaving_date'], '%d-%b-%Y')
Employee(0, request.POST['name'], 10, None, is_active, uuid.UUID(request.POST['cost_center_id']),
request.POST['designation'], int(request.POST['salary']), int(request.POST['service_points']),
is_active = request.json_body['IsActive']
joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
leaving_date = None if is_active else datetime.datetime.strptime(request.json_body['LeavingDate'],
'%d-%b-%Y')
item = Employee(0, request.json_body['Name'], is_active, uuid.UUID(request.json_body['CostCenter']['CostCenterID']),
request.json_body['Designation'], int(request.json_body['Salary']), int(request.json_body['ServicePoints']),
joining_date, leaving_date).create()
request.session.flash('Employee created')
else:
item = Employee.by_id(uuid.UUID(id))
item.name = request.POST['name']
item.is_active = True if request.POST.has_key('is_active') else False
item.costcenter_id = uuid.UUID(request.POST['cost_center_id'])
item.designation = request.POST['designation']
item.salary = int(request.POST['salary'])
item.service_points = int(request.POST['service_points'])
item.joining_date = datetime.datetime.strptime(request.POST['joining_date'], '%d-%b-%Y')
item.leaving_date = None if item.is_active else datetime.datetime.strptime(request.POST['leaving_date'],
item.name = request.json_body['Name']
item.is_active = request.json_body['IsActive']
item.costcenter_id = uuid.UUID(request.json_body['CostCenter']['CostCenterID'])
item.designation = request.json_body['Designation']
item.salary = int(request.json_body['Salary'])
item.service_points = int(request.json_body['ServicePoints'])
item.joining_date = datetime.datetime.strptime(request.json_body['JoiningDate'], '%d-%b-%Y')
item.leaving_date = None if item.is_active else datetime.datetime.strptime(request.json_body['LeavingDate'],
'%d-%b-%Y')
request.session.flash('Employee Updated')
transaction.commit()
url = request.route_url('employee_list')
return HTTPFound(location=url)
return employee_info(item.id)
except ValidationError as ex:
request.session.flash(ex)
transaction.abort()
request.session.flash(ex.message)
return request
response = Response("Failed validation: {0}".format(ex.message))
response.status_int = 500
return response
@view_config(route_name='employee_list', renderer='brewman:templates/employee/list.pt', permission='Employees')
def employee_list(request):
dbsession = DBSession()
list = dbsession.query(Employee)\
.order_by(Employee.leaving_date)\
.order_by(Employee.costcenter_id)\
.order_by(Employee.designation)\
.order_by(Employee.name)\
.all()
@view_config(request_method='DELETE', route_name='employee_id', renderer='json', xhr=True)
def delete(request):
id = request.matchdict.get('id', None)
if id is None:
response = Response("Employee is Null")
response.status_int = 500
return response
else:
response = Response("Employee deletion not implemented")
response.status_int = 500
return response
@view_config(request_method='GET', route_name='employee_id', renderer='json', xhr=True)
@view_config(request_method='GET', route_name='employee', renderer='json', xhr=True)
def show(request):
list = request.GET.get('list', None)
if list:
list = Employee.list()
ledgers = []
for item in list:
ledgers.append(
{'Code': item.code, 'Name': item.name, 'Designation': item.designation, 'Salary': item.salary,
'ServicePoints': item.service_points, 'IsActive': item.is_active,
'CostCenter': item.costcenter.name, 'Url': request.route_url('employee_id', id=item.id),
'JoiningDate': item.joining_date.strftime('%d-%b-%Y'),
'LeavingDate': '' if item.is_active else item.leaving_date.strftime('%d-%b-%Y')})
return ledgers
else:
id = request.matchdict.get('id', None)
id = None if id is None else uuid.UUID(id)
return employee_info(id)
def employee_info(id):
if id is None:
employee = {'Code': '(Auto)', 'IsActive': True, 'CostCenter': CostCenter.overall()}
else:
employee = Employee.by_id(id)
employee = {'LedgerID': employee.id, 'Code': employee.code, 'Name': employee.name,
'IsActive': employee.is_active, 'Designation': employee.designation, 'Salary': employee.salary,
'ServicePoints': employee.service_points, 'JoiningDate': employee.joining_date.strftime('%d-%b-%Y'),
'LeavingDate': None if employee.is_active else employee.leaving_date.strftime('%d-%b-%Y'),
'CostCenter': {'CostCenterID': employee.costcenter_id, 'Name': employee.costcenter.name}}
return employee
return {'title': 'Employees',
'pageclass': "page-blogpost page-sidebar-right",
'pagecontentclass': "page-content grid_12",
'page_header': '',
'list': list}
@view_config(request_method='GET', route_name='attendance_date', renderer='brewman:templates/employee/attendance.pt',