Initial commit

This commit is contained in:
zhugl
2015-07-30 13:01:42 +08:00
commit dfe9774fb1
122 changed files with 12088 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
default_app_config = 'basedata.apps.BaseDataConfig'
+339
View File
@@ -0,0 +1,339 @@
# coding=utf-8
from django.contrib import admin
from django.forms import models
from django.forms import fields,TextInput,Textarea
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.generic import GenericTabularInline
from common import generic
from basedata.models import ValueList,ValueListItem,Address,Partner,BankAccount,Project,Measure,Material,Brand,\
Category,Warehouse,TechnicalParameterName,TechnicalParameterValue,Trade,ExpenseAccount,Employee,Family,Education,\
WorkExperience,ExtraParam,DataImport,Document
class ValueListItemInline(admin.TabularInline):
model = ValueListItem
exclude = ['group_code']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class ValueListAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 3
CODE_PREFIX = 'S'
list_display = ['code', 'name', 'module', 'status']
fields = (('code',),('name',),('module',),('status','init','locked',),('locked_by','lock_time',))
raw_id_fields = ['module']
readonly_fields = ['locked_by','lock_time']
inlines = [ValueListItemInline]
search_fields = ['code','name']
def save_model(self, request, obj, form, change):
super(ValueListAdmin,self).save_model(request,obj,form,change)
obj.valuelistitem_set.update(group_code=obj.code)
class AddressAdmin(generic.BOAdmin):
list_display = ['address','phone','contacts']
exclude = ['content_type','object_id','creator','modifier','creation','modification','begin','end']
class AddressInline(GenericTabularInline):
model = Address
exclude = ['content_type','object_id','creator','modifier','creation','modification','begin','end']
extra = 1
class BankAccountInline(admin.TabularInline):
model = BankAccount
fields = ['account','title','memo']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class PartnerForm(models.ModelForm):
tax_address = fields.CharField(widget=TextInput(attrs={'size': 119,}),required=False,label=_("tax address"))
memo = fields.CharField(widget=Textarea(attrs={'rows':3,'cols':85}),required=False,label=_("memo"))
class Meta:
model = Partner
fields = '__all__'
class PartnerAdmin(generic.BOAdmin):
list_display = ['code','name','partner_type','level']
list_display_links = ['code','name']
fields = (('code','name',),('short','pinyin',),('partner_type','level'),('tax_num','tax_account',),
('tax_address',),('contacts','phone',),('memo',),)
search_fields = ['code','name','pinyin']
form = PartnerForm
save_on_top = True
inlines = [AddressInline,BankAccountInline]
def get_queryset(self, request):
if request.user.is_superuser or (request.user.has_perm('basedate.view_all_customer') and request.user.has_perm('basedate.view_all_supplier')):
return super(PartnerAdmin,self).get_queryset(request)
elif request.user.has_perm('basedata.view_all_customer'):
return super(PartnerAdmin,self).get_queryset(request).filter(partner_type='C')
else:
return super(PartnerAdmin,self).get_queryset(request).filter(partner_type='S')
class ProjectForm(models.ModelForm):
income = fields.DecimalField(required=False,widget=TextInput(attrs={'readonly':'true'}))
expand = fields.DecimalField(required=False,widget=TextInput(attrs={'readonly':'true'}))
class Meta:
model = Project
fields = '__all__'
class ProjectAdmin(generic.BOAdmin):
CODE_PREFIX = 'PJ'
list_display = ['code','name','status','income','expand']
list_display_links = ['code','name']
fields = (
('code','name',),('short','pinyin',),
('partner',),('status','prj_type',),
('description',),
('budget','income','expand',),('blueprint',),('offer',),('business',),('users',),
)
search_fields = ['code','name']
readonly_fields = ['status']
raw_id_fields = ['partner']
filter_horizontal = ['users']
form = ProjectForm
class WarehouseAdmin(admin.ModelAdmin):
list_display = ['code','name','location']
filter_horizontal = ['users']
def save_model(self, request, obj, form, change):
super(WarehouseAdmin,self).save_model(request,obj,form,change)
try:
code = getattr(obj,'code')
if not code:
obj.code = '%s%02d' % ('A',obj.id)
obj.save()
except Exception,e:
self.message_user(request,'ERROR:%s' % e,level=messages.ERROR)
class BrandAdmin(admin.ModelAdmin):
list_display = ['name','pinyin']
class MeasureAdmin(admin.ModelAdmin):
list_display = ['code','name','status']
class CategoryAdmin(admin.ModelAdmin):
list_display = ['code','name','path']
def save_model(self, request, obj, form, change):
super(CategoryAdmin,self).save_model(request,obj,form,change)
try:
code = getattr(obj,'code')
if not code:
obj.code = '%s%02d' % ('F',obj.id)
obj.save()
if obj.parent:
if obj.parent.path:
obj.path = obj.parent.path + '/'+obj.parent.name
else:
obj.path = obj.parent.name
obj.save()
except Exception,e:
self.message_user(request,'ERROR:%s' % e,level=messages.ERROR)
class MaterialForm(models.ModelForm):
name = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("material name"))
spec = fields.CharField(widget=TextInput(attrs={"size":"119"}),required=False,label=_("specifications"))
class Mata:
model = Material
fields = '__all__'
class ExtraParamInline(admin.TabularInline):
model = ExtraParam
fields = ['name','data_type','data_source']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class MaterialAdmin(generic.BOAdmin):
CODE_PREFIX = 'IT'
CODE_NUMBER_WIDTH = 5
list_display = ['code','name','spec','tp']
list_display_links = ['code','name']
list_filter = ['brand','tp']
search_fields = ['code','name']
fields = (
('code','barcode'),('name',),('spec',),
('brand',),('category',),('status','is_equip','can_sale','is_virtual',),
('warehouse',),('tp',),('measure',),('stock_price','purchase_price','sale_price',),
)
filter_horizontal = ['measure']
inlines = [ExtraParamInline]
form = MaterialForm
class TechParamValueInline(admin.TabularInline):
model = TechnicalParameterValue
class TechParamNameAdmin(admin.ModelAdmin):
list_display = ['name','category']
inlines = [TechParamValueInline]
class TradeAdmin(admin.ModelAdmin):
list_display = ['code','name','parent']
class ExpenseAdmin(generic.BOAdmin):
CODE_PREFIX = 'FC'
list_display = ['code','name','category']
list_display_links = ['code','name']
list_filter = ['category']
search_fields = ['name']
class FamilyForm(models.ModelForm):
name = fields.CharField(widget=TextInput(attrs={"size":"25"}),label=_("name"))
phone = fields.CharField(widget=TextInput(attrs={"size":"25"}),label=_("phone"))
class Meta:
model = Family
fields = '__all__'
class FamilyInline(admin.TabularInline):
model = Family
exclude = ['creator','modifier','creation','modification','begin','end']
form = FamilyForm
extra = 1
class EducationInline(admin.TabularInline):
model = Education
exclude = ['creator','modifier','creation','modification']
extra = 0
class WorkExperienceInline(admin.TabularInline):
model = WorkExperience
exclude = ['creator','modifier','creation','modification']
extra = 1
class EmployeeAdmin(generic.BOAdmin):
CODE_PREFIX = '1'
list_display = ['code','name','position','gender','idcard','age','work_age','literacy','phone','email']
search_fields = ['code','name','idcard','pinyin']
fieldsets = [
(None,{'fields':[('code','phone',),('name','pinyin',),('gender','birthday',),('idcard','country',),
('position',),('rank','category'),('status','ygxs',),('workday','startday',)]}),
(_('other info'),{'fields':[('hometown','address',),('banknum','bankname',),('email','office',),
('emergency','literacy',),('religion','marital',),('party','nation',),('spjob','health',),
('major','degree',),('tag1','tag2',),('tag3','tag4',),('user',),],'classes':['collapse']}),
]
readonly_fields = ['status','ygxs','rank','category']
inlines = [FamilyInline,EducationInline,WorkExperienceInline]
raw_id_fields = ['user']
def get_queryset(self, request):
if request.user.is_superuser or request.user.has_perm('basedata.view_all_employee'):
return super(EmployeeAdmin,self).get_queryset(request)
else:
return super(EmployeeAdmin,self).get_queryset(request).filter(user=request.user)
def get_readonly_fields(self, request, obj=None):
if request.user.is_superuser:
return []
else:
return ['status','ygxs','rank','category','position','user']
class DataImportAdmin(generic.BOAdmin):
list_display = ['imp_date','title','status']
list_display_links = ['imp_date','title']
raw_id_fields = ['content_type']
readonly_fields = ['status']
extra_buttons = [{'href':'action','title':_('import')}]
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id:
obj = DataImport.objects.get(id=object_id)
if obj.status == '1':
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
return super(DataImportAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class DocumentForm(models.ModelForm):
title = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("title"))
keywords = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("keywords"))
class Meta:
model = Document
fields = '__all__'
class DocumentAdmin(generic.BOAdmin):
CODE_PREFIX = 'FD'
CODE_NUMBER_WIDTH = 4
list_display = ['code','title','keywords','tp','business_domain','status','creation']
list_display_links = ['code','title']
fields = (('code','status',),('title',),('keywords',),('description',),('business_domain','tp',),('attach',))
readonly_fields = ['status']
list_filter = ['tp','business_domain']
search_fields = ['title','keywords','code']
form = DocumentForm
actions = ['publish']
date_hierarchy = 'begin'
def get_readonly_fields(self, request, obj=None):
if obj and obj.status=='1':
return ['code','status','title','keywords','description','business_domain','tp','attach',]
else:
return ['status']
def publish(self,request,queryset):
import datetime
cnt = queryset.filter(status='0').update(status='1',pub_date=datetime.datetime.now())
self.message_user(request,u'%s 个文档发布成功'%cnt)
publish.short_description = _('publish selected %(verbose_name_plural)s')
# admin.site.register(Address,AddressAdmin)
admin.site.register(ValueList,ValueListAdmin)
admin.site.register(Partner,PartnerAdmin)
admin.site.register(Project,ProjectAdmin)
admin.site.register(Material,MaterialAdmin)
admin.site.register(Warehouse,WarehouseAdmin)
admin.site.register(Brand,BrandAdmin)
admin.site.register(Measure,MeasureAdmin)
admin.site.register(Category,CategoryAdmin)
admin.site.register(TechnicalParameterName,TechParamNameAdmin)
admin.site.register(Trade,TradeAdmin)
admin.site.register(ExpenseAccount,ExpenseAdmin)
admin.site.register(Employee,EmployeeAdmin)
admin.site.register(DataImport,DataImportAdmin)
admin.site.register(Document,DocumentAdmin)
+9
View File
@@ -0,0 +1,9 @@
__author__ = 'zhugl'
# created at 15-4-22
from django.apps.config import AppConfig
from django.utils.translation import ugettext_lazy as _
class BaseDataConfig(AppConfig):
name = 'basedata'
verbose_name = _('BaseData')
+657
View File
@@ -0,0 +1,657 @@
# coding=utf-8
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.utils.translation import ugettext_lazy as _
from django.utils.text import force_text
from common import const
from common import generic
from syscfg.models import Module,Site
from organ.models import Organization,Position
import datetime
from plugin.xls import ExcelManager
class ValueList(generic.BO):
"""
值列表
"""
index_weight = 9
code = models.CharField(_("list code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("list name"),max_length=const.DB_CHAR_NAME_40)
module = models.ForeignKey(Module,verbose_name=_("module"),blank=True,null=True)
status = models.BooleanField(_("in use"),default=True)
init = models.BooleanField(_("is init"),default=False)
locked = models.BooleanField(_("is locked"),default=False)
locked_by = models.ForeignKey(User,verbose_name=_("locked by"),blank=True,null=True)
lock_time = models.DateTimeField(_("locked time"),null=True,blank=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(ValueList,self).save(force_insert,force_update,using,update_fields)
sql = 'update basedata_valuelistitem set group_code = %s where groud_id=%s'
params = [self.code,self.id]
generic.update(sql,params)
class Meta:
verbose_name = _('value list')
verbose_name_plural = _('value list')
class ValueListItem(models.Model):
"""
值列表项
"""
group = models.ForeignKey(ValueList,verbose_name=_("list group"))
group_code = models.CharField(max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
code = models.CharField(_("item code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("item name"),max_length=const.DB_CHAR_NAME_40)
status = models.BooleanField(_("in use"),default=True)
weight = models.IntegerField(_("weight"),null=True,default=9)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if not self.code:
cnt = self.group.valuelistitem_set.count()+1
self.code = "%02d" % cnt
self.group_code = self.group.code
super(ValueListItem,self).save(force_insert,force_update,using,update_fields)
def __unicode__(self):
return "%s-%s" % (self.code,self.name)
class Meta:
verbose_name = _('list item')
verbose_name_plural = _('list item')
ordering = ['weight','code']
index_together = ['group','group_code']
def get_value_list(group):
"""
:param group:
:return:
"""
if group:
return tuple([(item.code, item.name) for item in ValueListItem.objects.filter(group_code__exact=group,status=1)])
else:
return None
class Address(generic.BO):
"""
地址
"""
ADDRESS_TYPE = get_value_list('S011')
address_type = models.CharField(_("address type"),max_length=const.DB_CHAR_CODE_2,choices=ADDRESS_TYPE,default='01')
address = models.CharField(_("address"),max_length=const.DB_CHAR_NAME_120)
zipcode = models.CharField(_("zipcode"),max_length=const.DB_CHAR_CODE_8,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
contacts = models.CharField(_("contacts"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
content_type = models.ForeignKey(ContentType,blank=True,null=True)
object_id = models.PositiveIntegerField(blank=True,null=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
verbose_name = _('address')
verbose_name_plural = _('address')
class Partner(generic.BO):
"""
合作伙伴
"""
index_weight = 3
PARTNER_TYPE = (
('C', _('Customer')),
('S', _('Supplier')),
)
LEVEL = (
('A','A'),
('B','B'),
('C','C'),
('D','D'),
)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
code = models.CharField(_("partner code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
name = models.CharField(_("partner name"),max_length=const.DB_CHAR_NAME_120)
short = models.CharField(_("short name"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
partner_type = models.CharField(_("type"),max_length=const.DB_CHAR_CODE_2,choices=PARTNER_TYPE,default='C')
level = models.CharField(_("level"),max_length=const.DB_CHAR_CODE_2,choices=LEVEL,default='C')
tax_num = models.CharField(_("tax num"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
tax_address = models.CharField(_("tax address"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
tax_account = models.CharField(_("tax account"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
contacts = models.CharField(_("contacts"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
memo = models.TextField(_("memo"),blank=True,null=True)
class Meta:
verbose_name = _('partner')
verbose_name_plural = _('partner')
permissions = (
('view_all_customer',_("view all customer")),
('view_all_supplier',_("view all supplier")),
)
class BankAccount(generic.BO):
"""
银行账户 organization
"""
account = models.CharField(_("account num"),max_length=const.DB_CHAR_NAME_40)
title = models.CharField(_("bank name"),max_length=const.DB_CHAR_NAME_40)
memo = models.CharField(_("memo"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
partner = models.ForeignKey(Partner,verbose_name=_("partner"),blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
def __unicode__(self):
name = ''
if self.org:
name = self.org.name
elif self.partner:
name = self.partner.name
return u"%s %s %s" % (name,self.account,self.title)
class Meta:
verbose_name = _('bank account')
verbose_name_plural = _('bank account')
class Project(generic.BO):
"""
工程项目
"""
STATUS = get_value_list('S012')
TYPES = get_value_list('S013')
index_weight = 1
code = models.CharField(_("project code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
name = models.CharField(_("project name"),max_length=const.DB_CHAR_NAME_120)
short = models.CharField(_("short name"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
partner = models.ForeignKey(Partner,blank=True,null=True,verbose_name=_("partner"),limit_choices_to={"partner_type":"C"})
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,default='00',choices=STATUS)
prj_type = models.CharField(_("project type"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=TYPES,default='00')
description = models.TextField(_("description"),blank=True,null=True)
budget = models.DecimalField(_("budget"),max_digits=10,decimal_places=2,blank=True,null=True)
income = models.DecimalField(_("income"),max_digits=10,decimal_places=2,blank=True,null=True)
expand = models.DecimalField(_("expand"),max_digits=10,decimal_places=2,blank=True,null=True)
blueprint = models.FileField(_("blueprint"),upload_to='project',blank=True,null=True)
offer = models.FileField(_("offer sheet"),upload_to='offer sheet',blank=True,null=True)
business = models.FileField(_("business document"),upload_to='project',blank=True,null=True)
users = models.ManyToManyField(User,verbose_name=_("related users"),blank=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
class Meta:
verbose_name = _('project')
verbose_name_plural = _('project')
class Warehouse(models.Model):
"""
仓库
"""
index_weight = 6
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_40)
status = models.BooleanField(_("in use"),default=True)
location = models.CharField(_("location"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
users = models.ManyToManyField(User,verbose_name=_("related users"),blank=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('warehouse')
verbose_name_plural = _('warehouse')
class Measure(models.Model):
"""
计量单位
"""
index_weight = 5
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_20)
status = models.BooleanField(_("in use"),default=True)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('measure')
verbose_name_plural = _('measure')
class Trade(models.Model):
"""
国民经济行业分类
"""
index_weight = 102
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_6)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
memo = models.CharField(_("memo"),max_length=const.DB_CHAR_NAME_120,null=True,blank=True)
parent = models.ForeignKey('self',verbose_name=_("parent"),null=True,blank=True)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('trade')
verbose_name_plural = _('trade')
ordering = ['code']
class Brand(models.Model):
"""
品牌
"""
index_weight = 101
trade = models.ForeignKey(Trade,verbose_name=_("trade"),null=True,blank=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
weight = models.IntegerField(_("weight"),blank=True,null=True,default=99)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('brand')
verbose_name_plural = _('brand')
class Category(models.Model):
"""
分类
"""
index_weight = 100
trade = models.ForeignKey(Trade,verbose_name=_("trade"),null=True,blank=True)
parent = models.ForeignKey('self',verbose_name=_("parent"),null=True,blank=True)
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_6,null=True,blank=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
path = models.CharField(_("path"),max_length=const.DB_CHAR_NAME_200,null=True,blank=True)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('category')
verbose_name_plural = _('category')
class TechnicalParameterName(models.Model):
"""
技术参数-名称,将技术参数绑定于物料分类上,在此分类下的物料自动继承全部技术参数
"""
index_weight = 7
category = models.ForeignKey(Category,verbose_name=_("material category"))
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_40)
status = models.BooleanField(_("in use"),default=True)
def __unicode__(self):
return '%s' % self.name
class Meta:
verbose_name = _('technical parameter')
verbose_name_plural = _('technical parameter')
class TechnicalParameterValue(models.Model):
"""
技术参数-值,将技术参数绑定于物料分类上,在此分类下的物料自动继承全部技术参数
"""
tech_name = models.ForeignKey(TechnicalParameterName,verbose_name=_("technical name"))
value = models.CharField(_("value"),max_length=const.DB_CHAR_NAME_80)
description = models.CharField(_("description"),max_length=const.DB_CHAR_NAME_80,null=True,blank=True)
def __unicode__(self):
return '%s' % self.value
class Meta:
verbose_name = _('technical value')
verbose_name_plural = _('technical value')
class Material(generic.BO):
"""
物料
"""
index_weight = 4
code = models.CharField(_("material code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
barcode = models.CharField(_("bar code"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
name = models.CharField(_("material name"),max_length=const.DB_CHAR_NAME_120)
spec = models.CharField(_("specifications"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
brand = models.ForeignKey(Brand,blank=True,null=True,verbose_name=_("brand"))
category = models.ForeignKey(Category,blank=True,null=True,verbose_name=_("category"))
tp = models.CharField(_('mt type'),blank=True,null=True,max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('S054'),default='10')
status = models.BooleanField(_("in use"),default=True)
is_equip = models.BooleanField(_("is equipment"),default=False)
can_sale = models.BooleanField(_("can sale"),default=True)
is_virtual = models.BooleanField(_("is virtual"),default=False)
warehouse = models.ForeignKey(Warehouse,blank=True,null=True,verbose_name=_("warehouse"))
measure = models.ManyToManyField(Measure,verbose_name=_("measure"))
params = models.ManyToManyField(TechnicalParameterValue,verbose_name=_("technical parameter"),through='MaterialParam')
stock_price = models.DecimalField(_("stock price"),max_digits=14,decimal_places=4,blank=True,null=True)
purchase_price = models.DecimalField(_("purchase price"),max_digits=14,decimal_places=4,blank=True,null=True)
sale_price = models.DecimalField(_("sale price"),max_digits=14,decimal_places=4,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
def __unicode__(self):
return "%s %s" % (self.code,self.name)
class Meta:
verbose_name = _('material')
verbose_name_plural = _('material')
ordering = ['tp','code']
class MaterialParam(models.Model):
"""
"""
material = models.ForeignKey(Material)
param_value = models.ForeignKey(TechnicalParameterValue)
param_name = models.ForeignKey(TechnicalParameterName,blank=Trade,null=True)
creation = models.DateField(auto_now_add=True)
def __unicode__(self):
return '%s' % self.param_value
class Meta:
verbose_name = _('material parameter')
verbose_name_plural = _('material parameter')
class ExtraParam(models.Model):
"""
"""
DATA_TYPE = (
('CHAR',_('CHAR')),
('NUM',_('NUMBER')),
('DATE',_('DATE')),
)
material = models.ForeignKey(Material,verbose_name=_("material"))
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_40)
data_type = models.CharField(_("data type"),default='CHAR',choices=DATA_TYPE,max_length=const.DB_CHAR_CODE_6)
data_source = models.CharField(_("data source"),blank=True,null=True,max_length=const.DB_CHAR_NAME_40)
def __unicode__(self):
return "%s" % self.name
class Meta:
verbose_name = _("extra param")
verbose_name_plural = _("extra params")
class ExpenseAccount(generic.BO):
"""
费用科目
"""
CATEGORY = (
('HR',_('HR-DOMAIN')),
('OF',_('OFFICE-DOMAIN')),
('PU',_('PUBLIS-DOMAIN')),
('MU',_('MUNADOMAIN')),
('BU',_('BUSINESS')),
('OT',_('OTHER')),
)
index_weight = 10
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
category = models.CharField(_("category"),max_length=const.DB_CHAR_CODE_4,choices=CATEGORY,default='PU')
description = models.TextField(_("description"),blank=True,null=True)
parent = models.ForeignKey('self',verbose_name=_("parent"),null=True,blank=True)
status = models.BooleanField(_("in use"),default=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
class Meta:
verbose_name = _('expenses account')
verbose_name_plural = _('expenses account')
ordering = ['category','code']
class Employee(generic.BO):
"""
职员信息
"""
index_weight = 2
code = models.CharField(_("employee number"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
organization = models.ForeignKey(Organization,verbose_name = _('organization'),null=True,blank=True)
name = models.CharField(_("employee name"),max_length=const.DB_CHAR_NAME_120)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
birthday = models.DateField(_("birthday"),blank=True,null=True)
gender = models.CharField(_("gender"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('gender'),default='1')
idcard = models.CharField(_("id card"),max_length=const.DB_CHAR_NAME_20)
country = models.CharField(_("nationality"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,default='CN',choices=const.get_value_list('S022'))
hometown = models.CharField(_("hometown"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
address = models.CharField(_("home address"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
banknum = models.CharField(_("bank account"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
bankname = models.CharField(_("bank name"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
emergency = models.CharField(_("emergency contacts"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
email = models.CharField(_("email"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
office = models.CharField(_("office phone"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
position = models.ForeignKey(Position,verbose_name = _('position'))
rank = models.CharField(_("employee rank"),max_length=const.DB_CHAR_CODE_2,default='00',choices=const.get_value_list('S017'))
workday = models.DateField(_("workday"),blank=True,null=True)
startday = models.DateField(_("start date"),blank=True,null=True)
religion = models.CharField(_("religion"),max_length=const.DB_CHAR_CODE_2,default='00',choices=const.get_value_list('S020'),blank=True,null=True,)
marital = models.CharField(_("marital status"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S023'),default='10')
party = models.CharField(_("political party"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S026'),default='13')
nation = models.CharField(_("nation"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S021'),default='01')
ygxs = models.CharField(_("employ ygxs"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S019'),default='2')
status = models.CharField(_("employ status"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S016'),default='10')
category = models.CharField(_("employ category"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S018'),default='21')
literacy = models.CharField(_("literacy"),max_length=const.DB_CHAR_CODE_2,default='10',choices=const.get_value_list('S024'),blank=True,null=True)
major = models.CharField(_("major type"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S038'),default='99')
degree = models.CharField(_("major degree"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S037'),default='4')
spjob = models.CharField(_("special job"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S042'),default='00')
health = models.CharField(_("health"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S043'),default='1')
tag1 = models.CharField(_("tag1 fzjr"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S039'),default='99')
tag2 = models.CharField(_("tag2 dwld"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S040'),default='9')
tag3 = models.CharField(_("tag3 dsjs"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S041'),default='00')
tag4 = models.CharField(_("tag4 byzk"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S027'),default='0')
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
def age(self):
import datetime
if self.birthday:
cnt = datetime.date.today().year-self.birthday.year
return cnt
def work_age(self):
import datetime
if self.birthday and self.workday:
cnt = datetime.date.today().year-self.workday.year
return cnt
def __unicode__(self):
return u'%s %s'%(self.code,self.name)
age.short_description = u'年龄'
work_age.short_description = u'工龄'
class Meta:
verbose_name = _("employee")
verbose_name_plural = _("employee")
permissions = (
('view_all_employee',_("view all employee")),
)
class Family(generic.BO):
"""
家庭成员
"""
relation = models.CharField(_("family title"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S025'))
status = models.CharField(_("social status"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S029'),default='17')
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_60)
birthday = models.DateField(_("birthday"),blank=True,null=True)
organization = models.CharField(_("organization"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
emergency = models.BooleanField(_("emergency"),default=False)
employee = models.ForeignKey(Employee,verbose_name=_("employee"))
class Meta:
verbose_name = _("family member")
verbose_name_plural = _("family member")
class Education(generic.BO):
"""
教育履历
"""
edu_type = models.CharField(_("edu type"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('S035'),default='1')
school = models.CharField(_("school"),max_length=const.DB_CHAR_NAME_120)
major = models.CharField(_("major"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
degree = models.CharField(_("major degree"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S037'),default='4')
employee = models.ForeignKey(Employee,verbose_name=_("employee"))
class Meta:
verbose_name = _("education experience")
verbose_name_plural = _("education experience")
class WorkExperience(generic.BO):
"""
工作履历
"""
organization = models.CharField(_("organization"),max_length=const.DB_CHAR_NAME_120)
position = models.CharField(_("position"),max_length=const.DB_CHAR_NAME_120)
employee = models.ForeignKey(Employee,verbose_name=_("employee"))
class Meta:
verbose_name = _("work experience")
verbose_name_plural = _("work experience")
class DataImport(generic.BO):
"""
Data import
"""
actions = {}
STATUS = (
('0',_('NEW')),
('1',_('EXECUTED')),
)
imp_date = models.DateField(_('date'),blank=True,null=True,default=datetime.datetime.today)
title = models.CharField(_('title'),max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_('description'),blank=True,null=True)
content_type = models.ForeignKey(ContentType,verbose_name=_("content type"),limit_choices_to={"app_label__in":['basedata','organ','auth']})
attach = models.FileField(_('attach'),blank=True,null=True,upload_to='data')
is_clear = models.BooleanField(_('clear old data?'),default=0)
handler = models.CharField(_('handler class'),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
status = models.CharField(_('status'),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
def action_import(self,request):
from django.db import transaction
if self.attach:
if self.handler:
klass = ExcelManager().handlers.get(self.handler)
with transaction.atomic():
klass.handle(self,self.attach)
self.status = 1
self.save()
else:
import xlrd
import os
from mis import settings
path = os.path.join(settings.MEDIA_ROOT,self.attach.name)
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
row_count = sheet.nrows
col_count = sheet.ncols
cols = []
with transaction.atomic():
for row_index in range(row_count):
line = sheet.row_values(row_index)
if row_index == 0:
cols = line
continue
elif row_index == 1:
continue
else:
klass = self.content_type.model_class()
values = line
params = {}
for name in cols:
index = cols.index(name)
v = values[index]
if type(v) == str:
v = force_text(v.decode('gbk'))
params[name]=v
# print 'name is %s value is %s'%(name,v)
try:
params.pop('')
except Exception,e:
pass
# print params
klass.objects.create(**params)
self.status = '1'
self.save()
class Meta:
verbose_name = _("data import")
verbose_name_plural = _("data import")
class Document(generic.BO):
"""
文档管理
"""
TP = (
('00',_('SYSTEM MANUAL')),
('10',_('BUSINESS DOC')),
)
STATUS = (
('0',_('draft')),
('1',_('published'))
)
index_weight = 8
code = models.CharField(_('code'),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
title = models.CharField(_('title'),max_length=const.DB_CHAR_NAME_120)
keywords = models.CharField(_('keywords'),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
description = models.TextField(_('description'),blank=True,null=True)
tp = models.CharField(_('type'),max_length=const.DB_CHAR_CODE_2,default='10',choices=TP)
business_domain = models.CharField(_("business domain"),max_length=const.DB_CHAR_CODE_4,choices=const.get_value_list('S045'),default='OT')
user = models.ForeignKey(User,verbose_name=_('user'),blank=True,null=True)
status = models.CharField(_('status'),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
pub_date = models.DateTimeField(_('publish date'),blank=True,null=True)
size = models.CharField(_('size'),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
attach = models.FileField(_('attach'),blank=True,null=True,upload_to='doc')
class Meta:
verbose_name = _("document")
verbose_name_plural = _("documents")
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+6
View File
@@ -0,0 +1,6 @@
from django.conf.urls import include, url,static
import basedata.views
urlpatterns = [
url(r"dataimport/(?P<object_id>\d+)/action", 'basedata.views.action_import'),
]
+42
View File
@@ -0,0 +1,42 @@
# coding=utf-8
from django.contrib.admin import site
from django.http.response import HttpResponseRedirect
from django.utils.encoding import force_text
from django.template.response import TemplateResponse
from django.contrib import messages
from basedata.models import DataImport
from django.utils.translation import ugettext_lazy as _
def action_import(request,object_id):
"""
数据导入操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = DataImport.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
obj.action_import(request)
try:
messages.success(request,_('data import successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/basedata/dataimport/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
+1
View File
@@ -0,0 +1 @@
__author__ = 'Administrator'
+39
View File
@@ -0,0 +1,39 @@
# coding=utf-8
from django.db import connection
from django.utils.translation import ugettext_lazy as _
__author__ = 'zhugl'
DB_CHAR_CODE_2 = 2
DB_CHAR_CODE_4 = 4
DB_CHAR_CODE_6 = 6
DB_CHAR_CODE_8 = 8
DB_CHAR_CODE_10 = 10
DB_CHAR_NAME_20 = 20
DB_CHAR_NAME_40 = 40
DB_CHAR_NAME_60 = 60
DB_CHAR_NAME_80 = 80
DB_CHAR_NAME_120 = 120
DB_CHAR_NAME_200 = 200
STATUS_ON_OFF = (
(0,_('OFF')),
(0,_('ON')),
)
def get_value_list(group):
"""
获取值列表信息
"""
if group:
try:
cursor = connection.cursor()
cursor.execute('SELECT code,name FROM basedata_valuelistitem WHERE group_code=%s AND status=1',[group])
rows = cursor.fetchall()
return tuple([(code,name) for code,name in rows])
except Exception,e:
return None
else:
return None
+312
View File
@@ -0,0 +1,312 @@
# coding=utf-8
__author__ = 'zhugl'
# created at 15-4-21
import datetime
import xlwt
import re
from django.db import models
from django.db import connection,transaction
from django.db.models import fields
from django.db.models.fields import related
from django.contrib import admin
from django.http import HttpRequest,HttpResponseRedirect,HttpResponse
from django.contrib.contenttypes.models import ContentType
from django.utils.text import force_text
from django.utils.encoding import smart_str
from django.utils.http import urlquote
from django.utils.translation import ugettext_lazy as _
from common import const
from midware import cuser
def update(sql, params=None):
"""
:param sql:
:param params:
:return:
"""
cursor = connection.cursor()
with transaction.atomic():
try:
if params:
cursor.execute(sql,params)
else:
cursor.execute(sql)
except Exception,e:
print e
def get_app_model_info_from_request(request):
"""
"""
if request and isinstance(request,HttpRequest):
import re
pattern = re.compile(r"/(admin)/(\w+)/(\w+)/(\d+)")
match = pattern.match(request.path)
if match and match.group():
app = match.group(2)
model = match.group(3)
oid = match.group(4)
ct = ContentType.objects.get(app_label=app,model=model)
obj = ct.get_object_for_this_type(id=oid)
return {'app':app,'model':model,'id':oid,'obj':obj}
return None
class MineBOManager(models.Manager):
"""
get the objects created by current login user
"""
def get_query_set(self):
return super(MineBOManager,self).get_query_set().filter(creator=cuser.getuser())
class BOManager(models.Manager):
"""
"""
def get_query_set(self):
return super(BOManager,self).get_query_set()
class BO(models.Model):
"""
All business object derive from this class
"""
begin = models.DateField(_('begin date'),blank=True,null=True)
end = models.DateField(_('end date'),blank=True,null=True)
creator = models.CharField(_("creator"),blank=True,null=True,max_length=const.DB_CHAR_NAME_20)
modifier = models.CharField(_("modifier"),blank=True,null=True,max_length=const.DB_CHAR_NAME_20)
creation = models.DateTimeField(_('creation'),auto_now_add=True,blank=True,null=True)
modification = models.DateTimeField(_('modification'),auto_now=True,blank=True,null=True)
# mine = MineBOManager()
objects = models.Manager()
def __unicode__(self):
display = getattr(self,'name',None) or getattr(self,'title',None) or getattr(self,'description',None)
if not display:
display = ' '
return u'%s' % display
class Meta:
abstract = True
class BOAdmin(admin.ModelAdmin):
"""
All business object admin derive from this class
"""
CODE_NUMBER_WIDTH = 4
CODE_PREFIX = '9'
extra_buttons = []
exclude = ['creator','modifier','creation','modification','begin','end']
list_per_page = 18
actions = ['export_selected_data']
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
"""
:param request:
:param object_id:
:param form_url:
:param extra_context:
:return:
"""
app_info = get_app_model_info_from_request(request)
workflow_modal = None
workflow_instance = None
has_workflow_modal = False
has_workflow_instance = False
show_workflow_line = False
show_submit_button = False
can_restart = False
can_edit = False
# print app_info
if app_info:
try:
modal = ContentType.objects.get(app_label='workflow',model='modal')
workflow_modal = modal.get_object_for_this_type(app_name=app_info['app'],model_name=app_info['model'])
has_workflow_modal = True
# print workflow_modal.code
instance = ContentType.objects.get(app_label='workflow',model='instance')
workflow_instance = instance.get_object_for_this_type(modal=workflow_modal,object_id=app_info['id'])
has_workflow_instance = True
todo = ContentType.objects.get(app_label='workflow',model='todolist')
todo_list = todo.model_class().objects.filter(inst=workflow_instance,status=0,user=request.user)
x = todo_list.all()
if x and len(x)>0:
can_edit = x[0].node.can_edit
if todo_list.count() > 0:
# print 'we fount it'
unread = todo_list.filter(is_read=0)
show_workflow_line = True
if unread.count() > 0:
unread.update(is_read=1,read_time=datetime.datetime.now())
if workflow_instance.status == 3 and request.user == workflow_instance.starter:
can_restart = True
show_workflow_line = True
except Exception,e:
print Exception,e
if workflow_modal and not workflow_instance:
show_submit_button = True
extra_context = extra_context or {}
ctx = dict(
has_workflow_instance = has_workflow_instance,
has_workflow_modal = has_workflow_modal,
workflow_modal = workflow_modal,
workflow_instance = workflow_instance,
show_workflow_line = show_workflow_line,
can_restart = can_restart,
can_edit = can_edit,
show_submit_button = show_submit_button,
)
if len(self.extra_buttons) > 0:
buttons = dict(
extra_buttons = self.extra_buttons
)
ctx.update(buttons)
extra_context.update(ctx)
# print extra_context
return super(BOAdmin,self).changeform_view(request,object_id,form_url,extra_context)
def history_view(self, request, object_id, extra_context=None):
"""
:param request:
:param object_id:
:param extra_context:
:return:
"""
app_info = get_app_model_info_from_request(request)
# print app_info
if app_info:
try:
modal = ContentType.objects.get(app_label='workflow',model='modal')
workflow_modal = modal.get_object_for_this_type(app_name=app_info['app'],model_name=app_info['model'])
has_workflow_modal = True
instance = ContentType.objects.get(app_label='workflow',model='instance')
workflow_instance = instance.get_object_for_this_type(modal=workflow_modal,object_id=app_info['id'])
has_workflow_instance = True
history = ContentType.objects.get(app_label='workflow',model='history')
history_list = history.model_class().objects.filter(inst=workflow_instance)
has_history = True
todo = ContentType.objects.get(app_label='workflow',model='todolist')
todo_list = todo.model_class().objects.filter(inst=workflow_instance,status=0).exclude(node=None)
extra_context = extra_context or {}
ctx = dict(
has_workflow_instance = has_workflow_instance,
has_workflow_modal = has_workflow_modal,
workflow_modal = workflow_modal,
workflow_instance = workflow_instance,
history_list = history_list,
has_history = has_history,
todo_list = todo_list,
)
# print history_list
extra_context.update(ctx)
except Exception,e:
print Exception,e
pass
return super(BOAdmin,self).history_view(request,object_id,extra_context)
def get_changeform_initial_data(self, request):
import datetime
return {'begin':datetime.date.today,'end':datetime.date(9999,12,31)}
def save_model(self, request, obj, form, change):
if change:
setattr(obj,'modifier',request.user.username)
else:
setattr(obj,'creator',request.user.username)
setattr(obj,'begin',datetime.date.today())
setattr(obj,'end',datetime.date(9999,12,31))
try:
setattr(obj,'user',request.user)
except Exception,e:
pass
super(BOAdmin,self).save_model(request,obj,form,change)
# print '=========it is here========='
try:
code = getattr(obj,'code')
# print code
if code is None or len(code) == 0:
fmt = '%s%0'+str(self.CODE_NUMBER_WIDTH)+'d'
code = fmt % (self.CODE_PREFIX,obj.id)
table = obj._meta.db_table
sql = 'update %s set code = \'%s\' where id=%s' % (table,code,obj.id)
print sql
update(sql)
except Exception,e:
print e
# def response_change(self, request, obj):
# return HttpResponseRedirect('')
def export_selected_data(self,request,queryset):
ops = self.model._meta
workbook = xlwt.Workbook(encoding='utf-8')
dd = datetime.date.today().strftime('%Y%m%d')
file_name = force_text(ops.verbose_name+dd)
sheet = workbook.add_sheet(force_text(ops.verbose_name))
obj_fields = getattr(self,'export_fields',None) or self.list_display or self.fields
head_col_index = 0
for field in obj_fields:
col_name = field
try:
f = ops.get_field(field)
col_name = f.verbose_name
except Exception,e:
f = getattr(self.model,field)
if hasattr(f,'short_description'):
col_name = f.short_description
sheet.write(0,head_col_index,force_text(col_name))
head_col_index+=1
row_index = 1
for obj in queryset:
col_index = 0
for field in obj_fields:
f = field
try:
f = ops.get_field(field)
except Exception,e:
pass
v = getattr(obj,field,'')
if hasattr(v,'__call__') or callable(v):
v = v()
elif type(f) == fields.DateField:
v = v.strftime('%Y-%m-%d')
elif type(f) == fields.DateTimeField:
v = v.strftime('%Y-%m-%d %H:%M')
elif type(f) == fields.CharField and f.choices:
fc = 'get_'+field+'_display'
v = getattr(obj,fc)()
elif type(f) == related.ForeignKey:
v = str(v)
sheet.write(row_index,col_index,v)
col_index += 1
row_index += 1
response = HttpResponse(content_type='application/vnd.ms-excel')
agent = request.META.get('HTTP_USER_AGENT')
nn = smart_str(file_name)
if agent and re.search('MSIE',agent):
nn = urlquote(file_name)
response['Content-Disposition'] = 'attachment; filename=%s.xls'%nn
workbook.save(response)
return response
#self.message_user(request,'SUCCESS')
export_selected_data.short_description = _("export selected %(verbose_name_plural)s")
class Meta:
ordering = ['-creation']
class Media:
css = {'all':('css/maximus.css',)}
js = ('js/maximus.js',)
+1
View File
@@ -0,0 +1 @@
default_app_config = 'hr.apps.MyAppConfig'
+47
View File
@@ -0,0 +1,47 @@
# coding = utf-8
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from hr.models import Entry,SalaryItem,EmployeeSalaryItem
class SalaryItemAdmin(admin.ModelAdmin):
list_display = ['code','classification','name','plus_or_minus','required']
list_display_links = ['code','name']
list_per_page = 20
class EmployeeSalaryItemInline(admin.TabularInline):
model = EmployeeSalaryItem
exclude = ['employee']
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'salary_item':
kwargs['queryset'] = SalaryItem.objects.filter(required=1)
return super(EmployeeSalaryItemInline,self).formfield_for_foreignkey(db_field,request,**kwargs)
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class EntryAdmin(generic.BOAdmin):
list_display = ['code','name','gender','position','rank','probation_months','probation_end']
inlines = [EmployeeSalaryItemInline]
fieldsets = [
(None,{'fields':[('code','position',),('name','pinyin',),('address','zipcode',),('idcard','phone',),('memo',),('profile',)]}),
(_('org distribute'),{'fields':[('guider',),('rank','ygxs',),('category','probation_months',),('probation_begin','probation_end',)],'classes': ['collapse']})
]
raw_id_fields = ['position','guider']
def get_changeform_initial_data(self, request):
import datetime
end = datetime.date.today()+datetime.timedelta(90)
return {'probation_end':end}
admin.site.register(SalaryItem,SalaryItemAdmin)
admin.site.register(Entry,EntryAdmin)
+11
View File
@@ -0,0 +1,11 @@
# created at 15-5-23
# coding=utf-8
__author__ = 'zhugl'
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class MyAppConfig(AppConfig):
name = 'hr'
verbose_name = _("human resource")
+125
View File
@@ -0,0 +1,125 @@
# coding=utf-8
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from basedata.models import Position,Employee
from organ.models import OrgUnit
import datetime
class SalaryItemHandler:
code = None
def __init__(self,employee):
self.employee = employee
def value(self):
return 0
class SalaryItem(models.Model):
"""
工资项
"""
formulas = {}
@classmethod
def add_formula(cls, code, handler):
SalaryItem.formulas[code] = handler
@classmethod
def get_formula(cls):
return SalaryItem.formulas.get(cls.code,None)
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_10,null=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
classification = models.CharField(_("classification"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('S048'),default='10')
plus_or_minus = models.CharField(_("plus or minus"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('S049'),default='+')
required = models.BooleanField(_("is required"),default=0)
def __unicode__(self):
return "%s %s" % (self.code,self.name)
class Meta:
verbose_name = _('salary item')
verbose_name_plural = _('salary items')
ordering = ('code',)
class Entry(generic.BO):
"""
人员入职
"""
code = models.CharField(_("employee number"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
name = models.CharField(_("employee name"),max_length=const.DB_CHAR_NAME_120)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
birthday = models.DateField(_("birthday"),blank=True,null=True)
gender = models.CharField(_("gender"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('gender'),default='1')
idcard = models.CharField(_("id card"),max_length=const.DB_CHAR_NAME_20)
address = models.CharField(_("mail address"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
zipcode = models.CharField(_("zipcode"),max_length=const.DB_CHAR_CODE_8)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
guider = models.ForeignKey(Employee,verbose_name=_("guider"))
position = models.ForeignKey(Position,verbose_name = _('designate position'))
rank = models.CharField(_("employee rank"),max_length=const.DB_CHAR_CODE_2,default='00',choices=const.get_value_list('S017'))
ygxs = models.CharField(_("employ ygxs"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S019'),default='2')
category = models.CharField(_("employ category"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=const.get_value_list('S018'),default='21')
probation_months = models.CharField(_("probation months"),max_length=2,default='3',choices=const.get_value_list('S047'))
probation_begin = models.DateField(_("probation begin"),default=datetime.date.today)
probation_end = models.DateField(_("probation end"),blank=True,null=True)
memo = models.TextField(_("memo"),blank=True,null=True)
profile = models.FileField(_("profile"),blank=True,null=True,upload_to='hr profile')
class Meta:
verbose_name = _("employee entry")
verbose_name_plural = _("employee entries")
permissions = (
('modify_salary_item',_("modify salary item")),
)
class EmployeeSalaryItem(models.Model):
"""
"""
entry = models.ForeignKey(Entry,verbose_name=_("employee entry"))
employee = models.ForeignKey(Employee,verbose_name=_("employee"),blank=True,null=True)
salary_item = models.ForeignKey(SalaryItem,verbose_name=_("salary item"))
calculate_way = models.CharField(_("calculate way"),max_length=const.DB_CHAR_CODE_2,choices=const.get_value_list('S050'),default='10')
fixed_value = models.DecimalField(_("fixed value"),blank=True,null=True,max_digits=10,decimal_places=2)
base_value = models.DecimalField(_("base value"),blank=True,null=True,max_digits=10,decimal_places=2)
org_percent = models.DecimalField(_("org percent"),blank=True,null=True,max_digits=4,decimal_places=2)
employee_percent = models.DecimalField(_("employee percent"),blank=True,null=True,max_digits=4,decimal_places=2)
class Meta:
verbose_name = _("salary item")
verbose_name_plural = _("salary item")
unique_together = (('entry', 'salary_item'),)
class Transfer(generic.BO):
"""
人员调动
"""
employee = models.ForeignKey(Employee,verbose_name=_("employee"))
class Meta:
verbose_name = _("employee transfer")
verbose_name_plural = _("employee transfers")
class Departure(generic.BO):
"""
人员离职
"""
employee = models.ForeignKey(Employee,verbose_name=_("employee"))
class Meta:
verbose_name = _("employee departure")
verbose_name_plural = _("employee departures")
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+1
View File
@@ -0,0 +1 @@
default_app_config = "invent.apps.MyAppConfig"
+248
View File
@@ -0,0 +1,248 @@
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from common import generic
from basedata.models import Material
from invent.models import StockIn,StockOut,InitialInventory,InItem,OutItem,InitItem,Inventory,InItemForm,InOutDetail,\
WareReturn,ReturnItem,WareAdjust,AdjustItem
class InItemInline(admin.TabularInline):
model = InItem
form = InItemForm
fields = ('material', 'measure', 'cnt', 'price')
raw_id_fields = ['material']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
def get_readonly_fields(self, request, obj=None):
if obj and obj.status == 1:
return ['material', 'measure', 'cnt', 'price']
else:
return []
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'material':
kwargs['queryset'] = Material.objects.filter(is_virtual=0)
return super(InItemInline,self).formfield_for_foreignkey(db_field,request,**kwargs)
class OutItemInline(admin.TabularInline):
model = OutItem
fields = ('inventory', 'measure', 'cnt', 'price','warehouse',)
raw_id_fields = ['inventory']
readonly_fields = ['measure', 'price', 'warehouse']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class InitItemInline(admin.TabularInline):
model = InitItem
fields = ('material', 'measure', 'cnt', 'warehouse', 'price',)
raw_id_fields = ['material']
def get_readonly_fields(self, request, obj=None):
if obj and obj.execute_time:
return ['material', 'measure', 'cnt', 'warehouse', 'price']
else:
return []
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'material':
kwargs['queryset'] = Material.objects.filter(is_virtual=0)
return super(InitItemInline,self).formfield_for_foreignkey(db_field,request,**kwargs)
class StockInAdmin(generic.BOAdmin):
CODE_PREFIX = 'RK'
CODE_NUMBER_WIDTH = 5
list_display = ['code','title','money_of_amount','status','entry_time']
inlines = [InItemInline]
raw_id_fields = ['po']
fields = (
('code',),('title',),('po',),('warehouse',),('batch',),('status','amount',)
)
date_hierarchy = 'begin'
extra_buttons = [{'href':'cin','title':_('Action Stock In')}]
def save_model(self, request, obj, form, change):
import decimal
super(StockInAdmin,self).save_model(request,obj,form,change)
if obj and obj.po:
po_items = obj.po.poitem_set.filter(left_cnt__gt=0).all()
for item in po_items:
try:
InItem.objects.get(po_item=item,master=obj)
continue
except Exception,e:
pp = item.discount_price or item.price
if decimal.Decimal(item.tax) > decimal.Decimal(0):
pp = pp /(decimal.Decimal(1)+decimal.Decimal(item.tax))
InItem.objects.create(warehouse=obj.warehouse,material=item.material,measure=item.measure,prop='+',
po_item=item,master=obj,cnt=item.left_cnt,price=pp,batch=obj.batch,source=obj.code)
def get_readonly_fields(self, request, obj=None):
print obj
if obj and obj.status == 9:
return ['code','title','po','warehouse','batch','status']
else:
return ['status','amount']
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
extra_context = extra_context or {}
if object_id:
obj = StockIn.objects.get(id=object_id)
if obj and obj.execute_time:
extra_context.update(dict(readonly=True))
return super(StockInAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class StockOutAdmin(generic.BOAdmin):
CODE_PREFIX = 'CK'
CODE_NUMBER_WIDTH = 5
list_display = ['code','title','project','status','out_time','out_amount']
list_display_links = ['code','title']
date_hierarchy = 'begin'
inlines = [OutItemInline]
raw_id_fields = ['project','wo','user']
fields = (
('code', 'status',),('project', ),('wo','user'),
('title','amount',),('description',),
)
readonly_fields = ['status']
extra_buttons = [{'href':'out','title':_('Action Stock Out')}]
search_fields = ['code','title','user__username']
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
extra_context = extra_context or {}
if object_id:
obj = StockOut.objects.get(id=object_id)
if obj and obj.execute_time:
extra_context.update(dict(readonly=True))
return super(StockOutAdmin,self).changeform_view(request,object_id,form_url,extra_context)
def save_model(self, request, obj, form, change):
if obj and obj.user is None:
obj.user = request.user
super(StockOutAdmin,self).save_model(request,obj,form,change)
class InitialInventoryAdmin(generic.BOAdmin):
CODE_PREFIX = 'QC'
CODE_NUMBER_WIDTH = 3
list_display = ['code','title','status']
inlines = [InitItemInline]
fields = ('code','title','org','status','amount','attach')
readonly_fields = ['status','amount']
extra_buttons = [{'href':'cin','title':_('Action Stock In')}]
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
extra_context = extra_context or {}
if object_id:
obj = InitialInventory.objects.get(id=object_id)
if obj and obj.execute_time:
extra_context.update(dict(readonly=True))
return super(InitialInventoryAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class InventoryAdmin(generic.BOAdmin):
list_display = ['material','measure','warehouse','cnt','price']
search_fields = ['material__name','material__code']
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
if object_id:
inventory = Inventory.objects.get(id=object_id)
material = inventory.material
warehouse = inventory.warehouse
detail = InOutDetail.objects.filter(material=material,warehouse=warehouse)
extra_context.update(dict(detail=detail))
return super(InventoryAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class ReturnItemInline(admin.TabularInline):
model = ReturnItem
fields = ['material','measure','warehouse','out_cnt','cnt']
readonly_fields = ['material','measure','warehouse','out_cnt']
extra = 0
class WareReturnAdmin(generic.BOAdmin):
"""
"""
CODE_PREFIX = 'FK'
CODE_NUMBER_WIDTH = 4
list_display = ['code','title','out']
fields = (
('code',),('title',),('out',),('amount',),('status',)
)
readonly_fields = ['status']
raw_id_fields = ['out']
inlines = [ReturnItemInline]
extra_buttons = [{'href':'cin','title':_('Action Ware Return')}]
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id :
obj = WareReturn.objects.get(id=object_id)
if obj.status == '9':
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
return super(WareReturnAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class AdjustItemInline(admin.TabularInline):
model = AdjustItem
fields = ['inventory','measure','warehouse','prop','cnt']
readonly_fields = ['measure','warehouse']
raw_id_fields = ['inventory']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class WareAdjustAdmin(generic.BOAdmin):
CODE_PREFIX = 'TZ'
CODE_NUMBER_WIDTH = 3
list_display = ['code','title','status']
fields = (
('code',),('title',),('description',),('status',)
)
readonly_fields = ['status']
inlines = [AdjustItemInline]
extra_buttons = [{'href':'adjust','title':_('Action Ware Adjust')}]
date_hierarchy = 'begin'
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id:
obj = WareAdjust.objects.get(id=object_id)
if obj and obj.status == '9':
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
return super(WareAdjustAdmin,self).changeform_view(request,object_id,form_url,extra_context)
admin.site.register(StockIn,StockInAdmin)
admin.site.register(StockOut,StockOutAdmin)
admin.site.register(InitialInventory,InitialInventoryAdmin)
admin.site.register(Inventory,InventoryAdmin)
admin.site.register(WareReturn,WareReturnAdmin)
admin.site.register(WareAdjust,WareAdjustAdmin)
+11
View File
@@ -0,0 +1,11 @@
# created at 15-5-23
# coding=utf-8
__author__ = 'zhugl'
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class MyAppConfig(AppConfig):
name = 'invent'
verbose_name = _("inventory manage")
+493
View File
@@ -0,0 +1,493 @@
# coding=utf-8
import csv
import os
import datetime
import decimal
from django.db import transaction
from django.db import models
from django import forms
from mis import settings
from django.utils.text import force_text
from django.db import transaction
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from basedata.models import Material,Warehouse,Measure,Organization,Project
from selfhelp.models import WorkOrder
from purchase.models import PurchaseOrder,POItem
class Inventory(generic.BO):
"""
库存信息
"""
index_weight = 1
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
warehouse = models.ForeignKey(Warehouse,verbose_name=_("warehouse"))
material = models.ForeignKey(Material,verbose_name=_("material"))
measure = models.ForeignKey(Measure,verbose_name=_("measure"))
cnt = models.DecimalField(_("count"),max_digits=14,decimal_places=4)
batch = models.CharField(_("batch"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
price = models.DecimalField(_("price"),max_digits=14,decimal_places=4)
def __unicode__(self):
des = self.material.spec or ''
return u'%s %s %s' % (self.material.code,self.material.name,des)
class Meta:
verbose_name = _("Inventory")
verbose_name_plural = _("Inventory")
ordering = ['material']
class InitialInventory(generic.BO):
"""
期初库存
"""
STATUS = (
('0', _("NEW")),
('9', _("EXECUTED"))
)
index_weight = 9
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
execute_time = models.DateTimeField(_("execute time"),blank=True,null=True)
attach = models.FileField(_('attach'),blank=True,null=True,upload_to='inventory',help_text=u'参考FD0002模板文档')
amount = models.DecimalField(_('money of amount'),max_digits=14,decimal_places=4,blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(InitialInventory,self).save(force_insert,force_update,using,update_fields)
count = InitItem.objects.filter(master=self).count()
if self.attach and count == 0:
path = os.path.join(settings.MEDIA_ROOT,self.attach.name)
reader = csv.reader(open(path,'r'))
index = 0
with transaction.atomic():
for code,name,description,unit_code,unit_name,warehouse_code,warehouse_name,price,cnt in reader:
index+=1
if index == 1:
continue
material = None
measure = None
house = None
try:
measure = Measure.objects.get(code=unit_code)
except Exception,e:
measure = Measure.objects.create(code=unit_code,name=force_text(unit_name.decode('gbk')))
try:
house = Warehouse.objects.get(code=warehouse_code)
except Exception,e:
house = Warehouse.objects.create(code=warehouse_code,name=force_text(warehouse_name.decode('gbk')))
try:
material = Material.objects.get(code=code)
except Exception,e:
material = Material(code=code,name=force_text(name.decode('gbk')),spec=force_text(description.decode('gbk')),warehouse=house)
material.stock_price = price
material.save()
InitItem.objects.create(master=self,material=material,price=price,cnt=cnt,warehouse=house,measure=measure,source=self.code)
def init_entry(self,request=None):
"""
执行期初入库
"""
count = InitItem.objects.filter(master=self).count()
if count > 0:
with transaction.atomic():
total_amount = 0
for item in InitItem.objects.filter(master=self).all():
Inventory.objects.create(material=item.material,price=item.price,cnt=item.cnt,warehouse=item.warehouse,measure=item.measure)
item.status = 1
item.event_time = datetime.datetime.now()
item.source = self.code
item.save()
item.material.stock_price = item.price
if item.material.measure.count() == 0:
item.material.measure.add(item.measure)
item.material.save()
total_amount += item.price*item.cnt
self.amount = total_amount
self.status = '9'
self.execute_time = datetime.datetime.now()
self.save()
else:
raise Exception(_("none material was found"))
class Meta:
verbose_name = _("Initial Inventory")
verbose_name_plural = _("Initial Inventory")
class StockIn(generic.BO):
"""
入库单
"""
STATUS = (
('0', _("NEW")),
('1', _("QUALITY TESTING")),
('9', _("EXECUTED"))
)
index_weight = 3
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
warehouse = models.ForeignKey(Warehouse,verbose_name=_("warehouse"))
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
execute_time = models.DateTimeField(_("execute time"),blank=True,null=True)
po = models.ForeignKey(PurchaseOrder,verbose_name=_("purchase order"),null=True,limit_choices_to={"entry_status":"0"},blank=True)
amount = models.DecimalField(_("stock in money of amount"),max_digits=14,decimal_places=4,blank=True,null=True)
batch = models.CharField(_("batch"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
def money_of_amount(self):
if self.amount:
return self.amount
else:
return 0.00
def entry_time(self):
if self.execute_time:
return self.execute_time
else:
return ''
money_of_amount.short_description = _("stock in money of amount")
entry_time.short_description = _("entry time")
def action_entry(self,request):
"""
执行入库操作
"""
if self.initem_set.count() > 0:
with transaction.atomic():
total_amount = decimal.Decimal(0)
for item in self.initem_set.filter(status=0).all():
try:
inventory = Inventory.objects.get(warehouse=self.warehouse,material=item.material,measure=item.measure)
if inventory.price != item.price:
at = decimal.Decimal(inventory.price*inventory.cnt+item.price*item.cnt)
ac = decimal.Decimal(inventory.cnt+item.cnt)
average = at/ac
inventory.price = average
item.material.stock_price = average
item.material.save()
inventory.cnt += item.cnt
inventory.save()
total_amount += item.price*item.cnt
except Exception,e:
Inventory.objects.create(warehouse=self.warehouse,material=item.material,measure=item.measure,
cnt=item.cnt,price=item.price,org=self.org)
item.material.stock_price = item.price
item.material.save()
item.status=1
item.event_time = datetime.datetime.now()
item.source = self.code
item.save()
total_amount += item.price*item.cnt
# saving the purchase item
item.po_item.is_in_stock = 1
item.po_item.in_stock_time = datetime.datetime.now()
item.po_item.entry_cnt = item.cnt
item.po_item.save()
none_zero_left = POItem.objects.filter(po=item.po_item.po,left_cnt__gt=0).count()
if none_zero_left == 0:
item.po_item.po.status = '99'
item.po_item.po.entry_status = 1
item.po_item.po.entry_time = datetime.datetime.now()
item.po_item.po.save()
# saving stock in item status
item.status = 1
item.event_time = datetime.datetime.now()
# updating master's record
self.status = 9
self.execute_time = datetime.datetime.now()
self.amount = total_amount
self.save()
class Meta:
verbose_name = _("StockIn")
verbose_name_plural = _("StockIn")
class StockOut(generic.BO):
"""
领料单
"""
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('9', _("EXECUTED"))
)
index_weight = 2
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
project = models.ForeignKey(Project,verbose_name=_("project"),blank=True,null=True)
wo = models.ForeignKey(WorkOrder,verbose_name=_("work order"),blank=True,null=True)
description = models.TextField(_("description"),blank=True,null=True)
amount = models.DecimalField(_("money of amount"),max_digits=14,decimal_places=4,blank=True,null=True)
user = models.ForeignKey(User,verbose_name=_("out user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
execute_time = models.DateTimeField(_("execute time"),blank=True,null=True)
def out_amount(self):
return self.amount or ''
def out_time(self):
return self.execute_time or ''
out_time.short_description = _('stock out time')
out_amount.short_description = _('stock out amount')
def action_out(self,request=None):
"""
执行出库操作
"""
if self.outitem_set.count() > 0:
with transaction.atomic():
total = decimal.Decimal(0)
for item in OutItem.objects.filter(master=self).all():
if item.inventory.cnt < item.cnt:
raise Exception('%s does not meets required' % item.material)
if item.cnt:
total += item.cnt * item.inventory.price
item.inventory.cnt -= item.cnt
item.status = 1
item.price = item.inventory.price
item.event_time = datetime.datetime.now()
item.inventory.save()
item.source=self.code
item.save()
if total > 0:
self.amount = total
self.status = '9'
self.execute_time = datetime.datetime.now()
self.save()
class Meta:
verbose_name = _("StockOut")
verbose_name_plural = _("StockOut")
class WareReturn(generic.BO):
"""
返库单
"""
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('9', _("EXECUTED"))
)
index_weight = 5
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
out = models.ForeignKey(StockOut,verbose_name=_('StockOut'))
amount = models.DecimalField(_("money of amount"),max_digits=14,decimal_places=4,blank=True,null=True)
user = models.ForeignKey(User,verbose_name=_("out user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
execute_time = models.DateTimeField(_("execute time"),blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(WareReturn,self).save(force_insert,force_update,using,update_fields)
item_count = ReturnItem.objects.filter(master=self).count()
if self.out and item_count == 0:
for out_item in OutItem.objects.filter(master=self.out):
ReturnItem.objects.create(master=self,out_item=out_item,material=out_item.material,price=out_item.price,
measure=out_item.measure,warehouse=out_item.warehouse,out_cnt=out_item.cnt,cnt=out_item.cnt)
def action_return(self,request):
with transaction.atomic():
total_amount = decimal.Decimal(0)
for item in ReturnItem.objects.filter(master=self):
if item.cnt > item.out_item.cnt or item.cnt < 0:
raise Exception('%s cnt is invalid,out is %s,return is %s' % (item.material,item.out_cnt,item.cnt))
item.event_time = datetime.datetime.now()
item.source = self.code
item.status = 1
item.out_item.inventory.cnt += item.cnt
item.out_item.inventory.save()
item.save()
total_amount += item.price * item.cnt
self.amount = total_amount
self.status = '9'
self.execute_time = datetime.datetime.now()
self.save()
class Meta:
verbose_name = _("ware return")
verbose_name_plural = _("ware return")
class WareAdjust(generic.BO):
"""
库存调整
"""
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('9', _("EXECUTED"))
)
index_weight = 4
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_("description"),blank=True,null=True)
user = models.ForeignKey(User,verbose_name=_("out user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
execute_time = models.DateTimeField(_("execute time"),blank=True,null=True)
def action_adjust(self,request):
with transaction.atomic():
for item in AdjustItem.objects.filter(master=self,status=0):
inventory = item.inventory
if item.prop == '+':
inventory.cnt += item.cnt
else:
inventory.cnt -= item.cnt
inventory.save()
item.status = 1
item.event_time = datetime.datetime.now()
item.source = self.code
item.save()
self.status = '9'
self.execute_time = datetime.datetime.now()
self.save()
class Meta:
verbose_name = _("ware adjust")
verbose_name_plural = _("ware adjust")
class InOutDetail(models.Model):
"""
in out detail
"""
PROP = (
('+', _("PLUS")),
('-', _("MINUS"))
)
create_time = models.DateTimeField(_("create time"),auto_now_add=True)
status = models.BooleanField(_("executed"),default=0)
event_time = models.DateTimeField(_("event time"),blank=True,null=True)
warehouse = models.ForeignKey(Warehouse,verbose_name=_("warehouse"),blank=True,null=True)
material = models.ForeignKey(Material,verbose_name=_("material"),limit_choices_to={"is_virtual":"0"},blank=True,null=True)
measure = models.ForeignKey(Measure,verbose_name=_("measure"),blank=True,null=True)
cnt = models.DecimalField(_("count"),max_digits=14,decimal_places=4,blank=True,null=True)
batch = models.CharField(_("batch"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
price = models.DecimalField(_("price"),max_digits=14,decimal_places=4,blank=True,null=True)
prop = models.CharField(_("plus or minus property"),max_length=const.DB_CHAR_CODE_2,choices=PROP,default='+')
source = models.CharField(_("source"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
class InitItem(InOutDetail):
"""
期初入库明细
"""
master = models.ForeignKey(InitialInventory)
class Meta:
verbose_name = _("init item")
verbose_name_plural = _("init item")
class InItem(InOutDetail):
"""
入库单明细
"""
master = models.ForeignKey(StockIn)
po_item = models.ForeignKey(POItem,verbose_name=_("po item"),blank=True,null=True)
def get_new_price(self):
if self.po_item and self.master.warehouse:
try:
inventory = Inventory.objects.get(warehouse=self.master.warehouse,material=self.material,measure=self.measure)
if inventory and self.price != inventory.price:
total_amount = self.price*self.cnt+inventory.price*inventory.cnt
total_count = self.cnt+inventory.cnt
return total_amount/total_count
except Exception,e:
pass
return self.price or ''
class Meta:
verbose_name = _("in item")
verbose_name_plural = _("in item")
class InItemForm(forms.ModelForm):
new_price = forms.CharField(label=_('new price'),required=False)
class Meta:
model = InItem
fields = ('material', 'measure', 'cnt', 'price')
class OutItem(InOutDetail):
"""
出库单明细
"""
master = models.ForeignKey(StockOut)
inventory = models.ForeignKey(Inventory,blank=True,null=True,verbose_name=_("inventory material"))
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
self.prop = '-'
if self.inventory:
self.material = self.inventory.material
self.measure = self.inventory.measure
self.warehouse = self.inventory.warehouse
super(OutItem,self).save(force_insert,force_update,using,update_fields)
class Meta:
verbose_name = _("out item")
verbose_name_plural = _("out item")
class ReturnItem(InOutDetail):
"""
返库单明细
"""
master = models.ForeignKey(WareReturn)
out_item = models.ForeignKey(OutItem,blank=True,null=True,verbose_name=_('out item'))
out_cnt = models.DecimalField(_("out count"),max_digits=14,decimal_places=4)
class Meta:
verbose_name = _("return item")
verbose_name_plural = _("return item")
class AdjustItem(InOutDetail):
"""
库存调整明细
"""
master = models.ForeignKey(WareAdjust)
inventory = models.ForeignKey(Inventory,blank=True,null=True,verbose_name=_("inventory material"))
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.inventory:
self.material = self.inventory.material
self.measure = self.inventory.measure
self.warehouse = self.inventory.warehouse
super(AdjustItem,self).save(force_insert,force_update,using,update_fields)
class Meta:
verbose_name = _("adjust item")
verbose_name_plural = _("adjust item")
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+10
View File
@@ -0,0 +1,10 @@
from django.conf.urls import include, url,static
import invent.views
urlpatterns = [
url(r"stockin/(?P<object_id>\d+)/cin", 'invent.views.action_in'),
url(r"initialinventory/(?P<object_id>\d+)/cin", 'invent.views.action_init'),
url(r"stockout/(?P<object_id>\d+)/out", 'invent.views.action_out'),
url(r"warereturn/(?P<object_id>\d+)/cin", 'invent.views.action_return'),
url(r"wareadjust/(?P<object_id>\d+)/adjust", 'invent.views.action_adjust'),
]
+175
View File
@@ -0,0 +1,175 @@
# coding=utf-8
from django.contrib.admin import site
from django.contrib.contenttypes.models import ContentType
from django.db import connection
from django.http.response import HttpResponseRedirect
from django.utils.encoding import force_text
from django.template.response import TemplateResponse
from django.contrib import messages
from django.contrib.auth.models import User
from invent.models import StockIn,StockOut,InitialInventory,WareReturn,WareAdjust
from django.utils.translation import ugettext_lazy as _
def action_in(request,object_id):
"""
入库操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = StockIn.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
try:
obj.action_entry(request)
messages.success(request,_('check in successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/invent/stockin/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
def action_out(request,object_id):
"""
出库操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = StockOut.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
try:
obj.action_out(request)
messages.success(request,_('check out successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/invent/stockout/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockout/out_confirmation.html', context)
def action_init(request,object_id):
"""
期初入库操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = InitialInventory.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
try:
obj.init_entry(request)
messages.success(request,_('check in successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/invent/initialinventory/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
def action_return(request,object_id):
"""
返库操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = WareReturn.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
try:
obj.action_return(request)
messages.success(request,_('check in successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/invent/warereturn/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
def action_adjust(request,object_id):
"""
调整操作
:param request:
:param object_id:
:return:
"""
title = _("Are you sure?")
obj = WareAdjust.objects.get(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if request.POST.get("post"):
try:
obj.action_adjust(request)
messages.success(request,_('check in successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/invent/wareadjust/%s"%(object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
Binary file not shown.
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mis.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
+1
View File
@@ -0,0 +1 @@
__author__ = 'Administrator'
+176
View File
@@ -0,0 +1,176 @@
__author__ = 'zhugl'
# created at 15-4-21
#python import
from threading import local
from django.contrib import admin
from django.apps import apps
from django.conf import settings
from django.contrib.admin import ModelAdmin, actions
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.core.urlresolvers import NoReverseMatch, reverse
from django.db.models.base import ModelBase
from django.http import Http404, HttpResponseRedirect
from django.template.engine import Engine
from django.template.response import TemplateResponse
from django.utils import six
from django.utils.text import capfirst
from django.utils.translation import ugettext as _, ugettext_lazy
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
_thread_local = local()
def getuser():
return getattr(_thread_local,'user',None)
class RequestUser(object):
def process_request(self,request):
django_user = getattr(request,'user',None)
if django_user is not None:
_thread_local.user = django_user
def process_view(self, request, view_func, view_args, view_kwargs):
app_weight = {'selfhelp':1,'purchase':3,'sale':2,'invent':4,'organ':5,'basedata':6,'syscfg':7,'workflow':8}
if view_func.__name__ == 'index':
app_dict = {}
for model, model_admin in admin.site._registry.items():
app_label = model._meta.app_label
has_module_perms = model_admin.has_module_permission(request)
if has_module_perms:
perms = model_admin.get_model_perms(request)
if True in perms.values():
info = (app_label, model._meta.model_name)
model_dict = {
'name': capfirst(model._meta.verbose_name_plural),
'object_name': model._meta.object_name,
'perms': perms,
'weight':getattr(model,'index_weight',99)
}
if perms.get('change', False):
try:
model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=admin.site.name)
except NoReverseMatch:
pass
if perms.get('add', False):
try:
model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=admin.site.name)
except NoReverseMatch:
pass
if app_label in app_dict:
app_dict[app_label]['models'].append(model_dict)
else:
app_dict[app_label] = {
'name': apps.get_app_config(app_label).verbose_name,
'app_label': app_label,
'app_url': reverse(
'admin:app_list',
kwargs={'app_label': app_label},
current_app=admin.site.name,
),
'has_module_perms': has_module_perms,
'models': [model_dict],
'weight':app_weight.get(app_label,99)
}
app_list = list(six.itervalues(app_dict))
app_list.sort(key=lambda x: x['weight'])
for app in app_list:
app['models'].sort(key=lambda x: x['weight'])
context = dict(
maxi_app_list=app_list,
)
try:
todolist = self.get_my_task(request)
context.update(dict(todolist = todolist))
except Exception,e:
pass
# print context
view_kwargs['extra_context'] = context
if view_func.__name__ == 'app_index':
app_label = view_kwargs['app_label']
app_name = apps.get_app_config(app_label).verbose_name
app_dict = {}
lib_dict = {}
for model, model_admin in admin.site._registry.items():
if model_admin.has_module_permission(request):
label = model._meta.app_label
is_current = False
if label == app_label:
is_current = True
lib_dict[label] = {
'name': apps.get_app_config(label).verbose_name,
'app_label': label,
'app_url': reverse(
'admin:app_list',
kwargs={'app_label': label},
current_app=admin.site.name,
),
'weight':app_weight.get(label,99),
'is_current':is_current,
}
if app_label == model._meta.app_label:
has_module_perms = model_admin.has_module_permission(request)
if not has_module_perms:
raise PermissionDenied
perms = model_admin.get_model_perms(request)
if True in perms.values():
info = (app_label, model._meta.model_name)
model_dict = {
'name': capfirst(model._meta.verbose_name_plural),
'object_name': model._meta.object_name,
'perms': perms,
'weight':getattr(model,'index_weight',99)
}
if perms.get('change'):
try:
model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=admin.site.name)
except NoReverseMatch:
pass
if perms.get('add'):
try:
model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=admin.site.name)
except NoReverseMatch:
pass
if app_dict:
app_dict['models'].append(model_dict),
else:
app_dict = {
'name': app_name,
'app_label': app_label,
'app_url': '',
'has_module_perms': has_module_perms,
'models': [model_dict],
}
if not app_dict:
raise Http404('The requested admin page does not exist.')
# Sort the models alphabetically within each app.
app_dict['models'].sort(key=lambda x: x['weight'])
app_lib = list(six.itervalues(lib_dict))
app_lib.sort(key=lambda x: x['weight'])
context = dict(
maxi_app_list=[app_dict],
app_lib=app_lib,
)
view_kwargs['extra_context'] = context
def get_my_task(self,request):
from workflow.models import TodoList
if request and request.user:
query = TodoList.objects.filter(user=request.user,status=0)
if query.count() == 0:
return None
else:
return query.all()[:10]
+4
View File
@@ -0,0 +1,4 @@
from django.contrib import admin
admin.site.site_header = 'Django-ERP'
admin.site.site_title = 'ERP'
+127
View File
@@ -0,0 +1,127 @@
"""
Django settings for mis project.
Generated by 'django-admin startproject' using Django 1.8.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '_5%1a5zxdjsb-je@85!l34g--ve7!skhc%^c2n)3vqyhq)yq@c'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'syscfg',
'basedata',
'organ',
'workflow',
'selfhelp',
'hr',
'invent',
'purchase',
'sale',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'midware.cuser.RequestUser',
)
ROOT_URLCONF = 'mis.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
TEMPLATE_THEME = 'default'
WSGI_APPLICATION = 'mis.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '172.31.16.165',
'NAME': 'erp',
'USER': 'maximus',
'PASSWORD': 'maximus1234',
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'zh-CN'
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')]
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATICFILES_DIRS = (
('css',os.path.join(STATIC_ROOT,'css')),
('js',os.path.join(STATIC_ROOT,'js')),
('img',os.path.join(STATIC_ROOT,'img')),
)
MEDIA_ROOT = os.path.join(BASE_DIR,'upload')
MEDIA_URL = '/upload/'
+127
View File
@@ -0,0 +1,127 @@
"""
Django settings for mis project.
Generated by 'django-admin startproject' using Django 1.8.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '_5%1a5zxdjsb-je@85!l34g--ve7!skhc%^c2n)3vqyhq)yq@c'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'syscfg',
'basedata',
'organ',
'workflow',
'selfhelp',
'hr',
'invent',
'purchase',
'sale',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'midware.cuser.RequestUser',
)
ROOT_URLCONF = 'mis.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
TEMPLATE_THEME = 'default'
WSGI_APPLICATION = 'mis.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'NAME': 'mis',
'USER': 'root',
'PASSWORD': 'root',
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'zh-CN'
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')]
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATICFILES_DIRS = (
('css',os.path.join(STATIC_ROOT,'css')),
('js',os.path.join(STATIC_ROOT,'js')),
('img',os.path.join(STATIC_ROOT,'img')),
)
MEDIA_ROOT = os.path.join(BASE_DIR,'upload')
MEDIA_URL = '/upload/'
+23
View File
@@ -0,0 +1,23 @@
from django.conf.urls import include, url,static
from django.contrib import admin
from mis import settings
import workflow
import invent.urls
import basedata.urls
import selfhelp.urls
import mis
urlpatterns = [
# Examples:
url(r'^$', 'mis.views.home'),
# url(r'^blog/', include('blog.urls')),
url(r"^admin/(?P<app>\w+)/(?P<model>\w+)/(?P<object_id>\d+)/start",'workflow.views.start'),
url(r"^admin/(?P<app>\w+)/(?P<model>\w+)/(?P<object_id>\d+)/approve/(?P<operation>\d+)",'workflow.views.approve'),
url(r"^admin/(?P<app>\w+)/(?P<model>\w+)/(?P<object_id>\d+)/restart/(?P<instance>\d+)",'workflow.views.restart'),
url(r'^admin/', include(admin.site.urls)),
url(r'^admin/invent/', include(invent.urls)),
url(r'^admin/basedata/', include(basedata.urls)),
url(r'^admin/selfhelp/', include(selfhelp.urls)),
]
urlpatterns += static.static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static.static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
+5
View File
@@ -0,0 +1,5 @@
from django.http.response import HttpResponseRedirect
def home(request):
return HttpResponseRedirect("/admin")
+16
View File
@@ -0,0 +1,16 @@
"""
WSGI config for mis project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mis.settings")
application = get_wsgi_application()
+1
View File
@@ -0,0 +1 @@
default_app_config = 'organ.apps.OrganConfig'
+68
View File
@@ -0,0 +1,68 @@
# coding=utf-8
from django.contrib import admin
from common import generic
from organ.models import Organization,OrgUnit,Position
from basedata.models import BankAccount
from basedata.admin import BankAccountInline
import datetime
class OrgAdmin(generic.BOAdmin):
CODE_PREFIX = 'O'
CODE_NUMBER_WIDTH = 2
list_display = ['code','name','represent','lic_code','cer_code']
fields = (
('name','code',),('short','pinyin',),
('tax_num','tax_account',),('tax_address',),('represent','email',),
('address','zipcode',),('contacts','phone',),('fax','website',),
('lic_code','cer_code',),('license','certificate',),('status','weight',),
)
inlines = [BankAccountInline]
class OrgUnitAdmin(generic.BOAdmin):
CODE_PREFIX = 'S'
CODE_NUMBER_WIDTH = 3
list_display = ['code','name','unit_type','parent']
list_display_links = ['code','name']
fields = (
('organization',),('parent',),('name','code',),('short','pinyin',),
('unit_type',),('status','virtual',),('phone','fax',),
('contacts','email',),('weight',),
)
def get_queryset(self, request):
return super(OrgUnitAdmin,self).get_queryset(request).filter(end__gt=datetime.date.today())
def save_model(self, request, obj, form, change):
if obj.parent and obj.parent.organization:
obj.organization = obj.parent.organization
obj.save()
super(OrgUnitAdmin,self).save_model(request,obj,form,change)
class PositionAdmin(generic.BOAdmin):
CODE_PREFIX = 'P'
CODE_NUMBER_WIDTH = 4
list_display = ['code','name','unit','series','grade','parent']
list_display_links = ['code','name']
fields = (
('unit',),('organization',),('parent',),('name','code',),('short','pinyin',),('series','grade',),
('virtual','status'),('description',),('qualification',),('document',),('weight',),
)
readonly_fields = ['organization']
def get_queryset(self, request):
return super(PositionAdmin,self).get_queryset(request).filter(end__gt=datetime.date.today())
def save_model(self, request, obj, form, change):
if obj.unit:
obj.organization = obj.unit.organization
obj.save()
super(PositionAdmin,self).save_model(request,obj,form,change)
admin.site.register(Position,PositionAdmin)
admin.site.register(OrgUnit,OrgUnitAdmin)
admin.site.register(Organization,OrgAdmin)
+9
View File
@@ -0,0 +1,9 @@
__author__ = 'zhugl'
# created at 15-4-22
from django.apps.config import AppConfig
from django.utils.translation import ugettext_lazy as _
class OrganConfig(AppConfig):
name = 'organ'
verbose_name = _('organization')
+115
View File
@@ -0,0 +1,115 @@
# coding=utf-8
from django.db import models
from django.db import connection
from django.utils.translation import ugettext_lazy as _
from common import const
from common import generic
class Organization(generic.BO):
"""
组织单位
"""
index_weight = 1
code = models.CharField(_("organ code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
name = models.CharField(_("organ name"),max_length=const.DB_CHAR_NAME_120)
short = models.CharField(_("short name"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
status = models.BooleanField(_("in use"),default=True)
tax_num = models.CharField(_("tax num"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
tax_address = models.CharField(_("tax address"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
tax_account = models.CharField(_("tax account"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
represent = models.CharField(_("representative "),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
address = models.CharField(_("address"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
zipcode = models.CharField(_("zipcode"),max_length=const.DB_CHAR_CODE_8,blank=True,null=True)
fax = models.CharField(_("fax"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
contacts = models.CharField(_("contacts"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
website = models.CharField(_("website"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
email = models.CharField(_("email"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
lic_code = models.CharField(_("license code"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
cer_code = models.CharField(_("certificate code"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
license = models.FileField(_("business license"),blank=True,null=True,upload_to='organ')
certificate = models.FileField(_("organization code certificate"),blank=True,null=True,upload_to='organ')
weight = models.IntegerField(_("weight"),default=9)
class Meta:
verbose_name = _('organization')
verbose_name_plural = _('organization')
class OrgUnit(generic.BO):
"""
组织单元
"""
UNIT_LEVEL = (
(1,_('BRANCH')),
(2,_('DEPARTMENT')),
(3,_('OFFICE')),
(4,_('TEAM')),
(5,_('COMMITTEE'))
)
index_weight = 2
parent = models.ForeignKey('self',verbose_name=_("parent"),null=True,blank=True)
organization = models.ForeignKey(Organization,verbose_name = _('organization'),null=True,blank=True)
code = models.CharField(_("code"),max_length=const.DB_CHAR_CODE_8,blank=True,null=True)
name = models.CharField(_("name"),max_length=const.DB_CHAR_NAME_120)
short = models.CharField(_("short name"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
unit_type = models.IntegerField(_("type"),choices=UNIT_LEVEL,default=2)
status = models.BooleanField(_("in use"),default=True)
virtual = models.BooleanField(_("is virtual"),default=False)
fax = models.CharField(_("fax"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
contacts = models.CharField(_("contacts"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
email = models.CharField(_("email"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
weight = models.IntegerField(_("weight"),default=99)
class Meta:
verbose_name = _('org unit')
verbose_name_plural = _('org unit')
class Position(generic.BO):
"""
岗位
"""
SERIES = (
('A',_("Admin Position")),
('S',_("Sale Position")),
('T',_("Technology Position")),
('P',_("Produce Position")),
)
GRADE = (
('01', _("BASIC")),
('02', _("MEDIUM")),
('03', _("SENIOR")),
('04', _("PROFESSOR")),
('05', _("EXPERT")),
)
index_weight = 3
unit = models.ForeignKey(OrgUnit,verbose_name=_('org unit'))
organization = models.ForeignKey(Organization,verbose_name=_('organization'),null=True,blank=True)
parent = models.ForeignKey('self',verbose_name=_("parent"),null=True,blank=True)
code = models.CharField(_("position code"),max_length=const.DB_CHAR_CODE_8,blank=True,null=True)
name = models.CharField(_("position name"),max_length=const.DB_CHAR_NAME_120)
short = models.CharField(_("short name"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
pinyin = models.CharField(_("pinyin"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
series = models.CharField(_("position series"),max_length=1,default='A',choices=const.get_value_list('S014'))
grade = models.CharField(_("position grade"),max_length=const.DB_CHAR_CODE_2,default='01',choices=const.get_value_list('S015'))
virtual = models.BooleanField(_("is virtual"),default=False)
status = models.BooleanField(_("in use"),default=True)
description = models.TextField(_("position description"),blank=True,null=True)
qualification = models.TextField(_("qualification"),blank=True,null=True)
document = models.FileField(_("reference"),blank=True,null=True)
weight = models.IntegerField(_("weight"),default=99)
def __unicode__(self):
return u'%s %s' % (self.code,self.name)
class Meta:
verbose_name = _('position')
verbose_name_plural = _('position')
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+3
View File
@@ -0,0 +1,3 @@
# created at 15-6-27
# coding=utf-8
__author__ = 'zhugl'
+54
View File
@@ -0,0 +1,54 @@
# created at 15-6-30
# coding=utf-8
__author__ = 'zhugl'
class Operation(object):
APPROVE = 1
DENY = 3
TERMINATE = 4
class WorkflowAction(object):
name = ''
description = ''
def action(self,request,obj,node_config,operation=Operation.APPROVE):
"""
:param request:
:param obj:
:param node_config:
:return:
"""
class TestAction(WorkflowAction):
name = 'action.test'
def action(self,request,obj,node_config,operation=Operation.APPROVE):
print 'this is a workflow test action'
print 'request user is %s,current node is %s'%(request.user,node_config)
class WorkflowActionManager(object):
"""
"""
actions = {}
registed = False
def __init__(self):
if WorkflowActionManager.registed:
pass
else:
WorkflowActionManager.register(TestAction)
WorkflowActionManager.registed = True
@classmethod
def register(cls,action):
if cls.actions.get(action.name):
raise Exception('%s already exists,register failed'%action.name)
if issubclass(action,WorkflowAction):
WorkflowActionManager.actions[action.name] = action()
+54
View File
@@ -0,0 +1,54 @@
# created at 15-6-30
# coding=utf-8
__author__ = 'zhugl'
from workflow.models import Node
class NextNodeHandler(object):
"""
"""
name = ''
description = ''
def handle(self,request,obj,node_config):
"""
:param request:
:param obj:
:param node_config:
:return:workflow.models.Node
"""
return None
class TestHandler(NextNodeHandler):
name = 'project.budge.gt.10000'
description = '预算金额大于10000,由总经理审批'
def handle(self,request,obj,node_config):
budget = getattr(obj,'budget',None)
if budget and budget > 10000:
return Node.objects.filter(id=7).all()
class NextNodeManager(object):
"""
"""
handlers = {}
registed = False
def __init__(self):
if NextNodeManager.registed:
pass
else:
NextNodeManager.register(TestHandler)
NextNodeManager.registed = True
@classmethod
def register(cls,handler):
if cls.handlers.get(handler.name):
raise Exception('%s already exists,register failed'%handler.name)
if issubclass(handler,NextNodeHandler):
NextNodeManager.handlers[handler.name] = handler()
+67
View File
@@ -0,0 +1,67 @@
# created at 15-6-30
# coding=utf-8
__author__ = 'zhugl'
class NextUserHandler(object):
"""
"""
name = ''
description = ''
def handle(self,request,obj,node_config):
"""
:param request:
:param obj:
:param node_config:
:return:django.contrib.auth.models.User[]
"""
return None
class UpPosition(NextUserHandler):
"""
"""
name = 'up.position.user'
def handle(self,request,obj,node_config):
from basedata.models import Employee,Position
emp_query = Employee.objects.filter(user=request.user)
if emp_query.count()>0:
emp = emp_query.all()
parent = []
for e in emp:
if e.position and e.position.parent:
parent.append(e.position.parent)
# print emp
# print parent
query2 = Employee.objects.filter(position__in=parent).exclude(user=None)
return [x.user for x in query2.all()]
else:
return None
class NextUserManager(object):
"""
"""
handlers = {}
registed = False
def __init__(self):
if NextUserManager.registed:
pass
else:
NextUserManager.register(UpPosition)
NextUserManager.registed = True
@classmethod
def register(cls,handler):
if cls.handlers.get(handler.name):
raise Exception('%s already exists,register failed'%handler.name)
if issubclass(handler,NextUserHandler):
NextUserManager.handlers[handler.name] = handler()
+183
View File
@@ -0,0 +1,183 @@
# created at 15-6-27
# coding=utf-8
__author__ = 'zhugl'
import xlrd
import os
import datetime
from mis import settings
class Handler(object):
name = ''
def handle(self,obj,f):
pass
class OPSHandler(Handler):
"""
导入基础信息:部门,岗位,职员
"""
name = 'OPS'
def handle(self,obj,f):
if f and f.name.endswith('.xls'):
path = os.path.join(settings.MEDIA_ROOT,f.name)
workbook = xlrd.open_workbook(path)
for sheet in workbook.sheets():
if sheet.name == u'部门' or sheet.name == 'department':
self.department(obj,sheet)
elif sheet.name == u'岗位' or sheet.name == 'position':
self.position(obj,sheet)
elif sheet.name == u'职员' or sheet.name == 'employee':
self.stuff(obj,sheet)
def department(self,obj,sheet):
from organ.models import OrgUnit
row_count = sheet.nrows
if obj.is_clear:
OrgUnit.objects.update(end=datetime.date.today())
for row_index in range(1,row_count):
row = sheet.row_values(row_index)
weight = 99
if row[6]:
weight = row[6]
OrgUnit.objects.create(code=row[0],name=row[1],short=row[2],pinyin=row[3],begin=datetime.date.today(),
end=datetime.date(9999,12,31),weight=weight)
for row_index in range(1,row_count):
row = sheet.row_values(row_index)
if len(row[4]) > 0:
try:
parent = OrgUnit.objects.get(code=row[4])
OrgUnit.objects.filter(code=row[0]).update(parent=parent)
except Exception,e:
pass
def position(self,obj,sheet):
from organ.models import Position,OrgUnit
row_count = sheet.nrows
if obj.is_clear:
Position.objects.update(end=datetime.date.today())
for row_index in range(1,row_count):
row = sheet.row_values(row_index)
depart = None
if len(row[4]) > 0:
try:
depart = OrgUnit.objects.filter(code=row[4],end__gt=datetime.date.today()).all()[0]
except Exception,e:
pass
weight = 99
if row[6]:
weight = row[6]
Position.objects.create(code=row[0],name=row[1],unit=depart,begin=datetime.date.today(),
end=datetime.date(9999,12,31),weight=weight)
for row_index in range(1,row_count):
row = sheet.row_values(row_index)
if len(row[2]) > 0:
try:
parent = Position.objects.filter(code=row[2],end__gt=datetime.date.today()).all()[0]
Position.objects.filter(code=row[0]).update(parent=parent)
except Exception,e:
pass
def stuff(self,obj,sheet):
from organ.models import Position
from basedata.models import Employee
from django.contrib.auth.models import User,Group
row_count = sheet.nrows
try:
group = Group.objects.get_by_natural_key(u'职员')
except Exception,e:
pass
for row_index in range(1,row_count):
row = sheet.row_values(row_index)
position = Position.objects.filter(code=row[8],end__gt=datetime.date.today()).all()[0]
username = row[10]
email = row[11]
password = row[4][-6:]
if position is None:
raise Exception(u'职员%s-%s未分配岗位,或者您选择的岗位已失效,不可被引用'%(row[0],row[1]))
try:
employee = Employee.objects.get(code=row[0])
if employee.position.code == row[8]:
continue
else:
employee.position = position
employee.save()
except Exception,e:
employee = Employee.objects.create(code=row[0],name=row[1],pinyin=row[2],gender=row[3],idcard=row[4],
birthday=row[5],workday=row[6],startday=row[7],position=position)
if username:
try:
user = User.objects.get_by_natural_key(username)
except Exception,e:
user = User.objects.create_user(username=username,password=password)
user.is_staff = True
user.is_active = True
user.first_name = row[1]
if email:
user.email = email
if group:
user.groups.add(group)
user.save()
employee.user = user
employee.save()
class UserHandler(Handler):
"""
基础数据导入:用户
"""
name = 'admin.user'
def handle(self,obj,f):
from django.contrib.auth.models import User,Group
if f and f.name.endswith('.xls'):
path = os.path.join(settings.MEDIA_ROOT,f.name)
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
row_count = sheet.nrows
try:
group = Group.objects.get_by_natural_key(u'职员')
except Exception,e:
pass
for row_index in range(2,row_count):
row = sheet.row_values(row_index)
username = row[0]
password = row[1]
last_name = row[2]
first_name = row[3]
email = row[4]
if username == '':
continue
try:
user = User.objects.get_by_natural_key(username)
except Exception,e:
user = User.objects.create_user(username=username,password=password,email=email)
user.is_staff = True
user.is_active = True
user.last_name = last_name
user.first_name = first_name
if group:
user.groups.add(group)
user.save()
class ExcelManager(object):
"""
"""
handlers = {}
def __init__(self):
ExcelManager.register(OPSHandler)
ExcelManager.register(UserHandler)
@classmethod
def register(cls,handler):
if cls.handlers.get(handler.name):
raise Exception('%s already exists,register failed'%handler.name)
if issubclass(handler,Handler):
ExcelManager.handlers[handler.name] = handler()
+1
View File
@@ -0,0 +1 @@
default_app_config = "purchase.apps.MyAppConfig"
+90
View File
@@ -0,0 +1,90 @@
from django.contrib import admin
from common import generic
from purchase.models import PurchaseOrder,POItem,Invoice,Payment
from basedata.models import Partner,BankAccount
class POItemInline(admin.TabularInline):
model = POItem
fields = ('material', 'measure','price', 'cnt', 'tax', 'discount_price')
raw_id_fields = ['material']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class PurchaseOrderAdmin(generic.BOAdmin):
"""
"""
CODE_PREFIX = 'CG'
CODE_NUMBER_WIDTH = 5
list_display = ['code','title','order_date','partner','amount','discount_amount','payed_amount','invoice_amount','status']
list_display_links = ['code','title']
raw_id_fields = ['partner']
fields = (
('code','partner'),('order_date','arrive_date'),
('title','status',),('description',),('amount','discount_amount'),('attach',),
)
readonly_fields = ['status','amount']
inlines = [POItemInline]
date_hierarchy = 'begin'
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id:
extra_context = extra_context or {}
obj = PurchaseOrder.objects.get(id=object_id)
if obj.status == '99':
extra_context.update(dict(readonly=True))
return super(PurchaseOrderAdmin,self).changeform_view(request,object_id,form_url,extra_context)
def get_changeform_initial_data(self, request):
import datetime
begin = datetime.date.today()
end = begin + datetime.timedelta(30)
return {'order_date':begin,'arrive_date':end}
class PurchaseItemAdmin(generic.BOAdmin):
list_display = ['po','vender','material','cnt','price','tax']
readonly_fields = ['po','material','cnt','price','tax']
def get_queryset(self, request):
return POItem.objects.filter(left_cnt__gt=0)
class InvoiceAdmin(generic.BOAdmin):
list_display = ['code','number','vo_date','po','partner','po_amount','vo_amount']
readonly_fields = ['partner','po_amount']
raw_id_fields = ['po']
search_fields = ['po__code','partner__name']
date_hierarchy = 'begin'
fields = (
('vo_date',),('po',),('po_amount','partner',),('code',),('number',),('vo_amount',),('file',)
)
class PaymentAdmin(generic.BOAdmin):
CODE_PREFIX = 'PY'
CODE_NUMBER_WIDTH = 4
list_display = ['code','py_date','po','partner','po_amount','py_amount']
readonly_fields = ['partner','po_amount']
raw_id_fields = ['po']
search_fields = ['po__code','partner__name']
fields = (
('py_date','code',),('po',),('partner','po_amount',),('py_amount',),('bank',),('response_code'),('memo',)
)
date_hierarchy = 'begin'
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'bank':
kwargs['queryset'] = BankAccount.objects.exclude(org__exact=None)
return super(PaymentAdmin,self).formfield_for_foreignkey(db_field,request,**kwargs)
admin.site.register(PurchaseOrder,PurchaseOrderAdmin)
admin.site.register(POItem,PurchaseItemAdmin)
admin.site.register(Invoice,InvoiceAdmin)
admin.site.register(Payment,PaymentAdmin)
+11
View File
@@ -0,0 +1,11 @@
# created at 15-5-23
# coding=utf-8
__author__ = 'zhugl'
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class MyAppConfig(AppConfig):
name = 'purchase'
verbose_name = _("purchase manage")
+221
View File
@@ -0,0 +1,221 @@
# coding=utf-8
import datetime
import os
import xlrd
import decimal
from django.db import transaction
from django.db import models
from django.db.models.aggregates import Sum
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.utils.text import force_text
from mis import settings
from common import generic
from common import const
from selfhelp.models import WOItem
from basedata.models import Material,Organization,Partner,Measure,BankAccount
class PurchaseOrder(generic.BO):
"""
"""
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('4', _("DROP")),
('9', _("APPROVED")),
('99', _("ALREADY STOCK IN")),
)
index_weight = 1
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
partner = models.ForeignKey(Partner,verbose_name=_("partner"),limit_choices_to={"partner_type":"S"})
order_date = models.DateField(_("order date"))
arrive_date = models.DateField(_("arrive date"))
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_("description"),blank=True,null=True)
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
amount = models.DecimalField(_("money amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
discount_amount = models.DecimalField(_("discount amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
entry_status = models.BooleanField(_("entry status"),default=0)
entry_time = models.DateTimeField(_("entry time"),blank=True,null=True)
attach = models.FileField(_('attach'),blank=True,null=True,help_text=u'您可导入采购明细,模板请参考文档FD0008')
def __unicode__(self):
return u'%s %s' % (self.code,self.title)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(PurchaseOrder,self).save(force_insert,force_update,using,update_fields)
if self.discount_amount > 0:
sql = 'UPDATE purchase_poitem a SET a.discount_price = ' \
'a.price-((SELECT discount_amount/amount FROM purchase_purchaseorder WHERE id=%s)*a.amount/a.cnt) WHERE a.po_id = %s'
params = [self.id,self.id]
generic.update(sql,params)
item_count = POItem.objects.filter(po=self).count()
if self.attach and item_count == 0:
path = os.path.join(settings.MEDIA_ROOT,self.attach.name)
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
row_count = sheet.nrows
with transaction.atomic():
total_amount = decimal.Decimal(0)
for row_index in range(row_count):
row = sheet.row_values(row_index)
if row_index == 0:
doc_type = row[1]
if doc_type.startswith('0'):
break
else:
continue
elif row_index < 3:
continue
material = None
measure = None
try:
measure = Measure.objects.get(code=row[4])
except Exception,e:
measure = Measure.objects.create(code=row[4],name=force_text(row[5]))
try:
material = Material.objects.get(code=row[0])
except Exception,e:
material = Material(code=row[0],name=force_text(row[1]),spec=force_text(row[2]))
material.purchase_price = row[6]
material.save()
amount = decimal.Decimal(row[6])*decimal.Decimal(row[7])
POItem.objects.create(po=self,material=material,measure=measure,cnt=row[7],price=row[6],amount=amount)
total_amount += amount
sql = 'update purchase_purchaseorder set amount = %s where id=%s'
params = [total_amount,self.id]
generic.update(sql,params)
def invoice_amount(self):
total = Invoice.objects.filter(po=self).aggregate(Sum('vo_amount')).get('vo_amount__sum') or 0.00
return total
def payed_amount(self):
return Payment.objects.filter(po=self).aggregate(Sum('py_amount')).get('py_amount__sum') or 0.00
invoice_amount.short_description = _('invoice amount')
payed_amount.short_description = _('pay amount')
class Meta:
verbose_name = _("purchase order")
verbose_name_plural = _("purchase orders")
class POItem(models.Model):
"""
"""
index_weight = 2
po = models.ForeignKey(PurchaseOrder,verbose_name=_("purchase order"))
material = models.ForeignKey(Material,verbose_name=_("material"),limit_choices_to={"is_virtual":"0"})
measure = models.ForeignKey(Measure,verbose_name=_("measure"),blank=True,null=True)
price = models.DecimalField(_("price"),max_digits=12,decimal_places=4,blank=True,null=True)
cnt = models.DecimalField(_("count"),max_digits=12,decimal_places=4,blank=True,null=True)
discount_price = models.DecimalField(_("discount price"),max_digits=12,decimal_places=4,blank=True,null=True)
amount = models.DecimalField(_("money of amount"),max_digits=12,decimal_places=2,blank=True,null=True)
discount_amount = models.DecimalField(_("discount amount"),max_digits=12,decimal_places=2,blank=True,null=True)
tax = models.CharField(_("tax rate"),max_length=const.DB_CHAR_CODE_6,choices=const.get_value_list('S052'),default='0.00')
woitem = models.ForeignKey(WOItem,verbose_name=_("wo item"),blank=True,null=True)
is_in_stock = models.BooleanField(_("is in stock"),default=0)
in_stock_time = models.DateTimeField(_("execute time"),blank=True,null=True)
entry_cnt = models.DecimalField(_("entry count"),max_digits=12,decimal_places=4,blank=True,null=True)
left_cnt = models.DecimalField(_("left count"),max_digits=12,decimal_places=4,blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.price and self.cnt:
money = self.price * self.cnt
self.amount = money
if self.measure is None and self.material and self.material.measure.count() > 0:
self.measure = self.material.measure.all()[0]
if self.is_in_stock:
self.left_cnt -= self.entry_cnt
else:
self.left_cnt = self.cnt
super(POItem,self).save(force_insert,force_update,using,update_fields)
self.material.purchase_price = self.price
self.material.save()
sql = 'UPDATE purchase_purchaseorder SET amount = (SELECT SUM(a.price*a.cnt) AS amount FROM ' \
'purchase_poitem a WHERE a.po_id = %s) WHERE id = %s'
params = [self.po.id,self.po.id]
generic.update(sql,params)
def vender(self):
return u'%s' % (self.po.partner)
vender.short_description = _("partner")
class Meta:
verbose_name = _("po item")
verbose_name_plural = _("po item")
class Invoice(generic.BO):
"""
采购发票
"""
index_weight = 4
vo_date = models.DateField(_("invoice date"),blank=True,null=True,default=datetime.date.today)
code = models.CharField(_("invoice code"),max_length=const.DB_CHAR_NAME_20)
number = models.CharField(_("invoice number"),max_length=const.DB_CHAR_NAME_20)
po = models.ForeignKey(PurchaseOrder,verbose_name=_("purchase order"))
partner = models.ForeignKey(Partner,verbose_name=_("partner"),blank=True,null=True)
po_amount = models.DecimalField(_("po amount"),max_digits=14,decimal_places=4,blank=True,null=True)
vo_amount = models.DecimalField(_("invoice amount"),max_digits=14,decimal_places=4)
file = models.FileField(_("invoice file"),upload_to='invoice',blank=True,null=True)
def __unicode__(self):
return u"%s %s" % (self.code,self.partner)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.po:
self.partner = self.po.partner
self.po_amount = self.po.amount
super(Invoice,self).save(force_insert,force_update,using,update_fields)
class Meta:
verbose_name = _("Invoice")
verbose_name_plural = _("Invoice")
class Payment(generic.BO):
"""
采购付款
"""
index_weight = 3
py_date = models.DateField(_("pay date"),blank=True,null=True,default=datetime.date.today)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
code = models.CharField(_("pay code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
po = models.ForeignKey(PurchaseOrder,verbose_name=_("purchase order"))
partner = models.ForeignKey(Partner,verbose_name=_("partner"),blank=True,null=True)
po_amount = models.DecimalField(_("po amount"),max_digits=14,decimal_places=4,blank=True,null=True)
py_amount = models.DecimalField(_("pay amount"),max_digits=14,decimal_places=4)
bank = models.ForeignKey(BankAccount,verbose_name=_("bank account"),blank=True,null=True)
response_code = models.CharField(_("response code"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
memo = models.TextField(_("memo"),blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.po:
self.partner = self.po.partner
self.po_amount = self.po.amount
super(Payment,self).save(force_insert,force_update,using,update_fields)
def __unicode__(self):
return u"%s %s" % (self.code,self.partner)
class Meta:
verbose_name = _("Payment")
verbose_name_plural = _("Payment")
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+1
View File
@@ -0,0 +1 @@
default_app_config = "sale.apps.MyAppConfig"
+104
View File
@@ -0,0 +1,104 @@
from django.contrib import admin
from common import generic
from sale.models import SaleOrder,SaleItem,PaymentCollection,OfferSheet,OfferItem
from basedata.models import Measure,BankAccount
from common import generic
import datetime
class SaleItemInline(admin.TabularInline):
model = SaleItem
fields = ('material','measure','sale_price','discount_price','cnt','tax')
raw_id_fields = ['material']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class OfferItemInline(admin.TabularInline):
model = OfferItem
fields = ('material','brand','measure','cost_price','sale_price','discount_price','cnt','tax')
raw_id_fields = ['material']
readonly_fields = ['brand']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 3
class SaleOrderAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 5
CODE_PREFIX = 'SO'
inlines = [SaleItemInline]
list_display = ['code','title','order_date','partner','amount','collection_amount']
list_display_links = ['code','title']
raw_id_fields = ['partner','user','org']
fields = (
('code','org',),('title','invoice_type',),('partner','user',),('order_date','deliver_date',),
('contact','phone',),('deliver_address','fax',),('description',),('amount','discount_amount','status')
)
readonly_fields = ['amount','status']
date_hierarchy = 'begin'
def save_model(self, request, obj, form, change):
if obj:
obj.user = request.user
super(SaleOrderAdmin,self).save_model(request,obj,form,change)
def get_changeform_initial_data(self, request):
today = datetime.datetime.today()
deadline = today+datetime.timedelta(days=30)
return {'order_date':today,'deliver_date':deadline}
class OfferSheetAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 5
CODE_PREFIX = 'BJ'
inlines = [OfferItemInline]
list_display = ['code','title','offer_date','partner','amount']
list_display_links = ['code','title']
raw_id_fields = ['partner','user','org']
fields = (
('code','org',),('partner','user',),('offer_date','deliver_date',),('title',),
('description',),('amount','discount_amount',),('attach'),
)
readonly_fields = ['amount']
date_hierarchy = 'begin'
def save_model(self, request, obj, form, change):
if obj:
obj.user = request.user
super(OfferSheetAdmin,self).save_model(request,obj,form,change)
def get_changeform_initial_data(self, request):
today = datetime.datetime.today()
deadline = today+datetime.timedelta(days=30)
return {'offer_date':today,'deliver_date':deadline}
class PaymentCollectionAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 4
CODE_PREFIX = 'CP'
list_display = ['code','so','partner','order_amount','collection_date','collection_amount']
fields = (
('code',),('collection_date',),('so',),('partner',),('order_amount','collection_amount',),('bank',),
('memo',)
)
raw_id_fields = ['so','partner']
readonly_fields = ['order_amount']
list_display_links = ['code','so']
date_hierarchy = 'begin'
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name=='bank':
kwargs['queryset'] = BankAccount.objects.exclude(org__exact=None)
return super(PaymentCollectionAdmin,self).formfield_for_foreignkey(db_field,request,**kwargs)
admin.site.register(SaleOrder,SaleOrderAdmin)
admin.site.register(PaymentCollection,PaymentCollectionAdmin)
admin.site.register(OfferSheet,OfferSheetAdmin)
+11
View File
@@ -0,0 +1,11 @@
# created at 15-5-23
# coding=utf-8
__author__ = 'zhugl'
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class MyAppConfig(AppConfig):
name = 'sale'
verbose_name = _("sale management")
+252
View File
@@ -0,0 +1,252 @@
# coding=utf-8
import decimal
import datetime
import csv
import os
import xlrd
from mis import settings
from django.db import models
from django.db import transaction
from django.db.models.aggregates import Sum
from django.contrib.auth.models import User
from django.utils.text import force_text
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from basedata.models import Material,Project,Partner,Organization,Measure,BankAccount
class SaleOrder(generic.BO):
"""
销售订单
"""
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('4', _("DROP")),
('9', _("APPROVED")),
('99', _("ALREADY STOCK OUT")),
)
index_weight = 2
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
partner = models.ForeignKey(Partner,verbose_name=_("partner"),limit_choices_to={"partner_type":"C"})
order_date = models.DateField(_("order date"))
deliver_date = models.DateField(_("deliver date"))
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_("memo"),blank=True,null=True)
contact = models.CharField(_("contacts"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
phone = models.CharField(_("phone"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
fax = models.CharField(_("fax"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
deliver_address = models.CharField(_("deliver address"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
invoice_type = models.CharField(_("invoice type"),max_length=const.DB_CHAR_CODE_6,choices=const.get_value_list('S053'),default='10')
amount = models.DecimalField(_("money amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
discount_amount = models.DecimalField(_("discount amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
user = models.ForeignKey(User,verbose_name=_("sales man"),blank=True,null=True)
status = models.CharField(_("status"),max_length=const.DB_CHAR_CODE_2,default='0',choices=STATUS)
def __unicode__(self):
return u'%s %s' % (self.code,self.title)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(SaleOrder,self).save(force_insert,force_update,using,update_fields)
if self.discount_amount > 0:
sql = 'UPDATE sale_saleitem a SET a.discount_price = a.sale_price - ' \
'((SELECT discount_amount/amount FROM sale_saleorder WHERE id = %s) * (a.sale_price*a.cnt)/a.cnt) WHERE a.master_id = %s'
params = [self.id,self.id]
generic.update(sql,params)
def collection_amount(self):
return PaymentCollection.objects.filter(so=self).aggregate(Sum('collection_amount')).get('collection_amount__sum') or 0.00
collection_amount.short_description = _('collection amount')
class Meta:
verbose_name = _('sale order')
verbose_name_plural = _('sale order')
class SaleItem(models.Model):
"""
订单明细
"""
master = models.ForeignKey(SaleOrder)
material = models.ForeignKey(Material,verbose_name=_("material"),limit_choices_to={"is_virtual":"0",'can_sale':'1'},blank=True,null=True)
measure = models.ForeignKey(Measure,verbose_name=_("measure"),blank=True,null=True)
cnt = models.DecimalField(_("count"),max_digits=14,decimal_places=4)
stock_price = models.DecimalField(_("stock price"),max_digits=14,decimal_places=4,blank=True,null=True)
sale_price = models.DecimalField(_("sale price"),max_digits=14,decimal_places=4,blank=True,null=True)
discount_price = models.DecimalField(_("discount price"),max_digits=14,decimal_places=4,blank=True,null=True)
tax = models.CharField(_("tax rate"),max_length=const.DB_CHAR_CODE_6,choices=const.get_value_list('S052'),default='0.00')
create_time = models.DateTimeField(_("create time"),auto_now_add=True)
status = models.BooleanField(_("executed"),default=0)
event_time = models.DateTimeField(_("event time"),blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.material and self.material.measure.count() > 0:
self.measure = self.material.measure.all()[0]
if self.material.sale_price or self.material.stock_price:
self.sale_price = self.material.sale_price or self.material.stock_price*decimal.Decimal(1.17)/decimal.Decimal(0.6)
super(SaleItem,self).save(force_insert,force_update,using,update_fields)
sql = 'update sale_saleorder set amount = (select sum(sale_price*cnt) from sale_saleitem where master_id=%s) where id=%s'
params = [self.master.id,self.master.id]
# print sql % (self.master.id,self.master.id)
generic.update(sql,params)
class Meta:
verbose_name = _('order detail')
verbose_name_plural = _('order detail')
class PaymentCollection(generic.BO):
"""
销售回款
"""
index_weight = 3
collection_date = models.DateField(_("collection date"),blank=True,null=True,default=datetime.date.today)
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
code = models.CharField(_("collection code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
so = models.ForeignKey(SaleOrder,verbose_name=_("sale order"))
partner = models.ForeignKey(Partner,verbose_name=_("partner"),blank=True,null=True)
order_amount = models.DecimalField(_("order amount"),max_digits=14,decimal_places=4,blank=True,null=True)
collection_amount = models.DecimalField(_("collection amount"),max_digits=14,decimal_places=4)
bank = models.ForeignKey(BankAccount,verbose_name=_("bank account"),blank=True,null=True)
memo = models.TextField(_("memo"),blank=True,null=True)
def __unicode__(self):
return u'%s %s'%(self.code,self.so)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.so:
self.partner = self.so.partner
self.order_amount = self.so.amount
if self.so.discount_amount > 0:
self.order_amount -= self.so.discount_amount
super(PaymentCollection,self).save(force_insert,force_update,using,update_fields)
class Meta:
verbose_name = _('Payment Collection')
verbose_name_plural = _('Payment Collection')
class OfferSheet(generic.BO):
"""
报价单
"""
index_weight = 1
STATUS = (
('0', _("NEW")),
('1', _("IN PROGRESS")),
('4', _("DROP")),
('9', _("APPROVED")),
)
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
partner = models.ForeignKey(Partner,verbose_name=_("partner"),limit_choices_to={"partner_type":"C"})
offer_date = models.DateField(_("offer date"))
deliver_date = models.DateField(_("deliver date"))
org = models.ForeignKey(Organization,verbose_name=_("organization"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_("memo"),blank=True,null=True)
amount = models.DecimalField(_("money amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
discount_amount = models.DecimalField(_("discount amount"),max_digits=12,decimal_places=2,blank=True,null=True,default=0.00)
user = models.ForeignKey(User,verbose_name=_("offer man"),blank=True,null=True)
attach = models.FileField(_('offer sheet file'),blank=True,null=True,upload_to='offer sheet',help_text=u'您可导入报价明细,模板请参考文档FD0006')
status = models.BooleanField(_("executed"),default=0)
event_time = models.DateTimeField(_("event time"),blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
import decimal
super(OfferSheet,self).save(force_insert,force_update,using,update_fields)
if self.discount_amount > 0:
sql = 'UPDATE sale_offeritem a SET a.discount_price = a.sale_price - ' \
'((SELECT discount_amount/amount FROM sale_offersheet WHERE id = %s) * (a.sale_price*a.cnt)/a.cnt) WHERE a.master_id = %s'
params = [self.id,self.id]
# print sql % (self.id,self.id)
generic.update(sql,params)
item_count = OfferItem.objects.filter(master=self).count()
if self.attach and item_count == 0:
path = os.path.join(settings.MEDIA_ROOT,self.attach.name)
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
row_count = sheet.nrows
with transaction.atomic():
total_amount = decimal.Decimal(0)
for row_index in range(row_count):
row = sheet.row_values(row_index)
if row_index == 0:
doc_type = row[1]
if doc_type.startswith('0'):
break
else:
continue
elif row_index < 3:
continue
material = None
measure = None
try:
measure = Measure.objects.get(code=row[4])
except Exception,e:
measure = Measure.objects.create(code=row[4],name=force_text(row[5]))
try:
material = Material.objects.get(code=row[0])
except Exception,e:
material = Material(code=row[0],name=force_text(row[1]),spec=force_text(row[2]))
material.sale_price = row[6]
material.purchase_price = row[7]
material.save()
OfferItem.objects.create(master=self,material=material,measure=measure,cnt=row[8],brand=force_text(row[3]),
cost_price=row[7],sale_price=row[6])
total_amount += decimal.Decimal(row[6])*decimal.Decimal(row[8])
sql = 'update sale_offersheet set amount = %s where id=%s'
params = [total_amount,self.id]
generic.update(sql,params)
class Meta:
verbose_name = _('offer sheet')
verbose_name_plural = _('offer sheet')
class OfferItem(models.Model):
"""
订单明细
"""
master = models.ForeignKey(OfferSheet)
material = models.ForeignKey(Material,verbose_name=_("material"),limit_choices_to={"is_virtual":"0",'can_sale':'1'},blank=True,null=True)
measure = models.ForeignKey(Measure,verbose_name=_("measure"),blank=True,null=True)
cnt = models.DecimalField(_("count"),max_digits=14,decimal_places=4)
brand = models.CharField(_('brand'),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
cost_price = models.DecimalField(_("cost price"),max_digits=14,decimal_places=4,blank=True,null=True)
stock_price = models.DecimalField(_("stock price"),max_digits=14,decimal_places=4,blank=True,null=True)
sale_price = models.DecimalField(_("sale price"),max_digits=14,decimal_places=4,blank=True,null=True)
discount_price = models.DecimalField(_("discount price"),max_digits=14,decimal_places=4,blank=True,null=True)
tax = models.CharField(_("tax rate"),max_length=const.DB_CHAR_CODE_6,choices=const.get_value_list('S052'),default='0.00')
create_time = models.DateTimeField(_("create time"),auto_now_add=True)
status = models.BooleanField(_("executed"),default=0)
event_time = models.DateTimeField(_("event time"),blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self.material and self.material.measure.count() > 0:
self.measure = self.material.measure.all()[0]
if self.material.sale_price or self.material.stock_price:
self.sale_price = self.material.sale_price or self.material.stock_price*decimal.Decimal(1.17)/decimal.Decimal(0.6)
super(OfferItem,self).save(force_insert,force_update,using,update_fields)
sql = 'update sale_offersheet set amount = (select sum(sale_price*cnt) from sale_offeritem where master_id=%s) where id=%s'
params = [self.master.id,self.master.id]
# print sql % (self.master.id,self.master.id)
generic.update(sql,params)
class Meta:
verbose_name = _('offer detail')
verbose_name_plural = _('offer detail')
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+1
View File
@@ -0,0 +1 @@
default_app_config = "selfhelp.apps.MyAppConfig"
+219
View File
@@ -0,0 +1,219 @@
# coding=utf-8
# coding = utf-8
import datetime
from django.contrib import admin
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.db.models.aggregates import Sum
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from basedata.models import Material,ExtraParam,Employee,Position
from selfhelp.models import WorkOrder,WOExtraValue,WOItem,Reimbursement,ReimbursementItem,Loan,Enroll,Feedback,Activity
class ParamValueInline(admin.TabularInline):
model = WOExtraValue
fields = ('param_name','param_value')
readonly_fields = ['param_name']
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'param_name':
app_info = generic.get_app_model_info_from_request(request)
instance = app_info['obj']
if instance:
kwargs['queryset'] = ExtraParam.objects.filter(material=instance.service)
return super(ParamValueInline,self).formfield_for_foreignkey(db_field,request,**kwargs)
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class ItemInline(admin.TabularInline):
model = WOItem
raw_id_fields = ['material']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class WorkOrderAdmin(generic.BOAdmin):
"""
"""
CODE_PREFIX = 'WO'
CODE_NUMBER_WIDTH = 5
list_display = ['code','begin','title','classification','business_domain','status']
list_display_links = ['code','title']
exclude = ['creator','modifier','creation','modification']
search_fields = ['code','title']
list_filter = ['classification','service','status']
fields = (
('begin','end',),
('code','refer',),('classification','business_domain',),
('service','project',),
('title','status',),('description',),('attach',),('detail',)
)
readonly_fields = ['status']
raw_id_fields = ['service','project','refer']
inlines = [ItemInline,ParamValueInline]
date_hierarchy = 'begin'
def save_model(self, request, obj, form, change):
if obj.user is None:
obj.user = request.user
super(WorkOrderAdmin,self).save_model(request,obj,form,change)
def get_changeform_initial_data(self, request):
import datetime
td = datetime.date.today()
end = td + datetime.timedelta(30)
return {'begin':datetime.date.today, 'end':end}
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'refer':
app_info = generic.get_app_model_info_from_request(request)
if app_info and app_info['obj']:
kwargs['queryset'] = WorkOrder.objects.exclude(id=app_info['id'])
return super(WorkOrderAdmin,self).formfield_for_foreignkey(db_field,request,**kwargs)
class LoanAdmin(generic.BOAdmin):
CODE_PREFIX = 'JK'
CODE_NUMBER_WIDTH = 5
list_display = ['code','title','project','loan_amount','applier','status']
list_display_links = ['code','title']
readonly_fields = ['status','logout_time','logout_amount']
raw_id_fields = ['project','user']
fields = (
('code',),('title','loan_amount',),('description',),('project'),('user','status'),('logout_time','logout_amount',),
)
extra_buttons = [{'href':'pay','title':_('pay')}]
search_fields = ['code','title','user__username']
date_hierarchy = 'begin'
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id:
try:
obj = Loan.objects.get(id=object_id)
if obj and obj.status == 'P':
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
except Exception,e:
pass
return super(LoanAdmin,self).changeform_view(request,object_id,form_url,extra_context)
def save_model(self, request, obj, form, change):
if obj and obj.user is None:
obj.user = request.user
super(LoanAdmin,self).save_model(request,obj,form,change)
class ReimbursementItemInline(admin.TabularInline):
model = ReimbursementItem
raw_id_fields = ['expense_account']
def get_extra(self, request, obj=None, **kwargs):
if obj:
return 0
else:
return 1
class ReimbursementAdmin(generic.BOAdmin):
CODE_PREFIX = 'BX'
CODE_NUMBER_WIDTH = 5
list_display = ['code','title','project','amount','applier','status']
list_display_links = ['code','title']
inlines = [ReimbursementItemInline]
raw_id_fields = ['project','wo','user','org']
readonly_fields = ['loan_amount','pay_time','status','amount']
fieldsets = [
(None,{'fields':[('code','user'),('title','amount','status',),('description',),('project','wo',)]}),
(_('fico'),{'fields':[('org',),('loan',),('logout_amount','pay_amount',)],'classes': ['collapse']})
]
extra_buttons = [{'href':'pay','title':_('pay')}]
search_fields = ['code','title','project__code','project__name','user__username']
date_hierarchy = 'begin'
def get_changeform_initial_data(self, request):
apps = generic.get_app_model_info_from_request(request)
obj = getattr(apps,'obj',None)
current = request.user
if obj:
current = obj.user
sm = Loan.objects.filter(user=current).aggregate(Sum('loan_amount')).get('loan_amount__sum') or 0.00
return {'loan_amount':sm}
def save_model(self, request, obj, form, change):
if obj and obj.user is None:
obj.user = request.user
super(ReimbursementAdmin,self).save_model(request,obj,form,change)
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'loan':
apps = generic.get_app_model_info_from_request(request)
current = request.user
if apps:
obj = apps.get('obj')
current = obj.user
if obj.status == 'P':
kwargs['queryset']=Loan.objects.filter(id=obj.loan.id)
else:
kwargs['queryset']=Loan.objects.filter(user=current,is_clear=0)
else:
kwargs['queryset']=Loan.objects.filter(user=current,is_clear=0)
return super(ReimbursementAdmin,self).formfield_for_foreignkey(db_field,request,**kwargs)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
if object_id:
try:
obj = Reimbursement.objects.get(id=object_id)
if obj and obj.status == 'P':
extra_context = extra_context or {}
extra_context.update(dict(readonly=True))
except Exception,e:
pass
return super(ReimbursementAdmin,self).changeform_view(request,object_id,form_url,extra_context)
class EnrollInline(admin.TabularInline):
model = Enroll
class FeedbackInline(admin.TabularInline):
model = Feedback
class ActivityAdmin(generic.BOAdmin):
CODE_PREFIX = 'AC'
CODE_NUMBER_WIDTH = 5
list_display = ['code','begin_time','end_time','title','classification','room']
list_display_links = ['code','title']
raw_id_fields = ['room','parent']
fieldsets = [
(None,{'fields':[('begin_time','end_time',),('title','classification',),('description',),
('host','speaker',),('room','location',),('attach',)]}),
(_('other info'),{'fields':[('mail_list',),('parent',),('mail_notice','short_message_notice','weixin_notice',)],'classes': ['collapse']})
]
def get_changeform_initial_data(self, request):
now = datetime.datetime.now()
begin = now + datetime.timedelta(hours=12)
end = begin + datetime.timedelta(hours=6)
return {'begin_time':begin,'end_time':end}
admin.site.register(WorkOrder,WorkOrderAdmin)
admin.site.register(Loan,LoanAdmin)
admin.site.register(Reimbursement,ReimbursementAdmin)
admin.site.register(Activity,ActivityAdmin)
+11
View File
@@ -0,0 +1,11 @@
# created at 15-5-23
# coding=utf-8
__author__ = 'zhugl'
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class MyAppConfig(AppConfig):
name = 'selfhelp'
verbose_name = _("self help")
+330
View File
@@ -0,0 +1,330 @@
# coding=utf-8
import datetime
import os
import xlrd
import decimal
from django.db import transaction
from django.db import models
from django.contrib.auth.models import User
from django.utils.text import force_text
from django.utils.translation import ugettext_lazy as _
from common import generic
from common import const
from mis import settings
from basedata.models import Material,ExtraParam,Project,ExpenseAccount,Measure
from organ.models import OrgUnit
class WorkOrder(generic.BO):
"""
"""
index_weight = 1
code = models.CharField(_("workorder code"),blank=True,null=True,max_length=const.DB_CHAR_CODE_10)
refer = models.ForeignKey("self",verbose_name=_("refer wo"),blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_120)
description = models.TextField(_("description"),blank=True,null=True)
business_domain = models.CharField(_("business domain"),max_length=const.DB_CHAR_CODE_4,choices=const.get_value_list('S045'),default='OT')
classification = models.CharField(_("classification"),max_length=const.DB_CHAR_CODE_4,choices=const.get_value_list('S044'),default='D')
service = models.ForeignKey(Material,verbose_name=_("service name"),null=True,blank=True,limit_choices_to={"is_virtual":"1"})
project = models.ForeignKey(Project,verbose_name=_("project"),null=True,blank=True)
status = models.CharField(_("status"),blank=True,null=True,default='NEW',max_length=const.DB_CHAR_CODE_6,choices=const.get_value_list('S046'))
answer = models.TextField(_("answer"),blank=True,null=True)
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
attach = models.FileField(_('attach'),blank=True,null=True,help_text=u'工单附件,不导入明细。')
detail = models.FileField(_('to be imported detail'),blank=True,null=True,help_text=u'您可导入需求明细,模板请参考文档FD0007')
def __unicode__(self):
return u"%s-%s" % (self.code,self.title)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(WorkOrder,self).save(force_insert,force_update,using,update_fields)
if self.service:
material = self.service
if self.woextravalue_set.count() < 1 and material.extraparam_set and material.extraparam_set.count() > 0:
for param in material.extraparam_set.all():
extra_param = WOExtraValue.objects.create(workorder=self,param_name=param)
self.woextravalue_set.add(extra_param)
item_count = WOItem.objects.filter(workorder=self).count()
if self.detail and item_count == 0:
path = os.path.join(settings.MEDIA_ROOT,self.detail.name)
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
row_count = sheet.nrows
with transaction.atomic():
for row_index in range(row_count):
row = sheet.row_values(row_index)
if row_index == 0:
doc_type = row[1]
if doc_type.startswith('0'):
break
else:
continue
elif row_index < 3:
continue
material = None
measure = None
try:
measure = Measure.objects.get(code=row[4])
except Exception,e:
measure = Measure.objects.create(code=row[4],name=force_text(row[5]))
try:
material = Material.objects.get(code=row[0])
except Exception,e:
material = Material(code=row[0],name=force_text(row[1]),spec=force_text(row[2]))
material.save()
WOItem.objects.create(workorder=self,material=material,measure=measure,amount=row[6])
class Meta:
verbose_name = _("workorder apply")
verbose_name_plural = _("workorder apply")
class Media:
js = ('js/workorder.js',)
class WOExtraValue(models.Model):
"""
"""
workorder = models.ForeignKey(WorkOrder,verbose_name=_("workorder"))
param_name = models.ForeignKey(ExtraParam,verbose_name=_("extra param"))
param_value = models.CharField(_("param value"),blank=True,null=True,max_length=const.DB_CHAR_NAME_40)
class Meta:
verbose_name = _("extra value")
verbose_name_plural = _("extra values")
class WOItem(models.Model):
"""
"""
workorder = models.ForeignKey(WorkOrder,verbose_name=_("workorder"))
material = models.ForeignKey(Material,verbose_name=_("material"),null=True,blank=True,limit_choices_to={"is_virtual":"0"})
amount = models.DecimalField(_("amount"),max_digits=10,decimal_places=4,blank=True,null=True)
measure = models.ForeignKey(Measure,verbose_name=_('measure'),blank=True,null=True)
price = models.DecimalField(_("price"),max_digits=10,decimal_places=4,blank=True,null=True)
class Meta:
verbose_name = _("workorder item")
verbose_name_plural = _("workorder items")
class Loan(generic.BO):
"""
"""
LOAD_STATUS = (
('N',_("NEW")),
('I',_("IN PROGRESS")),
('A',_("APPROVED")),
('P',_("PAYED"))
)
index_weight = 3
code = models.CharField(_("loan code"),max_length=const.DB_CHAR_CODE_10,blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_120)
description = models.TextField(_("description"),blank=True,null=True)
project = models.ForeignKey(Project,verbose_name=_("project"))
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
status = models.CharField(_("status"),blank=True,null=True,default='N',max_length=const.DB_CHAR_CODE_2,choices=LOAD_STATUS)
logout_time = models.DateTimeField(_("logout time"),blank=True,null=True)
loan_amount = models.DecimalField(_("loan amount"),max_digits=10,decimal_places=2,blank=True,null=True)
logout_amount = models.DecimalField(_("logout amount"),max_digits=10,decimal_places=2,blank=True,null=True)
pay_user = models.CharField(_('pay user'),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
pay_time = models.DateTimeField(_('pay time'),blank=True,null=True)
is_clear = models.BooleanField(_('is clear'),default=False)
def __unicode__(self):
import decimal
left = self.loan_amount
left -= self.logout_amount or decimal.Decimal(0.00)
name = '%s%s'%(self.user.last_name,self.user.first_name)
return '%s %s %s J:%.2f Y:%.2f' % (self.code,name,self.title,self.loan_amount,left)
def applier(self):
return u'%s%s'%(self.user.last_name,self.user.first_name)
applier.short_description = _('applier')
def action_pay(self,request):
self.pay_time = datetime.datetime.now()
self.pay_user = request.user.username
self.status = 'P'
self.save()
class Meta:
verbose_name = _("loan")
verbose_name_plural = _("loans")
permissions = (
('financial_pay',_("financial pay")),
)
class Reimbursement(generic.BO):
"""
"""
REIM_STATUS = (
('N',_("NEW")),
('I',_("IN PROGRESS")),
('A',_("APPROVED")),
('P',_("PAYED"))
)
index_weight = 2
code = models.CharField(_("fee code"),max_length=const.DB_CHAR_CODE_10,blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_120)
description = models.TextField(_("description"),blank=True,null=True)
project = models.ForeignKey(Project,verbose_name=_("project"))
wo = models.ForeignKey(WorkOrder,verbose_name=_("work order"),null=True,blank=True)
user = models.ForeignKey(User,verbose_name=_("user"),blank=True,null=True)
org = models.ForeignKey(OrgUnit,verbose_name=_("cost center"),blank=True,null=True)
bank_account = models.CharField(_("bank account"),max_length=const.DB_CHAR_NAME_120,blank=True,null=True)
status = models.CharField(_("status"),blank=True,null=True,default='N',max_length=const.DB_CHAR_CODE_2,choices=REIM_STATUS)
amount = models.DecimalField(_("amount of money"),max_digits=10,decimal_places=2,blank=True,null=True)
loan = models.ForeignKey(Loan,verbose_name=_("loan record"),blank=True,null=True)
loan_amount = models.DecimalField(_("loan amount"),max_digits=10,decimal_places=2,blank=True,null=True)
logout_amount = models.DecimalField(_("logout amount"),max_digits=10,decimal_places=2,blank=True,null=True)
pay_amount = models.DecimalField(_("pay amount"),max_digits=10,decimal_places=2,blank=True,null=True)
pay_time = models.DateTimeField(_("pay time"),blank=True,null=True)
pay_user = models.CharField(_('pay user'),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
def applier(self):
return u'%s%s'%(self.user.last_name,self.user.first_name)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
import decimal
if self.loan:
left = self.loan.loan_amount
left -= self.loan.logout_amount or decimal.Decimal(0.00)
if self.logout_amount is None or self.logout_amount == '':
if self.amount < left:
self.logout_amount = self.amount
else:
self.logout_amount = left
self.pay_amount = self.amount
if self.logout_amount:
self.pay_amount -= self.logout_amount
super(Reimbursement,self).save(force_insert,force_update,using,update_fields)
def action_pay(self,request):
if self.loan:
if self.logout_amount is None or self.logout_amount == '':
self.logout_amount = self.amount
if self.logout_amount < 0:
raise Exception(u'核销金额小于0')
if self.loan.logout_amount is None:
self.loan.logout_amount = self.logout_amount
else:
self.loan.logout_amount += self.logout_amount
if self.loan.loan_amount == self.loan.logout_amount:
self.loan.is_clear=True
self.loan.logout_time = datetime.datetime.now()
self.loan.save()
if self.amount > self.logout_amount:
self.pay_amount = self.amount - self.logout_amount
self.pay_time = datetime.datetime.now()
self.pay_user = request.user.username
self.status = 'P'
self.save()
applier.short_description = _('applier')
class Meta:
verbose_name = _("reimbursement")
verbose_name_plural = _("reimbursements")
permissions = (
('financial_pay',_("financial pay")),
)
class ReimbursementItem(models.Model):
"""
"""
import datetime
reimbursement = models.ForeignKey(Reimbursement,verbose_name=_("reimbursement"))
expense_account = models.ForeignKey(ExpenseAccount,verbose_name=_("expenses account"))
begin = models.DateField(_("occur date"),default=datetime.date.today)
amount = models.DecimalField(_("amount of money"),max_digits=10,decimal_places=2)
memo = models.CharField(_("memo"),max_length=const.DB_CHAR_NAME_40,blank=True,null=True)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super(ReimbursementItem,self).save(force_insert,force_update,using,update_fields)
sql = 'UPDATE selfhelp_reimbursement SET amount = (SELECT SUM(amount) FROM selfhelp_reimbursementitem WHERE reimbursement_id = %s) WHERE id = %s'
params = [self.reimbursement.id,self.reimbursement.id]
generic.update(sql,params)
class Meta:
verbose_name = _("fee item")
verbose_name_plural = _("fee items")
class Activity(generic.BO):
"""
"""
CLASSIFICATION = (
('T',_("Train")),
('M',_("Meeting")),
('G',_("Community")),
)
index_index_weight = 4
begin_time = models.DateTimeField(_('begin time'))
end_time = models.DateTimeField(_('end time'))
enroll_deadline = models.DateTimeField(_('enroll deadline'),blank=True,null=True)
code = models.CharField(_("code"),max_length=const.DB_CHAR_NAME_20,blank=True,null=True)
title = models.CharField(_("title"),max_length=const.DB_CHAR_NAME_120)
parent = models.ForeignKey('self',verbose_name=_("parent"),blank=True,null=True)
description = models.TextField(_("description"),blank=True,null=True)
host = models.CharField(_("host"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
speaker = models.CharField(_("speaker"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
accept_enroll = models.BooleanField(_("accept enroll"),default=1)
room = models.ForeignKey(Material,verbose_name=_("room"),blank=True,null=True,limit_choices_to={'tp':20})
location = models.CharField(_("location"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
classification = models.CharField(_("classification"),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=CLASSIFICATION,default='M')
mail_list = models.TextField(_("mail list"),blank=True,null=True)
mail_notice = models.BooleanField(_("mail notice"),default=1)
short_message_notice = models.BooleanField(_("short message notice"),default=1)
weixin_notice = models.BooleanField(_("weixin notice"),default=1)
status = models.BooleanField(_("published"),default=0)
publish_time = models.DateTimeField(_("publish time"),blank=True,null=True)
attach = models.FileField(_("attach"),blank=True,null=True,upload_to='activity')
class Meta:
verbose_name = _("activity")
verbose_name_plural = _("activities")
class Feedback(models.Model):
"""
"""
RANK = (
('A','A'),
('B','B'),
('C','C'),
('D','D'),
)
activity = models.ForeignKey(Activity)
user = models.ForeignKey(User)
feed_time = models.DateTimeField(_("feedback time"),auto_now_add=True)
rank = models.CharField(_('rank'),max_length=const.DB_CHAR_CODE_2,blank=True,null=True,choices=RANK,default='B')
comment = models.CharField(_("suggest"),blank=True,null=True,max_length=const.DB_CHAR_NAME_80)
class Enroll(models.Model):
"""
"""
activity = models.ForeignKey(Activity)
user = models.ForeignKey(User)
enroll_time = models.DateTimeField(_("enroll time"),auto_now_add=True)
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+6
View File
@@ -0,0 +1,6 @@
from django.conf.urls import include, url,static
import selfhelp.views
urlpatterns = [
url(r"(?P<model>\w+)/(?P<object_id>\d+)/pay", 'selfhelp.views.pay_action'),
]
+46
View File
@@ -0,0 +1,46 @@
# coding=utf-8
from django.contrib.admin import site
from django.contrib.contenttypes.models import ContentType
from django.db import connection
from django.http.response import HttpResponseRedirect
from django.utils.encoding import force_text
from django.template.response import TemplateResponse
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.models import ContentType
def pay_action(request,model,object_id):
title = _("Are you sure?")
ct = ContentType.objects.get(app_label='selfhelp',model=model)
obj = ct.get_object_for_this_type(id=int(object_id))
opts = obj._meta
objects_name = force_text(opts.verbose_name)
if model == 'reimbursement':
loan = obj.loan
amount = obj.logout_amount
if loan and (amount is None or amount< 0):
messages.error(request,u'您选择了借款单据,但是未正确填写核销金额,请在\'财务信息\'栏目中更正')
return HttpResponseRedirect("/admin/selfhelp/%s/%s"%(model,object_id))
if request.POST.get("post"):
try:
obj.action_pay(request)
messages.success(request,_('action successfully'))
except Exception,e:
messages.error(request,e)
return HttpResponseRedirect("/admin/selfhelp/%s/%s"%(model,object_id))
context = dict(
site.each_context(request),
title=title,
opts=opts,
objects_name=objects_name,
object=obj,
action_name=_('pay')
)
request.current_app = site.name
return TemplateResponse(request,'admin/invent/stockin/in_confirmation.html', context)
+38
View File
@@ -0,0 +1,38 @@
table#workflow-history{
width:100%
}
table#workflow-history tbody th,table#workflow-history tbody td.col {
width: 16em;
}
.submitlink {
padding-left: 12px;
background: url(../img/icon-yes.gif) 0 .25em no-repeat;
}
a.submitlink:link, a.submitlink:visited {
color: #CC3434;
}
a.submitlink:hover {
color: #993333;
}
label.control{
width:4em;
}
p.next-node{
font-weight:bold;
}
ul.node-users{
list-style:none;
}
p.tooltip{
color:#999;
}
li.done-link{
padding-left: 12px;
background: url(../img/icon_yes.gif) 0 .2em no-repeat;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

+22
View File
@@ -0,0 +1,22 @@
/**
author:zhugl
date:2015-05-15
*/
(function($) {
$(document).ready(function() {
/**
set operation type
*/
$("fieldset.workflow input[type='radio']").on('click',function(){
operation = $(this).val();
next = "approve/"+operation;
$("#workflow_approve").attr("href",next);
});
try{
$("div.inline-group table tbody tr.form-row").removeClass('has_original');
$("div.inline-group table tbody tr.form-row td:first-child").find('p').hide();
}catch(e){
}
});
})(django.jQuery);
+11
View File
@@ -0,0 +1,11 @@
/**
* Created by Administrator on 15-5-23.
*/
(function($) {
$(document).ready(function() {
/**
set operation type
*/
$("#woextravalue_set-group select").attr('readonly','true')
});
})(django.jQuery);
+2
View File
@@ -0,0 +1,2 @@
default_app_config = 'syscfg.apps.SysConfig'
+53
View File
@@ -0,0 +1,53 @@
# coding=utf-8
from django.contrib import admin
from django.forms import ModelForm,DateField
from syscfg.models import *
from common import generic
class SiteForm(ModelForm):
"""
"""
class Meta:
model = Site
fields = '__all__'
class SiteAdmin(admin.ModelAdmin):
list_per_page = 10
list_display = ['name', 'begin', 'end']
fields = (('begin', 'end'), 'name', 'description', 'user')
filter_horizontal = ['user']
form = SiteForm
class ModuleAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 3
CODE_PREFIX = 'U'
list_display = ['code','name','parent','status']
ordering = ['weight']
raw_id_fields = ['parent']
class MenuAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 3
CODE_PREFIX = 'M'
list_display = ['code','name','module','status']
list_filter = ['module']
ordering = ['weight']
raw_id_fields = ['module']
class RoleAdmin(generic.BOAdmin):
CODE_NUMBER_WIDTH = 3
CODE_PREFIX = 'R'
list_display = ['code','name','status']
filter_horizontal = ['users','menus']
admin.site.register(Site, SiteAdmin)
admin.site.register(Module,ModuleAdmin)
admin.site.register(Menu,MenuAdmin)
admin.site.register(Role,RoleAdmin)
+9
View File
@@ -0,0 +1,9 @@
__author__ = 'zhugl'
# created at 15-4-22
from django.apps.config import AppConfig
from django.utils.translation import ugettext_lazy as _
class SysConfig(AppConfig):
name = 'syscfg'
verbose_name = _('SysConfig')
+79
View File
@@ -0,0 +1,79 @@
# coding=utf-8
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from common import const
from common import generic
class Site(models.Model):
"""
站点,一个站点下可有多个公司,处于同一个站点下的用户逻辑上位于同一个组织
"""
index_weight = 1
begin = models.DateField(_('begin date'), blank=True,null=True)
end = models.DateField(_('end date'), blank=True,null=True)
name = models.CharField(_('site name'), max_length=const.DB_CHAR_NAME_40)
description = models.TextField(_('site description'),blank=True,null=True)
user = models.ManyToManyField(User,verbose_name=_('administrator'))
def __unicode__(self):
return u'%s'%self.name
class Meta:
verbose_name = _('Site')
verbose_name_plural = _('Site')
class Module(generic.BO):
"""
模块管理
"""
index_weight = 2
code = models.CharField(_("module code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("module name"),max_length=const.DB_CHAR_NAME_40)
url = models.URLField(_("module url"),blank=True,null=True,max_length=const.DB_CHAR_NAME_80)
weight = models.IntegerField(_("weight"),blank=True,null=True,default=99)
icon = models.CharField(_("style class"),blank=True,null=True,max_length=const.DB_CHAR_NAME_40)
parent = models.ForeignKey('self',blank=True,null=True,verbose_name=_("parent"))
status = models.BooleanField(_("in use"),default=True)
class Meta:
verbose_name = _("module")
verbose_name_plural = _("module")
class Menu(generic.BO):
"""
菜单管理
"""
index_weight = 3
module = models.ForeignKey(Module,verbose_name=_("module"))
code = models.CharField(_("menu code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("menu name"),max_length=const.DB_CHAR_NAME_40)
url = models.URLField(_("menu url"),blank=True,null=True,max_length=const.DB_CHAR_NAME_80)
weight = models.IntegerField(_("weight"),blank=True,null=True,default=99)
icon = models.CharField(_("style class"),blank=True,null=True,max_length=const.DB_CHAR_NAME_40)
status = models.BooleanField(_("in use"),default=True)
class Meta:
verbose_name = _("menu")
verbose_name_plural = _("menu")
class Role(generic.BO):
"""
角色管理,分配用户所拥有的菜单
"""
index_weight = 4
code = models.CharField(_("role code"),max_length=const.DB_CHAR_CODE_6,blank=True,null=True)
name = models.CharField(_("role name"),max_length=const.DB_CHAR_NAME_40)
description = models.CharField(_("description"),max_length=const.DB_CHAR_NAME_80,blank=True,null=True)
status = models.BooleanField(_("in use"),default=True)
parent = models.ForeignKey('self',blank=True,null=True,verbose_name=_("parent"))
users = models.ManyToManyField(User,verbose_name=_("role users"),blank=True)
menus = models.ManyToManyField(Menu,verbose_name=_("role menus"),blank=True)
class Meta:
verbose_name = _("role")
verbose_name_plural = _("role")
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+17
View File
@@ -0,0 +1,17 @@
{% extends "admin/index.html" %}
{% load i18n %}
{% block bodyclass %}{{ block.super }} app-{{ app_label }}{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
{% for app in app_lib %}
| {% if app.is_current %} {{app.name}} {% else %}<a href="{{ app.app_url }}">{{ app.name }}</a> {% endif %}
{% endfor %}
</div>
{% endblock %}
{% endif %}
{% block sidebar %}{% endblock %}
+91
View File
@@ -0,0 +1,91 @@
{% load i18n admin_static %}<!DOCTYPE html>
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}" />
{% block extrastyle %}{% endblock %}
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% block stylesheet_ie %}{% static "admin/css/ie.css" %}{% endblock %}" /><![endif]-->
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}" />{% endif %}
<script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% endfilter %}";</script>
<script type="text/javascript">window.__admin_utc_offset__ = "{% filter escapejs %}{% now "Z" %}{% endfilter %}";</script>
{% block extrahead %}{% endblock %}
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
</head>
{% load i18n %}
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
<!-- Container -->
<div id="container">
{% if not is_popup %}
<!-- Header -->
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% block usertools %}
{% if has_permission %}
<div id="user-tools">
{% block welcome-msg %}
{% trans 'Welcome,' %}
<strong>{% firstof user.get_short_name user.get_username %}</strong>.
{% endblock %}
{% block userlinks %}
<a href="/admin/workflow/todolist">{% trans 'workflow todo' %}</a> /
{% if site_url %}
<a href="/admin/basedata/document">{% trans 'document' %}</a> /
{% endif %}
{% if user.is_active and user.is_staff %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
{% endif %}
{% endif %}
{% if user.has_usable_password %}
<a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
{% endif %}
<a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
{% endblock %}
</div>
{% endif %}
{% endblock %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
{% if title %} &rsaquo; {{ title }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block messages %}
{% if messages %}
<ul class="messagelist">{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
{% endfor %}</ul>
{% endif %}
{% endblock messages %}
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
{% block content %}
{% block object-tools %}{% endblock %}
{{ content }}
{% endblock %}
{% block sidebar %}{% endblock %}
<br class="clear" />
</div>
<!-- END Content -->
{% block footer %}<div id="footer"></div>{% endblock %}
</div>
<!-- END Container -->
</body>
</html>
+148
View File
@@ -0,0 +1,148 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_approve">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
{% if can_edit %}
$('a.deletelink').hide();
$("#workflow_submit").hide();
$("input[name='_addanother']").hide();
$("input[name='_continue']").hide();
{% else %}
$('input,select,textarea').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select,textarea').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
try{
$("div.inline-group table tbody tr.form-row").removeClass('has_original');
$("div.inline-group table tbody tr.form-row td:first-child").find('p').hide();
}catch(e){
}
});
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
+110
View File
@@ -0,0 +1,110 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% block extrastyle %}{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />
{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
{% for app in maxi_app_list %}
| <a href="{{ app.app_url }}">{{ app.name }}</a>
{% endfor %}
</div>
{% endblock %}
{% block content %}
<div id="content-main">
{% if maxi_app_list %}
{% for app in maxi_app_list %}
<div class="app-{{ app.app_label }} module">
<table>
<caption>
<a href="{{ app.app_url }}" class="section" title="{% blocktrans with name=app.name %}Models in the {{ name }} application{% endblocktrans %}">{{ app.name }}</a>
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}">
{% if model.admin_url %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.add_url %}
<td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
{% if model.admin_url %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related" style="width:18em">
<div class="module">
<h2><a href="workflow/todolist" style="float:right">更多</a>我的待办</h2>
{% if not todolist %}
<p>无待办任务</p>
{% else %}
<ul class="actionlist">
{% for todo in todolist%}
<li class="changelink">
{{todo.href}}<br/>
<span class="mini quiet">{{todo.submitter}} {{todo.start_time}}</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
<div class="module" id="recent-actions-module">
<h2>{% trans 'Recent Actions' %}</h2>
<h3>{% trans 'My Actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% trans 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
{% endif %}
<br/>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type }}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
@@ -0,0 +1,167 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_submit">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
$('input,select,textarea').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select,textarea').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
});
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% if detail %}
<h1 style="margin-top:15px">{% trans "InOut History" %}</h1>
<div class="module">
<table id="workflow-history">
<thead>
<tr>
<th scope="col">{% trans 'execute time' %}</th>
<th scope="col">{% trans 'plus or minus prop' %}</th>
<th scope="col">{% trans 'price' %}</th>
<th scope="col">{% trans 'count' %}</th>
<th scope="col">{% trans 'measure' %}</th>
<th scope="col">{% trans 'status' %}</th>
<th scope="col">{% trans 'source' %}</th>
</tr>
</thead>
<tbody>
{% for item in detail %}
<tr>
<th scope="row">{{ item.event_time|date:"DATETIME_FORMAT" }}</th>
<td class="col">{{ item.prop }}</td>
<td class="col">{{ item.price }}</td>
<td class="col">{{ item.cnt }}</td>
<td class="col">{{ item.measure }}</td>
<td class="col">{% if item.status %} {% trans 'EXECUTED'%} {% endif %}</td>
<td class="col">{{ item.source }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endblock %}
@@ -0,0 +1,136 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_submit">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
$("div.inline-group tr").removeClass("has_original");
$("td.original p").hide();
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
$('input,select').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
});
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
@@ -0,0 +1,27 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% if action_name %}{{action_name}} {% else %} {% trans 'action' %}{% endif %}
</div>
{% endblock %}
{% block content %}
<p> {% trans 'Are your sure to execute the operations?' %} </p>
<form action="" method="post">{% csrf_token %}
<div>
<input type="hidden" name="post" value="yes" />
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
</form>
{% endblock %}
@@ -0,0 +1,137 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_submit">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
$("div.inline-group tr").removeClass("has_original");
$("td.original p").hide();
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
$('input,select,textarea').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select,textarea').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
$('div.inline-group select').attr('disabled',true);
});
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
@@ -0,0 +1,27 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'action' %}
</div>
{% endblock %}
{% block content %}
<p> {% trans 'Are your sure to execute the check out operations?' %} </p>
<form action="" method="post">{% csrf_token %}
<div>
<input type="hidden" name="post" value="yes" />
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
</form>
{% endblock %}
+82
View File
@@ -0,0 +1,82 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block extrastyle %}
<link rel="stylesheet" type="text/css" href="/static/css/maximus.css" />
{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ module_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'History' %}
</div>
{% endblock %}
{% block content %}
<div id="content-main">
<div class="module">
{% if action_list %}
<table id="change-history">
<thead>
<tr>
<th scope="col">{% trans 'Date/time' %}</th>
<th scope="col">{% trans 'User' %}</th>
<th scope="col">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
{% for action in action_list %}
<tr>
<th scope="row">{{ action.action_time|date:"DATETIME_FORMAT" }}</th>
<td>{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %}</td>
<td>{{ action.change_message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
{% endif %}
</div>
{% if history_list %}
<h1 style="margin-top:15px">{% trans "Workflow History" %}</h1>
<div class="module">
<table id="workflow-history">
<thead>
<tr>
<th scope="col">{% trans 'Date/time' %}</th>
<th scope="col">{% trans 'User' %}</th>
<th scope="col">{% trans 'node' %}</th>
<th scope="col">{% trans 'Action' %}</th>
<th scope="col">{% trans 'Workflow Memo' %}</th>
</tr>
</thead>
<tbody>
{% for history in history_list %}
<tr>
<th scope="row">{{ history.pro_time|date:"DATETIME_FORMAT" }}</th>
<td class="col">{{ history.user.get_username }}{% if history.user.get_full_name %} ({{ history.user.get_full_name }}){% endif %}</td>
<td class="col">{{ history.get_node_desc }}</td>
<td class="col">{{ history.get_action_desc }}</td>
<td>{{ history.get_memo_desc }}</td>
</tr>
{% endfor %}
{% if todo_list %}
{% for todo in todo_list %}
<tr>
<th scope="row">{% if todo.is_read %}{{ todo.read_time|date:"DATETIME_FORMAT" }}{% endif %}</th>
<td class="col">{{ todo.user.get_username }}{% if todo.user.get_full_name %} ({{ todo.user.get_full_name }}){% endif %}</td>
<td class="col">{{ todo.node.name }}</td>
<td class="col">{% if todo.is_read %} {% trans 'already read' %} {% else %} {% trans 'unread' %} {% endif %}</td>
<td></td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
{% endif %}
</div>
{% endblock %}
@@ -0,0 +1,173 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_approve">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
{% if can_edit %}
$('a.deletelink').hide();
$("#workflow_submit").hide();
$("input[name='_addanother']").hide();
$("input[name='_continue']").hide();
{% else %}
$('input,select,textarea').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select,textarea').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
try{
$("div.inline-group table tbody tr.form-row").removeClass('has_original');
$("div.inline-group table tbody tr.form-row td:first-child").find('p').hide();
}catch(e){
}
});
$('#id_classification').bind('change',function(){
var c = $("select[name='classification'] option:selected").val();
//alert(c);
if(c=='R' || c=='Q'){
$("label[for='id_service']").removeClass('required');
$('#woitem_set-group').hide();
$('#woextravalue_set-group').hide();
$('div.field-service').hide();
$('div.field-detail').hide();
}else{
$('#woitem_set-group').show();
$('#woextravalue_set-group').show();
$('div.field-service').show();
if(c=='D'){
$("label[for='id_service']").removeClass('required');
$('div.field-detail').show();
}
if(c=='S'){
$('div.field-detail').hide();
$("label[for='id_service']").addClass('required');
}
}
});
$('#woextravalue_set-group').hide();
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
+18
View File
@@ -0,0 +1,18 @@
{% load i18n admin_urls %}
<div class="submit-row">
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
<a href="start" class="button" id="workflow_submit">{% trans "submit" %}</a>
{% for button in extra_buttons %}
<a href="{{button.href}}" class="button">{{button.title}}</a>
{% endfor %}
{{extra_buttons}}
{% if show_delete_link %}
{% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
<p class="deletelink-box"><a href="{% add_preserved_filters delete_url %}" class="deletelink">{% trans "Delete" %}</a>
</p>
{% endif %}
{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
</div>
@@ -0,0 +1,164 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if show_workflow_line%}
<fieldset class="module aligned workflow">
<h2>{% trans "workflow approve" %}</h2>
<div style="padding:10px">
{% if can_restart %}
<a class="button" href="restart/{{workflow_instance.id}}" id="workflow_restart">{% trans "restart workflow" %}</a>
<p style="float:right;color:#666">{% trans "your apply has been denied,you can restart a new apply" %}</p>
{% else %}
<label class="control"><input type="radio" name="operation" value="1" checked> {% trans "agree" %}</label>
<label class="control"><input type="radio" name="operation" value="3"> {% trans "deny" %}</label>
<label class="control"><input type="radio" name="operation" value="4"> {% trans "terminate" %}</label>
<a class="button" href="approve/1" id="workflow_approve">{% trans "submit" %}</a>
{% endif %}
</div>
</fieldset>
{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
showAddAnotherPopup(this);
});
$('.related-lookup').click(function(e) {
e.preventDefault();
showRelatedObjectLookupPopup(this);
});
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
{% if workflow_modal %}
{% if workflow_instance %}
workflow_modal = "{{ workflow_modal.code }}";
workflow_instance = "{{ workflow_instance.code }}";
$('tr.add-row').hide();
$('input,select,textarea').attr('disabled','true');
$('div.submit-row').hide();
$('.workflow input,.workflow select').removeAttr("disabled");
$("#workflow_submit").hide();
{% endif %}
{% else %}
$("#workflow_submit").hide();
{% endif %}
{% if extra_buttons %}
{% for button in extra_buttons %}
$("<a href='{{button.href}}' class='button'>{{button.title}}</a>").insertAfter("#workflow_submit");
{% endfor %}
{% endif %}
{% if readonly %}
$('input,select,textarea').attr('disabled',true);
$('div.submit-row').hide();
$('tr.add-row').hide();
{% endif %}
try{
$("div.inline-group table tbody tr.form-row").removeClass('has_original');
$("div.inline-group table tbody tr.form-row td:first-child").find('p').hide();
}catch(e){
}
});
$("input[name='handler_type']").bind('click',function(){
v = $("input[name='handler_type']:checked").val();
if(v==1){
$('div.field-users').show();
$('div.field-positions').hide();
$('div.field-roles').hide();
}else if(v==2){
$('div.field-users').hide();
$('div.field-positions').show();
$('div.field-roles').hide();
}else if(v==3){
$('div.field-users').hide();
$('div.field-positions').hide();
$('div.field-roles').show();
}else if(v==4){
$('div.field-users').hide();
$('div.field-positions').hide();
$('div.field-roles').hide();
}
});
$('div.field-users').show();
$('div.field-positions').hide();
$('div.field-roles').hide();
})(django.jQuery);
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
@@ -0,0 +1,67 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="/static/css/maximus.css" />{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'workflow approve' %}
</div>
{% endblock %}
{% block content %}
{% if operation == '4' %}
<p>{% trans "Are you sure to terminate the request?" %}</p>
{% elif operation == '3' %}
<p>{% trans "Are you sure to deny the request?" %}</p>
{% else %}
<p>{% blocktrans with escaped_object=object %}Are you sure you want to submit the {{ object_name }} "{{ escaped_object }}"? {% endblocktrans %}</p>
{% endif%}
<h3> {{ workflow_modal.code }} {{ workflow_modal.name }} </h3>
<form action="" method="post">{% csrf_token %}
{% if is_stop_node %}
<p> {% trans "current node is stop node,click the submit button to complete it" %} </p>
{% else %}
{% for node_user in node_users %}
{% if node_user.node == 'start'%}
<p class="next-node">{% trans "back to start node" %}</p>
{%else%}
<p class="next-node">{% trans "next node" %}{{ node_user.node.name }}</p>
{% endif%}
{% if next_node_description %}
<p class="tooltip">{% trans "attention" %}{{next_node_description}}</p>
{% endif %}
{% if node_has_users %}
<ul class="node-users">
{% for user in node_user.users %}
<li><input type="checkbox" name="{{checkbox_name}}" value="{{user.id}}" checked> {{user.last_name}}{{user.first_name}}</li>
{% endfor %}
</ul>
{% else %}
<p>{% trans "No user was configured to handle this node"%}</p>
{% endif %}
{% endfor%}
{% endif%}
{% if is_stop_node or node_has_users%}
<label style="display:block">{% trans "Workflow Memo" %}</label>
<textarea name="memo" rows="3" cols="80"></textarea>
<div class="workflow_approve_command">
<input type="hidden" name="post" value="yes" />
<input type="hidden" name="oper_type" value="{{operation}}" />
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
{% else %}
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
{% endif %}
</form>
{% endblock %}
@@ -0,0 +1,46 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
&rsaquo; {% trans 'submit' %}
</div>
{% endblock %}
{% block content %}
{% if has_workflow %}
<p>{% blocktrans with escaped_object=object %}Are you sure you want to submit the {{ object_name }} "{{ escaped_object }}"? {% endblocktrans %}</p>
<h3> {{ workflow_modal.code }} {{ workflow_modal.name }} </h3>
<form action="" method="post">{% csrf_token %}
{% if next_node %}
<p class="next-node">{% trans "next node" %}{{ next_node.name }}</p>
{% if has_next_user %}
<ul class="node-users">
{% for user in next_users %}
<li><input type="checkbox" name="{{checkbox_name}}" value="{{user.id}}" checked> {{user.last_name}}{{user.first_name}}</li>
{% endfor %}
</ul>
{% else %}
<p>{% trans "No user was configured to handle this node"%}</p>
{% endif %}
{% endif %}
<div>
<input type="hidden" name="post" value="yes" />
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "No, take me back" %}</a>
</div>
</form>
{% else %}
<p>{% trans "you needs to config a workflow model for this content type" %}</p>
<a href="#" onclick="window.history.back(); return false;" class="button cancel-link">{% trans "OK" %}</a>
{% endif %}
{% endblock %}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More