From dfe9774fb1f22ee82e77831a3118d33f5902d110 Mon Sep 17 00:00:00 2001 From: zhugl Date: Thu, 30 Jul 2015 13:01:42 +0800 Subject: [PATCH] Initial commit --- basedata/__init__.py | 2 + basedata/admin.py | 339 ++++ basedata/apps.py | 9 + basedata/models.py | 657 +++++++ basedata/tests.py | 3 + basedata/urls.py | 6 + basedata/views.py | 42 + common/__init__.py | 1 + common/const.py | 39 + common/generic.py | 312 +++ hr/__init__.py | 1 + hr/admin.py | 47 + hr/apps.py | 11 + hr/models.py | 125 ++ hr/tests.py | 3 + hr/views.py | 3 + invent/__init__.py | 1 + invent/admin.py | 248 +++ invent/apps.py | 11 + invent/models.py | 493 +++++ invent/tests.py | 3 + invent/urls.py | 10 + invent/views.py | 175 ++ locale/zh_CN/LC_MESSAGES/django.mo | Bin 0 -> 21184 bytes locale/zh_CN/LC_MESSAGES/django.po | 1450 ++++++++++++++ manage.py | 10 + midware/__init__.py | 1 + midware/cuser.py | 176 ++ mis/__init__.py | 4 + mis/production.py | 127 ++ mis/settings.py | 127 ++ mis/urls.py | 23 + mis/views.py | 5 + mis/wsgi.py | 16 + organ/__init__.py | 1 + organ/admin.py | 68 + organ/apps.py | 9 + organ/models.py | 115 ++ organ/tests.py | 3 + organ/views.py | 3 + plugin/__init__.py | 3 + plugin/wfactions.py | 54 + plugin/wfnodes.py | 54 + plugin/wfusers.py | 67 + plugin/xls.py | 183 ++ purchase/__init__.py | 1 + purchase/admin.py | 90 + purchase/apps.py | 11 + purchase/models.py | 221 +++ purchase/tests.py | 3 + purchase/views.py | 3 + sale/__init__.py | 1 + sale/admin.py | 104 + sale/apps.py | 11 + sale/models.py | 252 +++ sale/tests.py | 3 + sale/views.py | 3 + selfhelp/__init__.py | 1 + selfhelp/admin.py | 219 +++ selfhelp/apps.py | 11 + selfhelp/models.py | 330 ++++ selfhelp/tests.py | 3 + selfhelp/urls.py | 6 + selfhelp/views.py | 46 + static/css/maximus.css | 38 + static/img/icon-submitlink.gif | Bin 0 -> 122 bytes static/img/icon-submitlink.png | Bin 0 -> 253 bytes static/img/icon-yes.gif | Bin 0 -> 299 bytes static/js/maximus.js | 22 + static/js/workorder.js | 11 + syscfg/__init__.py | 2 + syscfg/admin.py | 53 + syscfg/apps.py | 9 + syscfg/models.py | 79 + syscfg/tests.py | 3 + syscfg/views.py | 3 + templates/admin/app_index.html | 17 + templates/admin/base.html | 91 + templates/admin/change_form.html | 148 ++ templates/admin/index.html | 110 ++ .../admin/invent/inventory/change_form.html | 167 ++ .../admin/invent/stockin/change_form.html | 136 ++ .../admin/invent/stockin/in_confirmation.html | 27 + .../admin/invent/stockout/change_form.html | 137 ++ .../invent/stockout/out_confirmation.html | 27 + templates/admin/object_history.html | 82 + .../admin/selfhelp/workorder/change_form.html | 173 ++ templates/admin/submit_line.html | 18 + .../admin/workflow/node/change_form.html | 164 ++ .../workflow_approve_confirmation.html | 67 + .../workflow/workflow_start_confirmation.html | 46 + upload/data/1001部门岗位员工导入模板test.xls | Bin 0 -> 32768 bytes upload/data/1003合作伙伴导入模板.xls | Bin 0 -> 20480 bytes upload/data/1003合作伙伴导入模板_ENnUPsg.xls | Bin 0 -> 20480 bytes upload/data/1004项目导入模板.xls | Bin 0 -> 18944 bytes upload/data/1004项目导入模板_MDj3PCr.xls | Bin 0 -> 18944 bytes upload/data/1004项目导入模板_QE5NXrr.xls | Bin 0 -> 18944 bytes upload/data/1004项目导入模板_Sfco4Ck.xls | Bin 0 -> 18944 bytes upload/data/1004项目导入模板_YfVeRXU.xls | Bin 0 -> 18944 bytes upload/data/1005用户信息导入模板.xls | Bin 0 -> 19968 bytes upload/data/1005用户信息导入模板_LRE2NKU.xls | Bin 0 -> 19456 bytes upload/data/1005用户信息导入模板_stkXmtR.xls | Bin 0 -> 19456 bytes upload/data/合作伙伴.xls | Bin 0 -> 20480 bytes upload/doc/1001部门岗位员工导入模板.xls | Bin 0 -> 32256 bytes upload/doc/1002期初库存导入模板.csv | 11 + upload/doc/1003合作伙伴导入模板.xls | Bin 0 -> 20992 bytes upload/doc/1004项目导入模板.xls | Bin 0 -> 18944 bytes upload/doc/2001报价单明细样例.xls | Bin 0 -> 23040 bytes upload/doc/2002需求计划明细样例.xls | Bin 0 -> 23040 bytes upload/doc/2003采购单明细样例.xls | Bin 0 -> 23040 bytes upload/hr profile/mis.sql | 1604 +++++++++++++++ upload/inventory/INVENTORY.csv | 11 + upload/inventory/INVENTORY_PPfDioe.csv | 11 + upload/offer sheet/backbone.js | 1745 +++++++++++++++++ upload/project/2014年17月份时事政治全集.docx | Bin 0 -> 132666 bytes upload/project/综合知识与能力素质.docx | Bin 0 -> 12467 bytes workflow/__init__.py | 1 + workflow/admin.py | 118 ++ workflow/apps.py | 9 + workflow/models.py | 272 +++ workflow/tests.py | 3 + workflow/views.py | 314 +++ 122 files changed, 12088 insertions(+) create mode 100644 basedata/__init__.py create mode 100644 basedata/admin.py create mode 100644 basedata/apps.py create mode 100644 basedata/models.py create mode 100644 basedata/tests.py create mode 100644 basedata/urls.py create mode 100644 basedata/views.py create mode 100644 common/__init__.py create mode 100644 common/const.py create mode 100644 common/generic.py create mode 100644 hr/__init__.py create mode 100644 hr/admin.py create mode 100644 hr/apps.py create mode 100644 hr/models.py create mode 100644 hr/tests.py create mode 100644 hr/views.py create mode 100644 invent/__init__.py create mode 100644 invent/admin.py create mode 100644 invent/apps.py create mode 100644 invent/models.py create mode 100644 invent/tests.py create mode 100644 invent/urls.py create mode 100644 invent/views.py create mode 100644 locale/zh_CN/LC_MESSAGES/django.mo create mode 100644 locale/zh_CN/LC_MESSAGES/django.po create mode 100644 manage.py create mode 100644 midware/__init__.py create mode 100644 midware/cuser.py create mode 100644 mis/__init__.py create mode 100644 mis/production.py create mode 100644 mis/settings.py create mode 100644 mis/urls.py create mode 100644 mis/views.py create mode 100644 mis/wsgi.py create mode 100644 organ/__init__.py create mode 100644 organ/admin.py create mode 100644 organ/apps.py create mode 100644 organ/models.py create mode 100644 organ/tests.py create mode 100644 organ/views.py create mode 100644 plugin/__init__.py create mode 100644 plugin/wfactions.py create mode 100644 plugin/wfnodes.py create mode 100644 plugin/wfusers.py create mode 100644 plugin/xls.py create mode 100644 purchase/__init__.py create mode 100644 purchase/admin.py create mode 100644 purchase/apps.py create mode 100644 purchase/models.py create mode 100644 purchase/tests.py create mode 100644 purchase/views.py create mode 100644 sale/__init__.py create mode 100644 sale/admin.py create mode 100644 sale/apps.py create mode 100644 sale/models.py create mode 100644 sale/tests.py create mode 100644 sale/views.py create mode 100644 selfhelp/__init__.py create mode 100644 selfhelp/admin.py create mode 100644 selfhelp/apps.py create mode 100644 selfhelp/models.py create mode 100644 selfhelp/tests.py create mode 100644 selfhelp/urls.py create mode 100644 selfhelp/views.py create mode 100644 static/css/maximus.css create mode 100644 static/img/icon-submitlink.gif create mode 100644 static/img/icon-submitlink.png create mode 100644 static/img/icon-yes.gif create mode 100644 static/js/maximus.js create mode 100644 static/js/workorder.js create mode 100644 syscfg/__init__.py create mode 100644 syscfg/admin.py create mode 100644 syscfg/apps.py create mode 100644 syscfg/models.py create mode 100644 syscfg/tests.py create mode 100644 syscfg/views.py create mode 100644 templates/admin/app_index.html create mode 100644 templates/admin/base.html create mode 100644 templates/admin/change_form.html create mode 100644 templates/admin/index.html create mode 100644 templates/admin/invent/inventory/change_form.html create mode 100644 templates/admin/invent/stockin/change_form.html create mode 100644 templates/admin/invent/stockin/in_confirmation.html create mode 100644 templates/admin/invent/stockout/change_form.html create mode 100644 templates/admin/invent/stockout/out_confirmation.html create mode 100644 templates/admin/object_history.html create mode 100644 templates/admin/selfhelp/workorder/change_form.html create mode 100644 templates/admin/submit_line.html create mode 100644 templates/admin/workflow/node/change_form.html create mode 100644 templates/default/workflow/workflow_approve_confirmation.html create mode 100644 templates/default/workflow/workflow_start_confirmation.html create mode 100644 upload/data/1001部门岗位员工导入模板test.xls create mode 100644 upload/data/1003合作伙伴导入模板.xls create mode 100644 upload/data/1003合作伙伴导入模板_ENnUPsg.xls create mode 100644 upload/data/1004项目导入模板.xls create mode 100644 upload/data/1004项目导入模板_MDj3PCr.xls create mode 100644 upload/data/1004项目导入模板_QE5NXrr.xls create mode 100644 upload/data/1004项目导入模板_Sfco4Ck.xls create mode 100644 upload/data/1004项目导入模板_YfVeRXU.xls create mode 100644 upload/data/1005用户信息导入模板.xls create mode 100644 upload/data/1005用户信息导入模板_LRE2NKU.xls create mode 100644 upload/data/1005用户信息导入模板_stkXmtR.xls create mode 100644 upload/data/合作伙伴.xls create mode 100644 upload/doc/1001部门岗位员工导入模板.xls create mode 100644 upload/doc/1002期初库存导入模板.csv create mode 100644 upload/doc/1003合作伙伴导入模板.xls create mode 100644 upload/doc/1004项目导入模板.xls create mode 100644 upload/doc/2001报价单明细样例.xls create mode 100644 upload/doc/2002需求计划明细样例.xls create mode 100644 upload/doc/2003采购单明细样例.xls create mode 100644 upload/hr profile/mis.sql create mode 100644 upload/inventory/INVENTORY.csv create mode 100644 upload/inventory/INVENTORY_PPfDioe.csv create mode 100644 upload/offer sheet/backbone.js create mode 100644 upload/project/2014年17月份时事政治全集.docx create mode 100644 upload/project/综合知识与能力素质.docx create mode 100644 workflow/__init__.py create mode 100644 workflow/admin.py create mode 100644 workflow/apps.py create mode 100644 workflow/models.py create mode 100644 workflow/tests.py create mode 100644 workflow/views.py diff --git a/basedata/__init__.py b/basedata/__init__.py new file mode 100644 index 0000000..03d7ed8 --- /dev/null +++ b/basedata/__init__.py @@ -0,0 +1,2 @@ + +default_app_config = 'basedata.apps.BaseDataConfig' \ No newline at end of file diff --git a/basedata/admin.py b/basedata/admin.py new file mode 100644 index 0000000..a55761c --- /dev/null +++ b/basedata/admin.py @@ -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) \ No newline at end of file diff --git a/basedata/apps.py b/basedata/apps.py new file mode 100644 index 0000000..cbd8dc6 --- /dev/null +++ b/basedata/apps.py @@ -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') \ No newline at end of file diff --git a/basedata/models.py b/basedata/models.py new file mode 100644 index 0000000..68f77f6 --- /dev/null +++ b/basedata/models.py @@ -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") diff --git a/basedata/tests.py b/basedata/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/basedata/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/basedata/urls.py b/basedata/urls.py new file mode 100644 index 0000000..e9d2ec5 --- /dev/null +++ b/basedata/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls import include, url,static +import basedata.views + +urlpatterns = [ + url(r"dataimport/(?P\d+)/action", 'basedata.views.action_import'), +] diff --git a/basedata/views.py b/basedata/views.py new file mode 100644 index 0000000..744b316 --- /dev/null +++ b/basedata/views.py @@ -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) diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 0000000..db0afd1 --- /dev/null +++ b/common/__init__.py @@ -0,0 +1 @@ +__author__ = 'Administrator' diff --git a/common/const.py b/common/const.py new file mode 100644 index 0000000..cb30663 --- /dev/null +++ b/common/const.py @@ -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 diff --git a/common/generic.py b/common/generic.py new file mode 100644 index 0000000..50a4e03 --- /dev/null +++ b/common/generic.py @@ -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',) diff --git a/hr/__init__.py b/hr/__init__.py new file mode 100644 index 0000000..9d3c63a --- /dev/null +++ b/hr/__init__.py @@ -0,0 +1 @@ +default_app_config = 'hr.apps.MyAppConfig' \ No newline at end of file diff --git a/hr/admin.py b/hr/admin.py new file mode 100644 index 0000000..af662e2 --- /dev/null +++ b/hr/admin.py @@ -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) \ No newline at end of file diff --git a/hr/apps.py b/hr/apps.py new file mode 100644 index 0000000..5325f71 --- /dev/null +++ b/hr/apps.py @@ -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") diff --git a/hr/models.py b/hr/models.py new file mode 100644 index 0000000..3582a05 --- /dev/null +++ b/hr/models.py @@ -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") + diff --git a/hr/tests.py b/hr/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/hr/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/hr/views.py b/hr/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/hr/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/invent/__init__.py b/invent/__init__.py new file mode 100644 index 0000000..79f626d --- /dev/null +++ b/invent/__init__.py @@ -0,0 +1 @@ +default_app_config = "invent.apps.MyAppConfig" \ No newline at end of file diff --git a/invent/admin.py b/invent/admin.py new file mode 100644 index 0000000..5bfbd32 --- /dev/null +++ b/invent/admin.py @@ -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) diff --git a/invent/apps.py b/invent/apps.py new file mode 100644 index 0000000..25d842a --- /dev/null +++ b/invent/apps.py @@ -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") diff --git a/invent/models.py b/invent/models.py new file mode 100644 index 0000000..b863956 --- /dev/null +++ b/invent/models.py @@ -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") \ No newline at end of file diff --git a/invent/tests.py b/invent/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/invent/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/invent/urls.py b/invent/urls.py new file mode 100644 index 0000000..f5bbc89 --- /dev/null +++ b/invent/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import include, url,static +import invent.views + +urlpatterns = [ + url(r"stockin/(?P\d+)/cin", 'invent.views.action_in'), + url(r"initialinventory/(?P\d+)/cin", 'invent.views.action_init'), + url(r"stockout/(?P\d+)/out", 'invent.views.action_out'), + url(r"warereturn/(?P\d+)/cin", 'invent.views.action_return'), + url(r"wareadjust/(?P\d+)/adjust", 'invent.views.action_adjust'), +] diff --git a/invent/views.py b/invent/views.py new file mode 100644 index 0000000..d747b63 --- /dev/null +++ b/invent/views.py @@ -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) \ No newline at end of file diff --git a/locale/zh_CN/LC_MESSAGES/django.mo b/locale/zh_CN/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..9e6a941d29ec4d64d2f3fa1a57e6387c27e633fd GIT binary patch literal 21184 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, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-05-01 19:18+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: .\basedata\apps.py:9 +msgid "BaseData" +msgstr "基础数据" + +#: .\basedata\models.py:16 +msgid "list code" +msgstr "编号" + +#: .\basedata\models.py:17 +msgid "list name" +msgstr "名称" + +#: .\basedata\models.py:18 .\syscfg\models.py:40 .\syscfg\models.py:41 +#: .\syscfg\models.py:48 +msgid "module" +msgstr "模块" + +#: .\basedata\models.py:19 .\basedata\models.py:38 .\organ\models.py:16 +#: .\organ\models.py:60 .\syscfg\models.py:37 .\syscfg\models.py:54 +#: .\syscfg\models.py:68 +msgid "in use" +msgstr "在用?" + +#: .\basedata\models.py:20 +msgid "is init" +msgstr "初始数据?" + +#: .\basedata\models.py:21 +msgid "is locked" +msgstr "锁定?" + +#: .\basedata\models.py:22 +msgid "locked by" +msgstr "锁定用户" + +#: .\basedata\models.py:23 +msgid "locked time" +msgstr "锁定时间" + +#: .\basedata\models.py:26 .\basedata\models.py:27 +msgid "value list" +msgstr "值列表" + +#: .\basedata\models.py:34 +msgid "list group" +msgstr "值列表组" + +#: .\basedata\models.py:36 +msgid "item code" +msgstr "项编号" + +#: .\basedata\models.py:37 +msgid "item name" +msgstr "项名称" + +#: .\basedata\models.py:39 .\organ\models.py:34 .\organ\models.py:66 +#: .\organ\models.py:104 .\syscfg\models.py:34 .\syscfg\models.py:52 +msgid "weight" +msgstr "排序权重" + +#: .\basedata\models.py:53 .\basedata\models.py:54 +msgid "list item" +msgstr "列表项" + +#: .\basedata\models.py:63 .\basedata\models.py:73 .\basedata\models.py:74 +#: .\organ\models.py:23 +msgid "address" +msgstr "地址" + +#: .\basedata\models.py:64 .\organ\models.py:24 +msgid "zipcode" +msgstr "邮编" + +#: .\basedata\models.py:65 .\basedata\models.py:105 .\organ\models.py:27 +#: .\organ\models.py:63 +msgid "phone" +msgstr "联系电话" + +#: .\basedata\models.py:66 .\basedata\models.py:104 .\organ\models.py:26 +#: .\organ\models.py:64 +msgid "contacts" +msgstr "联系人" + +#: .\basedata\models.py:82 +msgid "Customer" +msgstr "客户" + +#: .\basedata\models.py:83 +msgid "Supplier" +msgstr "供应商" + +#: .\basedata\models.py:93 +msgid "partner code" +msgstr "合作伙伴编号" + +#: .\basedata\models.py:94 +msgid "partner name" +msgstr "名称" + +#: .\basedata\models.py:95 .\organ\models.py:14 .\organ\models.py:57 +#: .\organ\models.py:96 +msgid "short name" +msgstr "简称" + +#: .\basedata\models.py:96 .\organ\models.py:15 .\organ\models.py:58 +#: .\organ\models.py:97 +msgid "pinyin" +msgstr "拼音/英语" + +#: .\basedata\models.py:97 .\organ\models.py:59 +msgid "type" +msgstr "类别" + +#: .\basedata\models.py:98 +msgid "level" +msgstr "等级" + +#: .\basedata\models.py:100 .\organ\models.py:18 +msgid "tax num" +msgstr "纳税识别号" + +#: .\basedata\models.py:101 .\organ\models.py:19 +msgid "tax address" +msgstr "开票地址/电话" + +#: .\basedata\models.py:102 .\organ\models.py:20 +msgid "tax account" +msgstr "发票开户行" + +#: .\basedata\models.py:106 .\basedata\models.py:119 +msgid "memo" +msgstr "备注" + +#: .\basedata\models.py:109 .\basedata\models.py:110 .\basedata\models.py:120 +msgid "partner" +msgstr "合作伙伴" + +#: .\basedata\models.py:117 +msgid "account num" +msgstr "银行帐号" + +#: .\basedata\models.py:118 +msgid "bank name" +msgstr "开户行" + +#: .\basedata\models.py:123 .\basedata\models.py:124 +msgid "bank account" +msgstr "银行账户" + +#: .\common\const.py:20 +msgid "OFF" +msgstr "关闭" + +#: .\common\const.py:21 +msgid "ON" +msgstr "开启" + +#: .\common\generic.py:31 .\syscfg\models.py:13 +msgid "begin date" +msgstr "开始日期" + +#: .\common\generic.py:32 .\syscfg\models.py:14 +msgid "end date" +msgstr "结束日期" + +#: .\common\generic.py:33 +msgid "creator" +msgstr "创建用户" + +#: .\common\generic.py:34 +msgid "modifier" +msgstr "修改用户" + +#: .\common\generic.py:35 +msgid "creation" +msgstr "创建时间" + +#: .\common\generic.py:36 +msgid "modification" +msgstr "修改时间" + +#: .\organ\apps.py:9 .\organ\models.py:37 .\organ\models.py:38 +#: .\organ\models.py:54 +msgid "organization" +msgstr "组织机构" + +#: .\organ\models.py:12 .\organ\models.py:55 +msgid "organ code" +msgstr "机构编号" + +#: .\organ\models.py:13 .\organ\models.py:56 +msgid "organ name" +msgstr "机构名称" + +#: .\organ\models.py:22 +msgid "representative " +msgstr "法人代表" + +#: .\organ\models.py:25 .\organ\models.py:62 +msgid "fax" +msgstr "传真" + +#: .\organ\models.py:28 +msgid "website" +msgstr "网址" + +#: .\organ\models.py:29 .\organ\models.py:65 +msgid "email" +msgstr "邮箱" + +#: .\organ\models.py:30 +msgid "license code" +msgstr "营业执照代码" + +#: .\organ\models.py:31 +msgid "certificate code" +msgstr "组织机构代码" + +#: .\organ\models.py:32 +msgid "business license" +msgstr "营业执照" + +#: .\organ\models.py:33 +msgid "organization code certificate" +msgstr "组织机构证书" + +#: .\organ\models.py:46 +msgid "BRANCH" +msgstr "分公司/事业部" + +#: .\organ\models.py:47 +msgid "DEPARTMENT" +msgstr "一级部门" + +#: .\organ\models.py:48 +msgid "OFFICE" +msgstr "二级部门/处室/科室" + +#: .\organ\models.py:49 +msgid "TEAM" +msgstr "组/班" + +#: .\organ\models.py:50 +msgid "COMMITTEE" +msgstr "委员会" + +#: .\organ\models.py:53 .\organ\models.py:93 .\syscfg\models.py:36 +#: .\syscfg\models.py:69 +msgid "parent" +msgstr "父级" + +#: .\organ\models.py:61 .\organ\models.py:100 +msgid "is virtual" +msgstr "虚拟?" + +#: .\organ\models.py:69 .\organ\models.py:70 .\organ\models.py:92 +msgid "org unit" +msgstr "组织单元" + +#: .\organ\models.py:78 +msgid "Admin Position" +msgstr "管理类" + +#: .\organ\models.py:79 +msgid "Sale Position" +msgstr "营销类" + +#: .\organ\models.py:80 +msgid "Technology Position" +msgstr "技术类" + +#: .\organ\models.py:81 +msgid "Produce Position" +msgstr "生产/操作类" + +#: .\organ\models.py:85 +msgid "BASIC" +msgstr "基础" + +#: .\organ\models.py:86 +msgid "MEDIUM" +msgstr "中等" + +#: .\organ\models.py:87 +msgid "SENIOR" +msgstr "高级" + +#: .\organ\models.py:88 +msgid "PROFESSOR" +msgstr "教授" + +#: .\organ\models.py:89 +msgid "EXPERT" +msgstr "专家" + +#: .\organ\models.py:94 +msgid "position code" +msgstr "岗位编号" + +#: .\organ\models.py:95 +msgid "position name" +msgstr "岗位名称" + +#: .\organ\models.py:98 +msgid "position series" +msgstr "岗位序列" + +#: .\organ\models.py:99 +msgid "position grade" +msgstr "岗位级别" + +#: .\organ\models.py:101 +msgid "position description" +msgstr "岗位说明" + +#: .\organ\models.py:102 +msgid "qualification" +msgstr "任职资格" + +#: .\organ\models.py:103 +msgid "reference" +msgstr "参考资料" + +#: .\organ\models.py:107 .\organ\models.py:108 +msgid "position" +msgstr "岗位" + +#: .\syscfg\apps.py:9 +msgid "SysConfig" +msgstr "系统配置" + +#: .\syscfg\models.py:15 +msgid "site name" +msgstr "站点名称" + +#: .\syscfg\models.py:16 +msgid "site description" +msgstr "描述信息" + +#: .\syscfg\models.py:17 +msgid "administrator" +msgstr "管理员" + +#: .\syscfg\models.py:23 .\syscfg\models.py:24 +msgid "Site" +msgstr "站点" + +#: .\syscfg\models.py:31 +msgid "module code" +msgstr "模块编号" + +#: .\syscfg\models.py:32 +msgid "module name" +msgstr "模块名称" + +#: .\syscfg\models.py:33 +msgid "module url" +msgstr "URL" + +#: .\syscfg\models.py:35 .\syscfg\models.py:53 +msgid "style class" +msgstr "样式类" + +#: .\syscfg\models.py:49 +msgid "menu code" +msgstr "菜单编号" + +#: .\syscfg\models.py:50 +msgid "menu name" +msgstr "菜单名称" + +#: .\syscfg\models.py:51 +msgid "menu url" +msgstr "URL" + +#: .\syscfg\models.py:57 .\syscfg\models.py:58 +msgid "menu" +msgstr "菜单" + +#: .\syscfg\models.py:65 +msgid "role code" +msgstr "角色编号" + +#: .\syscfg\models.py:66 +msgid "role name" +msgstr "角色名称" + +#: .\syscfg\models.py:67 +msgid "description" +msgstr "描述信息" + +#: .\syscfg\models.py:70 +msgid "role users" +msgstr "分配用户" + +#: .\syscfg\models.py:71 +msgid "role menus" +msgstr "分配菜单" + +#: .\syscfg\models.py:74 .\syscfg\models.py:75 +msgid "role" +msgstr "角色" + +msgid "code" +msgstr "编号" + +msgid "address type" +msgstr "地址类型" + +msgid "project" +msgstr "项目" + +msgid "project code" +msgstr "项目编号" + +msgid "project name" +msgstr "项目名称" + +msgid "status" +msgstr "状态" + +msgid "project type" +msgstr "性质" + +msgid "budget" +msgstr "预算金额" + +msgid "income" +msgstr "收入金额" + +msgid "expand" +msgstr "支出金额" + +msgid "blueprint" +msgstr "技术/图纸" + +msgid "offer sheet" +msgstr "报价单" + +msgid "business document" +msgstr "商务/标书" + +msgid "related users" +msgstr "关系人" + +msgid "trade" +msgstr "经济行业" + +msgid "brand" +msgstr "品牌" + +msgid "category" +msgstr "分类" + +msgid "path" +msgstr "路径" + +msgid "material" +msgstr "物料" + +msgid "material code" +msgstr "物料编号" + +msgid "material name" +msgstr "物料名称" + +msgid "bar code" +msgstr "条形码" + +msgid "specifications" +msgstr "规格型号" + +msgid "is equipment" +msgstr "设备?" + +msgid "can sale" +msgstr "可销售" + +msgid "warehouse" +msgstr "仓库" + +msgid "measure" +msgstr "计量单位" + +msgid "stock price" +msgstr "库存单价" + +msgid "purchase price" +msgstr "采购单价" + +msgid "sale price" +msgstr "销售单价" + +msgid "technical parameter" +msgstr "技术参数" + +msgid "technical value" +msgstr "参数值" + +msgid "value" +msgstr "值" + +msgid "location" +msgstr "位置" + +msgid "material category" +msgstr "物料分类" + +msgid "expenses account" +msgstr "费用科目" + +msgid "HR-DOMAIN" +msgstr "人事费用" + +msgid "OFFICE-DOMAIN" +msgstr "行政办公" + +msgid "PUBLIS-DOMAIN" +msgstr "运营公共" + +msgid "MUNADOMAIN" +msgstr "生产制造" + +msgid "BUSINESS" +msgstr "市场商务" + +msgid "OTHER" +msgstr "其他" + +msgid "employee number" +msgstr "工号" + +msgid "employee name" +msgstr "职员姓名" + +msgid "birthday" +msgstr "出生日期" + +msgid "gender" +msgstr "性别" + +msgid "id card" +msgstr "身份证号码" + +msgid "nationality" +msgstr "国籍" + +msgid "hometown" +msgstr "籍贯" + +msgid "home address" +msgstr "家庭住址" + +msgid "emergency contacts" +msgstr "紧急联系人/方式" + +msgid "office phone" +msgstr "办公电话" + +msgid "employee rank" +msgstr "职员职级" + +msgid "workday" +msgstr "参加工作日期" + +msgid "start date" +msgstr "入司日期" + +msgid "religion" +msgstr "宗教信仰" + +msgid "marital status" +msgstr "婚姻状况" + +msgid "political party" +msgstr "政治面貌" + +msgid "nation" +msgstr "民族" + +msgid "employ ygxs" +msgstr "用工形式" + +msgid "employ status" +msgstr "人员状态" + +msgid "employ category" +msgstr "人员类别" + +msgid "literacy" +msgstr "文化程度" + +msgid "major type" +msgstr "专业类别" + +msgid "major degree" +msgstr "学位" + +msgid "tag1 fzjr" +msgstr "复转军人?" + +msgid "tag2 dwld" +msgstr "党委负责人?" + +msgid "tag3 dsjs" +msgstr "董事监事?" + +msgid "tag4 byzk" +msgstr "兵役状况" + +msgid "employee" +msgstr "职员" + +msgid "special job" +msgstr "特殊工种?" + +msgid "family member" +msgstr "家庭成员" + +msgid "education experience" +msgstr "教育履历" + +msgid "work experience" +msgstr "工作履历" + +msgid "social status" +msgstr "人员身份" + +msgid "emergency" +msgstr "紧急联系人?" + +msgid "edu type" +msgstr "教育类型" + +msgid "school" +msgstr "毕业学校" + +msgid "major" +msgstr "专业" + +msgid "family title" +msgstr "成员称谓" + +msgid "health" +msgstr "健康状况" + +msgid "Content Types" +msgstr "内容类型" + +msgid "workflow model" +msgstr "工作流模型" + +msgid "workflow code" +msgstr "编号" + +msgid "workflow name" +msgstr "工作流名称" + +msgid "app name" +msgstr "应用名称" + +msgid "model name" +msgstr "模型名称" + +msgid "node code" +msgstr "节点编号" + +msgid "node name" +msgstr "节点名称" + +msgid "tooltip words" +msgstr "提示语" + +msgid "start node" +msgstr "起始节点?" + +msgid "stop node" +msgstr "结束节点?" + +msgid "can terminate" +msgstr "允许终止?" + +msgid "can deny" +msgstr "允许拒绝?" + +msgid "email notice" +msgstr "邮件通知?" + +msgid "short message notice" +msgstr "短信通知?" + +msgid "approve node" +msgstr "批准节点" + +msgid "handler" +msgstr "处理人" + +msgid "workflow node" +msgstr "工作流节点" + +msgid "NEW" +msgstr "新建" + +msgid "IN PROGRESS" +msgstr "处理中" + +msgid "DENY" +msgstr "拒绝" + +msgid "TERMINATED" +msgstr "已终止审批" + +msgid "APPROVED" +msgstr "已批准" + +msgid "start user" +msgstr "提交人" + +msgid "start time" +msgstr "提交时间" + +msgid "approved time" +msgstr "批准时间" + +msgid "current node" +msgstr "当前节点" + +msgid "SUBMIT" +msgstr "提交" + +msgid "AGREE" +msgstr "同意" + +msgid "workflow instance" +msgstr "工作流实例" + +msgid "submitter" +msgstr "提交人" + +msgid "process time" +msgstr "处理时间" + +msgid "process type" +msgstr "处理类型" + +msgid "workflow history" +msgstr "审批记录" + +msgid "arrived time" +msgstr "到达时间" + +msgid "is read" +msgstr "已阅?" + +msgid "read time" +msgstr "阅读时间" + +msgid "workflow todo" +msgstr "待办任务" + +msgid "workflow" +msgstr "工作流" + +msgid "No, take me back" +msgstr "不,返回" + +msgid "submit" +msgstr "提交" + +msgid "Are you sure you want to submit the %(object_name)s \"%(escaped_object)s\"? " +msgstr "您确定要提交\"%(escaped_object)s\"进行审批吗?" + +msgid "next node" +msgstr "下一节点" + +msgid "designated department" +msgstr "部门范围" + +msgid "designated user" +msgstr "指定用户" + +msgid "designated role" +msgstr "指定角色" + +msgid "designated position" +msgstr "指定岗位" + +msgid "handler type" +msgstr "处理人类型" + +msgid "Please handle the request %(verbose)s:%(object)s" +msgstr "请审批单据:" + +msgid "node" +msgstr "节点" + +msgid "Workflow Memo" +msgstr "审批意见" + +msgid "Workflow History" +msgstr "审批历史" + +msgid "already read" +msgstr "已阅" + +msgid "unread" +msgstr "未阅" + +msgid "workflow started successfully" +msgstr "工作流提交成功" + +msgid "the object is already in workflow" +msgstr "对象已提交审批,请勿重复提交" + +msgid "agree" +msgstr "同意" + +msgid "deny" +msgstr "拒绝" + +msgid "terminate" +msgstr "终止" + +msgid "workflow approve" +msgstr "工作流审批" + +msgid "No workflow model was found" +msgstr "未配置工作流模型" + +msgid "you needs to config a workflow model for this content type" +msgstr "请在 工作流/工作流模型 中配置本业务的流程模型" + +msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +msgstr "按住\"Ctrl\"键或者Mac上的\"Command\"键进行多选" + +msgid "No user was configured to handle this node" +msgstr "本节点未配置处理人,请联系管理员配置处理人" + +msgid "current node is stop node,click the submit button to complete it" +msgstr "当前为流程最后一个环节,点击\"确定\"完成流程" + +msgid "workflow approved successfully" +msgstr "工作流审批成功" + +msgid "COMPLETED" +msgstr "完成" + +msgid "Summary" +msgstr "摘要" + +msgid "Objects" +msgstr "对象清单" + +msgid "your apply has been denied,you can restart a new apply" +msgstr "您的申请未获得批准,您可重新启动申请" + +msgid "restart workflow" +msgstr "重新启动" + +msgid "work order" +msgstr "工单" + +msgid "work orders" +msgstr "工单" + +msgid "classification" +msgstr "分类" + +msgid "business domain" +msgstr "业务域" + +msgid "workorder apply" +msgstr "工单服务" + +msgid "workorder code" +msgstr "工单编号" + +msgid "title" +msgstr "标题" + +msgid "amount" +msgstr "数量" + +msgid "price" +msgstr "单价" + +msgid "service name" +msgstr "服务名称" + +msgid "refer wo" +msgstr "参考工单" + +msgid "self help" +msgstr "个人自助" + +msgid "extra values" +msgstr "扩展信息" + +msgid "workorder items" +msgstr "工单明细" + +msgid "extra param" +msgstr "扩展参数" + +msgid "extra params" +msgstr "扩展参数" + +msgid "param value" +msgstr "值" + +msgid "data type" +msgstr "数据类别" + +msgid "data source" +msgstr "数据源" + +msgid "DATE" +msgstr "日期" + +msgid "NUMBER" +msgstr "数字" + +msgid "loans" +msgstr "借款申请" + +msgid "loan" +msgstr "借款申请" + +msgid "reimbursement" +msgstr "费用报销" + +msgid "reimbursements" +msgstr "费用报销" + +msgid "fee item" +msgstr "费用明细" + +msgid "fee items" +msgstr "费用明细" + +msgid "fee code" +msgstr "单据编号" + +msgid "loan code" +msgstr "单据编号" + +msgid "loan amount" +msgstr "借款金额" + +msgid "logout time" +msgstr "核销时间" + +msgid "logout amount" +msgstr "核销金额" + +msgid "amount of money" +msgstr "金额" + +msgid "cost center" +msgstr "成本中心" + +msgid "loan record" +msgstr "借款单据" + +msgid "pay amount" +msgstr "支付金额" + +msgid "occur date" +msgstr "发生日期" + +msgid "fico" +msgstr "财务信息" + +msgid "Authentication and Authorization" +msgstr "认证授权" + +msgid "human resource" +msgstr "人力资源" + +msgid "salary items" +msgstr "工资项" + +msgid "salary item" +msgstr "工资项" + +msgid "plus or minus" +msgstr "增减属性" + +msgid "employee entries" +msgstr "人员入职" + +msgid "employee entry" +msgstr "人员入职" + +msgid "designate position" +msgstr "拟任岗位" + +msgid "mail address" +msgstr "邮寄地址" + +msgid "profile" +msgstr "简历信息" + +msgid "org distribute" +msgstr "组织分配" + +msgid "guider" +msgstr "指导老师" + +msgid "calculate way" +msgstr "计算方式" + +msgid "fixed value" +msgstr "固定值" + +msgid "base value" +msgstr "基数值" + +msgid "org percent" +msgstr "公司比例" + +msgid "employee percent" +msgstr "员工比例" + +msgid "probation months" +msgstr "试聘期" + +msgid "probation begin" +msgstr "试聘开始" + +msgid "probation end" +msgstr "试聘结束" + +msgid "is required" +msgstr "必需?" + +msgid "extra value" +msgstr "扩展信息" + +msgid "workorder item" +msgstr "工单明细" + +msgid "inventory manage" +msgstr "库存管理" + +msgid "Initial Inventory" +msgstr "期初库存" + +msgid "StockIn" +msgstr "入库单" + +msgid "StockOut" +msgstr "领料单" + +msgid "execute time" +msgstr "执行时间" + +msgid "in items" +msgstr "入库明细" + +msgid "in item" +msgstr "入库明细" + +msgid "out items" +msgstr "出库明细" + +msgid "out item" +msgstr "出库明细" + +msgid "init item" +msgstr "期初明细" + +msgid "PLUS" +msgstr "增加" + +msgid "MINUS" +msgstr "减少" + +msgid "EXECUTED" +msgstr "已执行" + +msgid "QUALITY TESTING" +msgstr "质检" + +msgid "purchase manage" +msgstr "采购管理" + +msgid "purchase orders" +msgstr "采购单" + +msgid "purchase order" +msgstr "采购单" + +msgid "order date" +msgstr "订单日期" + +msgid "arrive date" +msgstr "交货日期" + +msgid "count" +msgstr "数量" + +msgid "money amount" +msgstr "金额" + +msgid "discount amount" +msgstr "折扣金额" + +msgid "tax rate" +msgstr "税率" + +msgid "po item" +msgstr "采购明细" + +msgid "discount price" +msgstr "折后单价" + +msgid "batch" +msgstr "批次号" + +msgid "Action Stock In" +msgstr "入库" + +msgid "Action Stock Out" +msgstr "出库" + +msgid "money of amount" +msgstr "金额" + +msgid "stock in money of amount" +msgstr "入库金额" + +msgid "entry time" +msgstr "入库时间" + +msgid "ALREADY STOCK IN" +msgstr "已入库" + +msgid "Inventory" +msgstr "实时库存" + +msgid "CHAR" +msgstr "字符" + +msgid "inventory material" +msgstr "库存物资" + +msgid "stock out time" +msgstr "出库时间" + +msgid "stock out amount" +msgstr "出库金额" + +msgid "Invoice" +msgstr "发票" + +msgid "invoice date" +msgstr "发票日期" + +msgid "invoice code" +msgstr "发票代码" + +msgid "invoice number" +msgstr "发票编号" + +msgid "po amount" +msgstr "采购金额" + +msgid "invoice amount" +msgstr "发票金额" + +msgid "invoice file" +msgstr "发票文件" + +msgid "pay date" +msgstr "付款日期" + +msgid "pay code" +msgstr "付款编号" + +msgid "response code" +msgstr "银行回执" + +msgid "Payment" +msgstr "采购付款" + +msgid "activity" +msgstr "活动" + +msgid "activities" +msgstr "活动" + +msgid "begin time" +msgstr "开始时间" + +msgid "end time" +msgstr "结束时间" + +msgid "host" +msgstr "主持人" + +msgid "speaker" +msgstr "主讲人" + +msgid "room" +msgstr "房间/会议室" + +msgid "mail list" +msgstr "邮件组" + +msgid "mail notice" +msgstr "邮件通知" + +msgid "weixin notice" +msgstr "微信通知" + +msgid "attach" +msgstr "附件" + +msgid "Meeting" +msgstr "会议" + +msgid "Train" +msgstr "培训" + +msgid "Community" +msgstr "集体活动" + +msgid "out user" +msgstr "领料人" + +msgid "other info" +msgstr "其他信息" + +msgid "InOut History" +msgstr "出入库历史" + +msgid "source" +msgstr "原始单据" + +msgid "plus or minus prop" +msgstr "增减属性" + +msgid "deliver address" +msgstr "交付地址" + +msgid "deliver date" +msgstr "交付日期" + +msgid "sales man" +msgstr "销售员" + +msgid "invoice type" +msgstr "发票类型" + +msgid "sale management" +msgstr "销售管理" + +msgid "sale order" +msgstr "销售订单" + +msgid "order detail" +msgstr "订单明细" + +msgid "Payment Collection" +msgstr "销售回款" + +msgid "collection date" +msgstr "回款日期" + +msgid "collection code" +msgstr "回款单号" + +msgid "order amount" +msgstr "合同金额" + +msgid "collection amount" +msgstr "到账金额" + +msgid "offer detail" +msgstr "报价明细" + +msgid "offer date" +msgstr "报价日期" + +msgid "offer man" +msgstr "报价员" + +msgid "offer sheet file" +msgstr "报价表" + +msgid "cost price" +msgstr "成本单价" + +msgid "mt type" +msgstr "物料性质" + +msgid "ware return" +msgstr "返库单" + +msgid "return item" +msgstr "返库明细" + +msgid "out count" +msgstr "领料数量" + +msgid "Action Ware Return" +msgstr "执行返库" + +msgid "ware adjust" +msgstr "库存调整" + +msgid "adjust item" +msgstr "调整明细" + +msgid "plus or minus property" +msgstr "增减属性" + +msgid "Action Ware Adjust" +msgstr "执行调整" + +msgid "data import" +msgstr "导入" + +msgid "date" +msgstr "日期" + +msgid "clear old data?" +msgstr "清除旧数据?" + +msgid "handler class" +msgstr "处理类" + +msgid "import" +msgstr "导入" + +msgid "action" +msgstr "执行" + +msgid "data import successfully" +msgstr "数据导入成功" + +msgid "applier" +msgstr "申请人" + +msgid "pay" +msgstr "支付" + +msgid "PAYED" +msgstr "已支付" + +msgid "action successfully" +msgstr "执行成功" + +msgid "Are your sure to execute the operations?" +msgstr "您确认要执行本操作吗?" + +msgid "to be imported detail" +msgstr "待导入明细" + +msgid "draft" +msgstr "草稿" + +msgid "published" +msgstr "已发布" + +msgid "keywords" +msgstr "关键词" + +msgid "BUSINESS DOC" +msgstr "业务文档" + +msgid "SYSTEM MANUAL" +msgstr "系统手册" + +msgid "document" +msgstr "文档" + +msgid "documents" +msgstr "文档" + +msgid "%(app)s administration" +msgstr "%(app)s 模块" + +msgid "next user handler" +msgstr "next用户处理类" + +msgid "next node handler" +msgstr "next节点处理类" + +msgid "status field" +msgstr "状态字段" + +msgid "status value" +msgstr "状态值" + +msgid "execute action" +msgstr "执行动作" + +msgid "can edit" +msgstr "可编辑?" + +msgid "attention" +msgstr "注意" + +msgid "is done" +msgstr "已办?" + +msgid "Are you sure to deny the request?" +msgstr "您确定要拒绝申请吗?" + +msgid "Are you sure to terminate the request?" +msgstr "您确定要终止申请吗?" + +msgid "workflow restarted success" +msgstr "工作流重启成功" + +msgid "export selected %(verbose_name_plural)s" +msgstr "导出所选的 %(verbose_name_plural)s" + +msgid "publish selected %(verbose_name_plural)s" +msgstr "发布所选的 %(verbose_name_plural)s" + +msgid "Are your sure to execute the check out operations?" +msgstr "您确定要执行出库操作吗?" + +msgid "check out successfully" +msgstr "已成功出库" + +msgid "check in successfully" +msgstr "已成功入库" \ No newline at end of file diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..1620c50 --- /dev/null +++ b/manage.py @@ -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) diff --git a/midware/__init__.py b/midware/__init__.py new file mode 100644 index 0000000..db0afd1 --- /dev/null +++ b/midware/__init__.py @@ -0,0 +1 @@ +__author__ = 'Administrator' diff --git a/midware/cuser.py b/midware/cuser.py new file mode 100644 index 0000000..d8989e9 --- /dev/null +++ b/midware/cuser.py @@ -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] diff --git a/mis/__init__.py b/mis/__init__.py new file mode 100644 index 0000000..fbb0a62 --- /dev/null +++ b/mis/__init__.py @@ -0,0 +1,4 @@ +from django.contrib import admin + +admin.site.site_header = 'Django-ERP' +admin.site.site_title = 'ERP' \ No newline at end of file diff --git a/mis/production.py b/mis/production.py new file mode 100644 index 0000000..f277194 --- /dev/null +++ b/mis/production.py @@ -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/' \ No newline at end of file diff --git a/mis/settings.py b/mis/settings.py new file mode 100644 index 0000000..5e4b36b --- /dev/null +++ b/mis/settings.py @@ -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/' \ No newline at end of file diff --git a/mis/urls.py b/mis/urls.py new file mode 100644 index 0000000..321801a --- /dev/null +++ b/mis/urls.py @@ -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\w+)/(?P\w+)/(?P\d+)/start",'workflow.views.start'), + url(r"^admin/(?P\w+)/(?P\w+)/(?P\d+)/approve/(?P\d+)",'workflow.views.approve'), + url(r"^admin/(?P\w+)/(?P\w+)/(?P\d+)/restart/(?P\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) diff --git a/mis/views.py b/mis/views.py new file mode 100644 index 0000000..a88c4fc --- /dev/null +++ b/mis/views.py @@ -0,0 +1,5 @@ +from django.http.response import HttpResponseRedirect + + +def home(request): + return HttpResponseRedirect("/admin") \ No newline at end of file diff --git a/mis/wsgi.py b/mis/wsgi.py new file mode 100644 index 0000000..31990a7 --- /dev/null +++ b/mis/wsgi.py @@ -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() diff --git a/organ/__init__.py b/organ/__init__.py new file mode 100644 index 0000000..ea52637 --- /dev/null +++ b/organ/__init__.py @@ -0,0 +1 @@ +default_app_config = 'organ.apps.OrganConfig' \ No newline at end of file diff --git a/organ/admin.py b/organ/admin.py new file mode 100644 index 0000000..bf142f4 --- /dev/null +++ b/organ/admin.py @@ -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) \ No newline at end of file diff --git a/organ/apps.py b/organ/apps.py new file mode 100644 index 0000000..d3aceac --- /dev/null +++ b/organ/apps.py @@ -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') \ No newline at end of file diff --git a/organ/models.py b/organ/models.py new file mode 100644 index 0000000..95e3347 --- /dev/null +++ b/organ/models.py @@ -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') diff --git a/organ/tests.py b/organ/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/organ/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/organ/views.py b/organ/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/organ/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/plugin/__init__.py b/plugin/__init__.py new file mode 100644 index 0000000..ce3bd2f --- /dev/null +++ b/plugin/__init__.py @@ -0,0 +1,3 @@ +# created at 15-6-27 +# coding=utf-8 +__author__ = 'zhugl' diff --git a/plugin/wfactions.py b/plugin/wfactions.py new file mode 100644 index 0000000..803fc2e --- /dev/null +++ b/plugin/wfactions.py @@ -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() \ No newline at end of file diff --git a/plugin/wfnodes.py b/plugin/wfnodes.py new file mode 100644 index 0000000..ec6bca2 --- /dev/null +++ b/plugin/wfnodes.py @@ -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() diff --git a/plugin/wfusers.py b/plugin/wfusers.py new file mode 100644 index 0000000..4dc6b45 --- /dev/null +++ b/plugin/wfusers.py @@ -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() \ No newline at end of file diff --git a/plugin/xls.py b/plugin/xls.py new file mode 100644 index 0000000..7f07e6f --- /dev/null +++ b/plugin/xls.py @@ -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() + diff --git a/purchase/__init__.py b/purchase/__init__.py new file mode 100644 index 0000000..8ef3b57 --- /dev/null +++ b/purchase/__init__.py @@ -0,0 +1 @@ +default_app_config = "purchase.apps.MyAppConfig" \ No newline at end of file diff --git a/purchase/admin.py b/purchase/admin.py new file mode 100644 index 0000000..946dcbf --- /dev/null +++ b/purchase/admin.py @@ -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) diff --git a/purchase/apps.py b/purchase/apps.py new file mode 100644 index 0000000..e6efba6 --- /dev/null +++ b/purchase/apps.py @@ -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") diff --git a/purchase/models.py b/purchase/models.py new file mode 100644 index 0000000..52cdf8e --- /dev/null +++ b/purchase/models.py @@ -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") \ No newline at end of file diff --git a/purchase/tests.py b/purchase/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/purchase/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/purchase/views.py b/purchase/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/purchase/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/sale/__init__.py b/sale/__init__.py new file mode 100644 index 0000000..69606b4 --- /dev/null +++ b/sale/__init__.py @@ -0,0 +1 @@ +default_app_config = "sale.apps.MyAppConfig" \ No newline at end of file diff --git a/sale/admin.py b/sale/admin.py new file mode 100644 index 0000000..86264ee --- /dev/null +++ b/sale/admin.py @@ -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) diff --git a/sale/apps.py b/sale/apps.py new file mode 100644 index 0000000..052b88f --- /dev/null +++ b/sale/apps.py @@ -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") diff --git a/sale/models.py b/sale/models.py new file mode 100644 index 0000000..d71d114 --- /dev/null +++ b/sale/models.py @@ -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') \ No newline at end of file diff --git a/sale/tests.py b/sale/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sale/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sale/views.py b/sale/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/sale/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/selfhelp/__init__.py b/selfhelp/__init__.py new file mode 100644 index 0000000..e5b99fa --- /dev/null +++ b/selfhelp/__init__.py @@ -0,0 +1 @@ +default_app_config = "selfhelp.apps.MyAppConfig" \ No newline at end of file diff --git a/selfhelp/admin.py b/selfhelp/admin.py new file mode 100644 index 0000000..0a52495 --- /dev/null +++ b/selfhelp/admin.py @@ -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) diff --git a/selfhelp/apps.py b/selfhelp/apps.py new file mode 100644 index 0000000..583e36d --- /dev/null +++ b/selfhelp/apps.py @@ -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") diff --git a/selfhelp/models.py b/selfhelp/models.py new file mode 100644 index 0000000..5fc023d --- /dev/null +++ b/selfhelp/models.py @@ -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) diff --git a/selfhelp/tests.py b/selfhelp/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/selfhelp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/selfhelp/urls.py b/selfhelp/urls.py new file mode 100644 index 0000000..750debd --- /dev/null +++ b/selfhelp/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls import include, url,static +import selfhelp.views + +urlpatterns = [ + url(r"(?P\w+)/(?P\d+)/pay", 'selfhelp.views.pay_action'), +] diff --git a/selfhelp/views.py b/selfhelp/views.py new file mode 100644 index 0000000..261d5a3 --- /dev/null +++ b/selfhelp/views.py @@ -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) diff --git a/static/css/maximus.css b/static/css/maximus.css new file mode 100644 index 0000000..f41a24e --- /dev/null +++ b/static/css/maximus.css @@ -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; +} \ No newline at end of file diff --git a/static/img/icon-submitlink.gif b/static/img/icon-submitlink.gif new file mode 100644 index 0000000000000000000000000000000000000000..65252893d142c7af89752ba5eee56fc731eb1dd8 GIT binary patch literal 122 zcmZ?wbhEHb6krfwSj5WE($eyuf#E+0GXTMV5DNqpf3h$#Ft9S{fH)wv49xZsyS&a7 z2r4jiX7ech>Wy-aRCrQzsnaOkk>!I{7@v$l)V@+DS$E-CUe_u#*k+_ChNu`#aGX^1 OJn-C-Yhucb4AuZ6?It*CBe}<>gB04sRoO8x{F4Bh#RD=A4RCXFcZ-QJ{^#J}h+~)lR0ve@zaFIUAHybOoSQ5B z|Mzd^{|*j7XMjxH3{(_}#Y8hRvzx0{ar{?OQaS-~<0FRWKw1)u_jsVb?NhTQ$x_deWPc4O)NkN2|oXRf%p{M+wuUw(Z# z`TWGXJ8Mf07p=Or^7yl3mtJ2C+~V)C-fh~&DX}}E_C4PF@Y93ee}B)tGUw-?pC_Il zZ#vO%{oS?y|Nqw=uUUR`+4?){5_iQh&Q{xM6OkFieY2o T4)tf0@^WEj=4)bdWUvMRbX#E6 literal 0 HcmV?d00001 diff --git a/static/js/maximus.js b/static/js/maximus.js new file mode 100644 index 0000000..b1d3f9e --- /dev/null +++ b/static/js/maximus.js @@ -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); \ No newline at end of file diff --git a/static/js/workorder.js b/static/js/workorder.js new file mode 100644 index 0000000..3ec5748 --- /dev/null +++ b/static/js/workorder.js @@ -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); diff --git a/syscfg/__init__.py b/syscfg/__init__.py new file mode 100644 index 0000000..557efda --- /dev/null +++ b/syscfg/__init__.py @@ -0,0 +1,2 @@ + +default_app_config = 'syscfg.apps.SysConfig' \ No newline at end of file diff --git a/syscfg/admin.py b/syscfg/admin.py new file mode 100644 index 0000000..cf8f765 --- /dev/null +++ b/syscfg/admin.py @@ -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) diff --git a/syscfg/apps.py b/syscfg/apps.py new file mode 100644 index 0000000..eb97ebd --- /dev/null +++ b/syscfg/apps.py @@ -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') \ No newline at end of file diff --git a/syscfg/models.py b/syscfg/models.py new file mode 100644 index 0000000..b84eebd --- /dev/null +++ b/syscfg/models.py @@ -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") diff --git a/syscfg/tests.py b/syscfg/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/syscfg/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/syscfg/views.py b/syscfg/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/syscfg/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/templates/admin/app_index.html b/templates/admin/app_index.html new file mode 100644 index 0000000..874ee81 --- /dev/null +++ b/templates/admin/app_index.html @@ -0,0 +1,17 @@ +{% extends "admin/index.html" %} +{% load i18n %} + +{% block bodyclass %}{{ block.super }} app-{{ app_label }}{% endblock %} + +{% if not is_popup %} +{% block breadcrumbs %} + +{% endblock %} +{% endif %} + +{% block sidebar %}{% endblock %} diff --git a/templates/admin/base.html b/templates/admin/base.html new file mode 100644 index 0000000..4166ecd --- /dev/null +++ b/templates/admin/base.html @@ -0,0 +1,91 @@ +{% load i18n admin_static %} +{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} + + +{% block title %}{% endblock %} + +{% block extrastyle %}{% endblock %} + +{% if LANGUAGE_BIDI %}{% endif %} + + +{% block extrahead %}{% endblock %} +{% block blockbots %}{% endblock %} + +{% load i18n %} + + + + +
+ + {% if not is_popup %} + + + + {% block breadcrumbs %} + + {% endblock %} + {% endif %} + + {% block messages %} + {% if messages %} +
    {% for message in messages %} + {{ message|capfirst }} + {% endfor %}
+ {% endif %} + {% endblock messages %} + + +
+ {% block pretitle %}{% endblock %} + {% block content_title %}{% if title %}

{{ title }}

{% endif %}{% endblock %} + {% block content %} + {% block object-tools %}{% endblock %} + {{ content }} + {% endblock %} + {% block sidebar %}{% endblock %} +
+
+ + + {% block footer %}{% endblock %} +
+ + + + diff --git a/templates/admin/change_form.html b/templates/admin/change_form.html new file mode 100644 index 0000000..93045f1 --- /dev/null +++ b/templates/admin/change_form.html @@ -0,0 +1,148 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% endblock %} diff --git a/templates/admin/index.html b/templates/admin/index.html new file mode 100644 index 0000000..bd1212c --- /dev/null +++ b/templates/admin/index.html @@ -0,0 +1,110 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_static %} + +{% block extrastyle %}{{ block.super }} + +{% endblock %} + +{% block coltype %}colMS{% endblock %} + +{% block bodyclass %}{{ block.super }} dashboard{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
+{% if maxi_app_list %} + {% for app in maxi_app_list %} + +
+ + + {% for model in app.models %} + + {% if model.admin_url %} + + {% else %} + + {% endif %} + + {% if model.add_url %} + + {% else %} + + {% endif %} + + {% if model.admin_url %} + + {% else %} + + {% endif %} + + {% endfor %} + +
+ {{ app.name }} +
{{ model.name }}{{ model.name }}{% trans 'Add' %} {% trans 'Change' %} 
+
+ + {% endfor %} +{% else %} +

{% trans "You don't have permission to edit anything." %}

+{% endif %} +
+{% endblock %} + +{% block sidebar %} + +{% endblock %} diff --git a/templates/admin/invent/inventory/change_form.html b/templates/admin/invent/inventory/change_form.html new file mode 100644 index 0000000..a6e147e --- /dev/null +++ b/templates/admin/invent/inventory/change_form.html @@ -0,0 +1,167 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% if detail %} +

{% trans "InOut History" %}

+
+ + + + + + + + + + + + + + {% for item in detail %} + + + + + + + + + + {% endfor %} + + +
{% trans 'execute time' %}{% trans 'plus or minus prop' %}{% trans 'price' %}{% trans 'count' %}{% trans 'measure' %}{% trans 'status' %}{% trans 'source' %}
{{ item.event_time|date:"DATETIME_FORMAT" }}{{ item.prop }}{{ item.price }}{{ item.cnt }}{{ item.measure }}{% if item.status %} {% trans 'EXECUTED'%} {% endif %}{{ item.source }}
+
+{% endif %} +{% endblock %} diff --git a/templates/admin/invent/stockin/change_form.html b/templates/admin/invent/stockin/change_form.html new file mode 100644 index 0000000..453b691 --- /dev/null +++ b/templates/admin/invent/stockin/change_form.html @@ -0,0 +1,136 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% endblock %} diff --git a/templates/admin/invent/stockin/in_confirmation.html b/templates/admin/invent/stockin/in_confirmation.html new file mode 100644 index 0000000..07ff43c --- /dev/null +++ b/templates/admin/invent/stockin/in_confirmation.html @@ -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 %} + +{% endblock %} + +{% block content %} +

{% trans 'Are your sure to execute the operations?' %}

+
{% csrf_token %} +
+ + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + + {% trans "No, take me back" %} +
+
+{% endblock %} diff --git a/templates/admin/invent/stockout/change_form.html b/templates/admin/invent/stockout/change_form.html new file mode 100644 index 0000000..3e8227e --- /dev/null +++ b/templates/admin/invent/stockout/change_form.html @@ -0,0 +1,137 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% endblock %} diff --git a/templates/admin/invent/stockout/out_confirmation.html b/templates/admin/invent/stockout/out_confirmation.html new file mode 100644 index 0000000..590a703 --- /dev/null +++ b/templates/admin/invent/stockout/out_confirmation.html @@ -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 %} + +{% endblock %} + +{% block content %} +

{% trans 'Are your sure to execute the check out operations?' %}

+
{% csrf_token %} +
+ + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + + {% trans "No, take me back" %} +
+
+{% endblock %} diff --git a/templates/admin/object_history.html b/templates/admin/object_history.html new file mode 100644 index 0000000..42ca717 --- /dev/null +++ b/templates/admin/object_history.html @@ -0,0 +1,82 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls %} +{% block extrastyle %} + +{% endblock %} +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
+
+ +{% if action_list %} + + + + + + + + + + {% for action in action_list %} + + + + + + {% endfor %} + +
{% trans 'Date/time' %}{% trans 'User' %}{% trans 'Action' %}
{{ action.action_time|date:"DATETIME_FORMAT" }}{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %}{{ action.change_message }}
+{% else %} +

{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}

+{% endif %} +
+{% if history_list %} +

{% trans "Workflow History" %}

+
+ + + + + + + + + + + + {% for history in history_list %} + + + + + + + + {% endfor %} + {% if todo_list %} + {% for todo in todo_list %} + + + + + + + + {% endfor %} + {% endif %} + +
{% trans 'Date/time' %}{% trans 'User' %}{% trans 'node' %}{% trans 'Action' %}{% trans 'Workflow Memo' %}
{{ history.pro_time|date:"DATETIME_FORMAT" }}{{ history.user.get_username }}{% if history.user.get_full_name %} ({{ history.user.get_full_name }}){% endif %}{{ history.get_node_desc }}{{ history.get_action_desc }}{{ history.get_memo_desc }}
{% if todo.is_read %}{{ todo.read_time|date:"DATETIME_FORMAT" }}{% endif %}{{ todo.user.get_username }}{% if todo.user.get_full_name %} ({{ todo.user.get_full_name }}){% endif %}{{ todo.node.name }}{% if todo.is_read %} {% trans 'already read' %} {% else %} {% trans 'unread' %} {% endif %}
+
+{% endif %} +
+{% endblock %} diff --git a/templates/admin/selfhelp/workorder/change_form.html b/templates/admin/selfhelp/workorder/change_form.html new file mode 100644 index 0000000..02f9efc --- /dev/null +++ b/templates/admin/selfhelp/workorder/change_form.html @@ -0,0 +1,173 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% endblock %} diff --git a/templates/admin/submit_line.html b/templates/admin/submit_line.html new file mode 100644 index 0000000..9ae7940 --- /dev/null +++ b/templates/admin/submit_line.html @@ -0,0 +1,18 @@ +{% load i18n admin_urls %} +
+ +{% if show_save %}{% endif %} +{% trans "submit" %} + {% for button in extra_buttons %} +{{button.title}} + {% endfor %} + {{extra_buttons}} +{% if show_delete_link %} + {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %} + +{% endif %} +{% if show_save_as_new %}{% endif %} +{% if show_save_and_add_another %}{% endif %} +{% if show_save_and_continue %}{% endif %} +
diff --git a/templates/admin/workflow/node/change_form.html b/templates/admin/workflow/node/change_form.html new file mode 100644 index 0000000..4358e4d --- /dev/null +++ b/templates/admin/workflow/node/change_form.html @@ -0,0 +1,164 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls admin_static admin_modify %} + +{% block extrahead %}{{ block.super }} + +{{ media }} +{% endblock %} + +{% block extrastyle %}{{ block.super }}{% 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 %} + +{% endblock %} +{% endif %} + +{% block content %}
+{% block object-tools %} +{% if change %}{% if not is_popup %} + +{% endif %}{% endif %} +{% endblock %} +
{% csrf_token %}{% block form_top %}{% endblock %} +
+{% if is_popup %}{% endif %} +{% if to_field %}{% endif %} +{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} +{% if show_workflow_line%} +
+

{% trans "workflow approve" %}

+
+ {% if can_restart %} + {% trans "restart workflow" %} +

{% trans "your apply has been denied,you can restart a new apply" %}

+ {% else %} + + + + {% trans "submit" %} + {% endif %} +
+
+{% endif %} +{% if errors %} +

+ {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} +

+ {{ 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 %} + +{% endblock %} + +{# JavaScript for prepopulated fields #} +{% prepopulated_fields_js %} + +
+
+{% endblock %} diff --git a/templates/default/workflow/workflow_approve_confirmation.html b/templates/default/workflow/workflow_approve_confirmation.html new file mode 100644 index 0000000..87588ea --- /dev/null +++ b/templates/default/workflow/workflow_approve_confirmation.html @@ -0,0 +1,67 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls %} +{% block extrastyle %}{{ block.super }}{% endblock %} +{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +{% if operation == '4' %} +

{% trans "Are you sure to terminate the request?" %}

+{% elif operation == '3' %} +

{% trans "Are you sure to deny the request?" %}

+{% else %} +

{% blocktrans with escaped_object=object %}Are you sure you want to submit the {{ object_name }} "{{ escaped_object }}"? {% endblocktrans %}

+{% endif%} +

{{ workflow_modal.code }} {{ workflow_modal.name }}

+ +
{% csrf_token %} + {% if is_stop_node %} +

{% trans "current node is stop node,click the submit button to complete it" %}

+ {% else %} + {% for node_user in node_users %} + {% if node_user.node == 'start'%} +

{% trans "back to start node" %}

+ {%else%} +

{% trans "next node" %}:{{ node_user.node.name }}

+ {% endif%} + {% if next_node_description %} +

{% trans "attention" %}:{{next_node_description}}

+ {% endif %} + {% if node_has_users %} +
    + {% for user in node_user.users %} +
  • {{user.last_name}}{{user.first_name}}
  • + {% endfor %} +
+ {% else %} +

{% trans "No user was configured to handle this node"%}

+ {% endif %} + {% endfor%} + {% endif%} + {% if is_stop_node or node_has_users%} + + +
+ + + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + + {% trans "No, take me back" %} +
+ {% else %} + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + {% trans "No, take me back" %} + {% endif %} +
+{% endblock %} diff --git a/templates/default/workflow/workflow_start_confirmation.html b/templates/default/workflow/workflow_start_confirmation.html new file mode 100644 index 0000000..c498ceb --- /dev/null +++ b/templates/default/workflow/workflow_start_confirmation.html @@ -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 %} + +{% endblock %} + +{% block content %} +{% if has_workflow %} +

{% blocktrans with escaped_object=object %}Are you sure you want to submit the {{ object_name }} "{{ escaped_object }}"? {% endblocktrans %}

+

{{ workflow_modal.code }} {{ workflow_modal.name }}

+ +
{% csrf_token %} + {% if next_node %} +

{% trans "next node" %}:{{ next_node.name }}

+ {% if has_next_user %} +
    + {% for user in next_users %} +
  • {{user.last_name}}{{user.first_name}}
  • + {% endfor %} +
+ {% else %} +

{% trans "No user was configured to handle this node"%}

+ {% endif %} + {% endif %} +
+ + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + + {% trans "No, take me back" %} +
+
+{% else %} +

{% trans "you needs to config a workflow model for this content type" %}

+ {% trans "OK" %} +{% endif %} +{% endblock %} diff --git a/upload/data/1001部门岗位员工导入模板test.xls b/upload/data/1001部门岗位员工导入模板test.xls new file mode 100644 index 0000000000000000000000000000000000000000..f4a0f43abaad71e8d8a054336fdc9eba19a4a624 GIT binary patch literal 32768 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 L&g+C9pa=dB+COC0 literal 0 HcmV?d00001 diff --git a/upload/data/1003合作伙伴导入模板_ENnUPsg.xls b/upload/data/1003合作伙伴导入模板_ENnUPsg.xls new file mode 100644 index 0000000000000000000000000000000000000000..4582ff71a2f7763b2a75e154e61e5cd36bad5529 GIT binary patch literal 20480 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 OLC)^HM))Cm;Qs(43uDLt literal 0 HcmV?d00001 diff --git a/upload/data/1004项目导入模板.xls b/upload/data/1004项目导入模板.xls new file mode 100644 index 0000000000000000000000000000000000000000..8fd7e7f2cfa0187acdd97476d9185111a4293bde GIT binary patch literal 18944 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 TkT#~z;WbMd4_QX%i;sw82+E!;D!R4tOk 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 literal 0 HcmV?d00001 diff --git a/upload/data/1004项目导入模板_YfVeRXU.xls b/upload/data/1004项目导入模板_YfVeRXU.xls new file mode 100644 index 0000000000000000000000000000000000000000..8fd7e7f2cfa0187acdd97476d9185111a4293bde GIT binary patch literal 18944 zcmeHP3y@URnf~vc?w&g$FayJgAT!PI7#=g@&;vLM(ul_0kePsh1`8Afx)~w?7DhId z&N5~-DFaDx#sER`Ad#wU-lA(_t-HdOl~kq1jhod~v${)mCChGhNkmg7mfHJ$=k)D9 zeP7eFWs=h3Or6{J{O5n2|NQ4ak9+St^OKs>#~z;WbMd4_QX%i;sw82+E!;D!R4tOk z4a@K3aybRV1-BQ{d&mNBL)S+1TLp3qIgZReuS9l`tB@~39)Wx@@<`-S$fJ?r0#buK z26-%UE%G?zI^;``$0J{gJOOzk@@2@Akn52fkm)zfQ;hrfkm=qRs;-dj`0K$~{(x-5 z?@rl+-Y7rS!DC!Q*dR+fyo#JuSGk@)pMGuPhST4B#%gQ%>Qnrk3|OB=laE09PPtt+ zC_Qf1RKvKA5!<5Qx;m6YO3^PY(3o*qDR;=n@OPVP`v+l#tkQ{)9@&EXZ4pdoKt5w2 z#}9RgKrN|yCSQunb&#-8>5x%9Fg$%aAm43!x$bT)xrpbmb{T^8_k? zF1CCxb_!RKe@9*`I~W^o+?Cmx{6nQBN{8Dl>TnVUz8ZIy90jx*F@;d{Jg#Ha^}7o1 z33a_1H6NE2=~;HVp#vD4qgLCC72apmwNYJ1;cChE70u5SWDX+KOTc&J0K3$d6A5b- zyr3IBL~r=x*Vjrnysbl?VAJK3Cv0oqnw86_S91{_sCR6L`j=pfJl{Zi+NEX)yVMR* zzi^29MUnNEq;M51|J>d% z{$L(pRg6O!ldcC`q(uvSA95Xv}Bh_MrJ{fwXV>rS&}r`OSswQpxRQ}M#V|f z@w!-et&cU!OlcBX*D@!eye&57u}EC>jn99r3-&nmg5%NHI2_bp~Ba2YzsA<`@}pviCb(BJ#f!>sPb=e||JAE>E0G~&<*i5*n-;XYQw zv)Lybo@|iV_Z6J`S_Sv$&pmGtoDoUEpOy8vMNrgsh$HSQxKGcSfpCAn|DDpu5C3!s z{P7U@aQ)}66(8>XmHvhP`lf>OEI`3wPi;4CPo5LFaBXMLI6YcZQ#Yax_CKQd@Vr39 z89EqKKF-k2LGbYb@VlH^xyz*|54lEun_KnkUT22%mcUtO;Vh$8?b|qKsEGxWv>%tX z<>GSIC>NJI#&U7FV=EVz5x87jj{b6SD~EwgW0%X9k)vE(Mu&278DYxBrFWN$OV2JB zm!qRxTt=pHaZ|&|x+G4+FO`0=LC8HhCIo7se(>i90q&Vb@~yItx7nQ$q=y z`~c_hk^I8nPd{x4`dm7ie)6Jo+e@(k4hBs$SIR&0fEKgYY zdHwbH@#6)0x4+*#`+CP(8#K^kjqSl{ZK1#Yx?c?p-51o|TqL+-Etebg>3-tG37>D| zVI{tyU>@I4Fvw!^FGR3yH*{y8ySD6gmV3t8EZ|lYf~cuGZOrzVF{va@=Es>o_RIxU zF)*W0(wAPIetIsAi}a>Wv}c86vZhXcdOlW)q95#xrsw0QB0UNo{k?J8I~L{*L9ZX4 zg~wiQF^cko+Rvq1I6arhQS^hI(e!-uR-~sW*MGGAQ|;08^M|14Xh8~{XStLw$`5LP zG(DI6QS^hI(e!-mSfoe6*ZyewD~6!g4^6|{&#h!peo*_l#15zDqtqz+!Om!U?3oRE zit_e2n5x`6ASXT5wEhvE*{ zlX3JoN~{!4@u$HuEy!1`tJwdk%tzK7J-qW1Nj#J5ca|c9M?P7x`rIgqqM#Wqyv8T4X9fWMiaAZrAc64$EU3ATo-g(3i2n&L0fE;uCpEw8$Wjof0Y1 z^w`19Up)Q;pUCmiB7;1(DN>~Av4fq@zw(4n&$GLbS*r zkG(unr0KDPosYeI)+cgew8$WjZI2XbdhB55ThBe}6L}d$&L5V?CLuD4qUf=y_Rl}^ zycWp-i^Lc^DOzNZ$4-qDX?kp`{l!C{_lc~J78&HRGa^Nr9-C_a`+q*-6WI_gGRR|_ zBSo4Xn`%FC>_}okiXcSSn=%b1P$0#c-D_eu(JE`;eKa!DRRZ=oGq-Or>YeI zcCZZ}?9EN%DdT`WQl?^$tZ4Nrqr*dAor@`Y)_QqV!XlN}jV`rd$V8Q1PJWC*%ZjLP*)(&O6d`^=n;Rib;0_6XGy8lic2AtH9R^|Hp@#* z7`A|Xmg2Y;b=nG>h+$yYd zq2#fBhwkimK3Ym(*MTi-xZCC`gvR8VpxaKK(NST-c}AoaE|#2Ha6X z&uqSN<+V2~?Cy7Vcoet;cZ(9GUO!MY`r`e;%JcugRyN=?vlS8hJj-B1Nbd_e{acp}89NVom$)O?~Wi&=L zG?**tF@Z zKGq$6)|^wltXq7n&3RPhL*M$LkM)&))|@-NtmpVxoAaf}8waoVu&$D;7*Om3Eg$Z8 z*nM;~oh<7z1Qgb|o}io-4{_Xpaug4F7&sS@#lYv@yulxn#(@QE%wS-~Bt5M4c;J08 zCh3wH4EP$RiAm85wdhQM=vpN@QzANtM@X*re8l9&q2Y(aD!H1X&u;zk{r%3ZrG~RF zf@s$8+}Dl7d?MhA<7s}erMl#{RF~YA>e6SO)$&=RYYw1?YVgNbkT=LyylA-+FQo5L zcU|hW%Ps1)@hkC$&KB8?my~-9j84EdnKV))mLI#TUNM7;@rrz{5ljW6QQZTegK%Zn$I9=8TUrCUNS*X4dU}W2KkY zs2;iM*LxzW`|k8tW5r13Z*6$(PzdEchY#KPkN1D^u(!HOH)#3NmTOz)w6)Fg)+aRQ zdv7><;F-@&yNBv~QE*D z*^5Wq*8}ifxXaHiyL?yMt8G5+xsZN87N~Ce{qViO^}T5U#t1&ZXJ*oIN#7T*HtMVJ zSHvZqH!%uh$SYplNw_=-3rehaV-)L6yiF)mo*P$K?=8DJm~_MoO9Mv5Vys$7$9$6k z=dBCpulKt?&T-yEJZ}nuxj1f}m$%yA)^|dasZX{sO16B+13-K}Z z_4rbAkv&EpQ*W9qMy;FnVI{qrv=_YWQeQ70d%yH=ohE&{qp(WE$goS z=KYS$ZhGX!Ho(4uOyAJsNss+MMVX$s8hH$IH!?RAeaIXE`;o^Y<57$9wXeh3_%ar0 z_)$520?UjgU0XKp+`emjwkP?4k8jLu#i&J^dEZF>9|7L?J#?@7p91vX|4)i)zx~|P z&mC=@SUqqE?Qj0wci8@?kU1vU{^iJgYoG1r%XwRo84a*eQeVv7gilM*tFckIS*!{`5r=FCH0U%=R0Ga){XPyURf=6KA;c%Vb+N+Iv~Ph3H;^r5W4c z{ofr^V1a@^CYNQiTQ+9&FifV}+S-$Ox8iiMWJ@;Np$=R$+MHDDpWnW#b!B%Z)6?1^ SuU~oM&&oFE1;js~1^y4fQrIE|Y4f!1ha8*Ee4*fnzes4>+RTS-mQnj@vPdc^7PckjHJH}B26 zGutLP2M>48eRJ>s{=e@3{_p>O%$q&+a{1{8pBVj)c+y-cl24PR5_Z8Yl$lj36RARh z^-q(@qy~zhcrjf-7B~-GCt>i4kVDAD$Q<($`A6MIMh#|6!i!Dqlb*yr5NWm96;OiLtm! zw%~KS+>TKwJPn7(I0mpm7LD*Ja#B6zYJNO=)0@YlPn@#4mc3Fw5uXzPi_zhbmP7h> z*(B?f9-B0<56>ZDTl8B;heAlHVQj9(ES6<*i`&9=5$Kyf&5-Z(y-@kI*K<@FsWgIF94?lJ$GueYBSiBs z8s8CH9uGZ_r^vq`ua<3$4L9zHZ;$@A(tM>uyG0#NLf0!$vg9bBWr!(+V&w50s-BN2 zyyw*O3bbsrYOTAkf2Xn;7+j-P*fE87uXS`L3e*se(*LgnA435!p}c*m5jv z-2gAxh!LVU{5IO3g5czy|DXKQK>aIV8B3bwIhsy>|CnvyNxx=Z1;Y7+GpfxpJQydq{XP8$lO5s z3gx#c{aoX!;VFN1!D;Uh)^qk36Tsu=m7!^f>O;kw$;Vj>MBFG zz~;@tifR3|n9Pu5tLMfcrXDupXeC?VZ<+(2j-oSUntaZsXnjMLuDY61x1}Yc@Mz2) z?EO|x)ZLphdv#5!yn0GyXdK)FyTDBAs@C}WHCZT8I080_DHO_a@j#VqCV@%RgOklk zA)Zz{QIY>ja);`qlTpICw^i_S7vaASJJ5=jItirgX?yI<1&t~6K(_tU@b3h`9}a*& z8UQ~M0Dmk1{_Ozx9|yqq2Ec>#3F7~x;!^^XDEp`F@FxLqt&bmH>*I%iGl0(%0r003 zJdBf`(&vBFXyKv9k!QeMe!_F1g1;t9QN(dh7+k{=9WI)0^$j8|w@`D(U#G{lBrv zY=7Q%o9WH==S{hp-fVwtckQ zgxd_uA6zB|5=2r9ws~+T<)KfunCU0yq4zqM*ErRn<zuVSit1(z3X9I4a?!V;nj% zVaXrre@LOF4RZ=!mr%)OFe@#4fI7h7m|`3w$8FYuV8RP;omUTf@h}x7HUqP z{J3=n+wz0qy3#Hm@Amig?AfzvTTy@F?b)*@iF*{KEA@B5s&LcNQtF2B#s#UL z8%6-q?ub_(T*svJ;TSVH{dC6e`0?XDeOg*teEOtdS^6lLM;`^#qM(o0?;6me?e6r^ z(Z`QFJqs7-wzS{)eY6p{I@o#b?$|TgWu^P+m(`S(MLU`OVTJ+MyNQ{Z)+?9&2{X_0 zOY_p37lF(2(wi57=DhUgMd0$h^yWoiR$lt-MZjzS*=c(E#nE`ihaCS;{_?2HFTC?- z4yZEonZE7#t3#h_KBwkN)_hLE`Z#~Q`ds1BXO~Z(WbYrP`}3QRFZ?D{+s8X^9Q!1b zy*_#3Zc5b;z^YiuQdazI@fu`?uc}#Z5$aqkmtNj!1p^uPN=R+vT3%ptPg zC{iy&%CHfP<@^8X6FJN*^3oh48;v6M%B4h>#uMj%{-#glaEhGKCyyNmktT|?VMD!( zp6PwpCvt>YWG;`LU=->0*xp4yd-fTh$dP7|xjeSoDAMh*y^G#>_c@=)QD%|3Ja(E< zq}yYA7xkX}sZZo+v&dW?`#GaXx5xG_diw46d?GI~i_GP*O-7M!kL_Lb$?H$~M2?}z zOZ()pQHV5AWIVR9>FZCvp+z#lA~D8}HH*yUu@j9V-5%T6^yZfcP6G1(8Deh3QB9&~s z|NidCv~1*}!AV=#LQhpY0PJeUE!>SaKXEhCV-J*xIKwDfy~}9!(3d4cik_`r9wo3y z2~I#u?)*!rPG*xb%;?)*X60#S+K=4|X=cfmZ=L+76tl@0X7pMwvmt3_+C%-!^qjPn zX4M&H^v9{5ZVpW|)8|7svmU!dYOs~E-e1!lX~-tDE=gMQ{u(C^6mxHh>lBi+%7~IsN2)4izSxcQ#t#Of8btR+?4ou?OSj7)+Uy8_#UGaoLrh zpR=($vdyEw2#CtGyVc+|jj|hh!L`9rgU8CSvK!UVHAf9ybJWl^s?k6-{`IRb-dDZ$ zEAiS5-H}?48Z#j()9yHm(@##*>6{FSz1QBL8F(gx-5-;|X?2rBML5b}oI0QZozOAF zERO~wp+TnI2^-XaV?Z}ynRhzcO`5uj-~g4`T#AdJ#+Az!FA29EIH-p|Bs03gz?|s8 z41=eG>2{Z4G86BLS^l%s+-wG+vB`+<#N|wvOoYSvDK&mQ_Au-Ve5@JsysXFjSi9G7 zk&{aoXSoJhU*>1c2sA?1eBw=kYeDRLl!-M`0?lcF=-fBu*Dq=+%ZW{Yds%W&cq~La|Z(p zFY354Df$X6I-Wyxg%Tal63y!+NBfqRUFkT~_i$K>cT&;o_cp(HUw7oDY{S|8Aet@w zQHc|Yd6VRXJ>CLkda7$qPj$`dsjhu3vO>P*8k+qWp>q83743Dh884bH!wdVjtI}fi z+G(eHt^RVnq0}k6@Dle<7sevMHsICnorr^%%36zeLigYX=0)ysBxKdxa@o3fmTX;n zI5JWWyQJ#XnE_Gc8+dvC8?H7|?n6}l0{%wg?bIXq%7c7UsqMDSi7oXDufD3abxG@( zvCmr(c^+)W{?d|9Ct$)Arg;myV-sXseDDxJ)|G%aE=D4@HpKeZcZr`!9Ef+$mM%dgQ z&|a+D<2Sc=`ZQ0;-qyZj$E{npulLGMHFs=`Z`sh%-sx=)%K-gy;`GL*FWm~w@s=|8 z1TKSO)5Xq}tqW*a>}x2~>N+xG?dv+~JGS2JrBC8_2odSQw>Nz2H2Z8->MI_PSdf5ws{fE{tc=ydx4+vkFj0k?npmmFnTzvSp|SFl+nZ29Fd?$XO} z|2&Yh7JAuuH+!%um*dG_bVcNohdy{^@w%lgZ3;eB!MQ0Exl2L1fa9b|+||lh>rS*h zAEK;b$X{02cdO@QU?)`iSxdF6T$ASVUdt3$d9geV_E%y`Z&AOziOOP3-$pFq4HA_d znAY1dapNdO0cV-NS|Ze)tWbEsTk?~VqJO@#hyn9({~3|>=y8dhM^K^_ndjji>ervh znbvZocqRM<+lTqrE?68+y@9p>Cj1VNn4Lu0NGrn7PQfoTL=XmK?Gll9xB2T{JmQ|q zf$zW_eoo!tyTV>!^L>wt={IA6GJaowFi3 zFs8iX#nXwyldxQg?M{qhyBlvk>Xhfi6}Efpjt*`*;svE1S3?XhE0T`+3obZ|4xFFf z-%_e8jvV+NP*z`p+Pu7-{y6xQ&*XgSTIT7t4RQ8(at2eE{tX7lSvPMAl9!jzh2Z9q z%VyLiUs5k5q>vojxc$XT|6Tz+Kg(RWZHl`nv9x#q`gm1Sa6=NT#3OI-m#)=n4A8^CYtDPtAtN`Wymj1@yF*0808Z=Y) zCAwCG8nw{15Nb39Ym_z**{NBmF{RJ(M#MiYDYU~Yb)GwyA&@~Hfd_P;) z$c39OT_cx)=^8GXaI6-21Jr}SyaqpAzgp(nL*!{?wiw!+v==+@y;);u<2#PNr0{iDD5arwTxt17vv1$|KQ*}ro(d= z!BOW-=B#EL=MFzFrq7NAKE*0ktS-MWxUNLMIDO9pXFpo9vFwriA~LP|$v1I@A%BWY z-(Y(TnE{VMh`zD{c?j}GWco@MG9&Ch=Si6OJjGIeTOx^O|;HH#Krf88<#qrUS1=h!oTkWV!z9DeRkwvR&| ziQL!4i*(dOTao2YlSK$noRQxDJu?AVY1>7YBodt+aqULY#)gKbXsY{EXMSfQ(X1}7 zG}`pW`dc^cs9&}*9^YBtEaxsi@g>Uq>?I5P9{zWeZL$QH=wIw}2l-!E+|jTQ2AmJO U3PCIor?2u0WLq%Wg)IMn0q1Tqs{jB1 literal 0 HcmV?d00001 diff --git a/upload/data/1005用户信息导入模板_LRE2NKU.xls b/upload/data/1005用户信息导入模板_LRE2NKU.xls new file mode 100644 index 0000000000000000000000000000000000000000..2ac80431400b460c9ee603766959b0041b56d33a GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/upload/data/1005用户信息导入模板_stkXmtR.xls b/upload/data/1005用户信息导入模板_stkXmtR.xls new file mode 100644 index 0000000000000000000000000000000000000000..3d2e96fa03522b0221477d70c73cb0f205672b63 GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/upload/data/合作伙伴.xls b/upload/data/合作伙伴.xls new file mode 100644 index 0000000000000000000000000000000000000000..67da091521ee5f9fb6816a5f8e75e6167e47b961 GIT binary patch literal 20480 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 M-Fc1h1N6ZE0mQszyZ`_I literal 0 HcmV?d00001 diff --git a/upload/doc/1001部门岗位员工导入模板.xls b/upload/doc/1001部门岗位员工导入模板.xls new file mode 100644 index 0000000000000000000000000000000000000000..770b396ba19affb9e35ad2ae2ab127deb8623c6f GIT binary patch literal 32256 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 literal 0 HcmV?d00001 diff --git a/upload/doc/1004项目导入模板.xls b/upload/doc/1004项目导入模板.xls new file mode 100644 index 0000000000000000000000000000000000000000..20032e0f77a5699851fdefcd91b11b6458d18626 GIT binary patch literal 18944 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 literal 0 HcmV?d00001 diff --git a/upload/doc/2001报价单明细样例.xls b/upload/doc/2001报价单明细样例.xls new file mode 100644 index 0000000000000000000000000000000000000000..1d2bf17b761ee5a0b6386030dc3d48ac8b6b332d GIT binary patch literal 23040 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 X)^PkZCyVEO*HiiDEl^|dd6xhGcp>5K literal 0 HcmV?d00001 diff --git a/upload/doc/2002需求计划明细样例.xls b/upload/doc/2002需求计划明细样例.xls new file mode 100644 index 0000000000000000000000000000000000000000..a8bdd29a301adb18dc163594ce9eb34768925cb3 GIT binary patch literal 23040 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 literal 0 HcmV?d00001 diff --git a/upload/doc/2003采购单明细样例.xls b/upload/doc/2003采购单明细样例.xls new file mode 100644 index 0000000000000000000000000000000000000000..071e9f85d6567c0d4fc2356d899fee38a543d466 GIT binary patch literal 23040 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 literal 0 HcmV?d00001 diff --git a/upload/hr profile/mis.sql b/upload/hr profile/mis.sql new file mode 100644 index 0000000..0f93e3d --- /dev/null +++ b/upload/hr profile/mis.sql @@ -0,0 +1,1604 @@ +/* +SQLyog 企业版 - MySQL GUI v8.14 +MySQL - 5.1.55-community : Database - mis +********************************************************************* +*/ + +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +CREATE DATABASE /*!32312 IF NOT EXISTS*/`mis` /*!40100 DEFAULT CHARACTER SET utf8 */; + +USE `mis`; + +/*Table structure for table `auth_group` */ + +DROP TABLE IF EXISTS `auth_group`; + +CREATE TABLE `auth_group` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(80) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; + +/*Data for the table `auth_group` */ + +insert into `auth_group`(`id`,`name`) values (2,'人事'),(1,'职员'); + +/*Table structure for table `auth_group_permissions` */ + +DROP TABLE IF EXISTS `auth_group_permissions`; + +CREATE TABLE `auth_group_permissions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `group_id` int(11) NOT NULL, + `permission_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `group_id` (`group_id`,`permission_id`), + KEY `auth_group_permissi_permission_id_23962d04_fk_auth_permission_id` (`permission_id`), + CONSTRAINT `auth_group_permissions_group_id_58c48ba9_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`), + CONSTRAINT `auth_group_permissi_permission_id_23962d04_fk_auth_permission_id` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=127 DEFAULT CHARSET=utf8; + +/*Data for the table `auth_group_permissions` */ + +insert into `auth_group_permissions`(`id`,`group_id`,`permission_id`) values (96,1,11),(97,1,37),(98,1,38),(99,1,39),(100,1,43),(101,1,44),(102,1,45),(103,1,55),(104,1,56),(105,1,57),(106,1,89),(107,1,91),(108,1,92),(109,1,93),(110,1,94),(111,1,95),(112,1,96),(113,1,97),(114,1,98),(115,1,99),(116,1,113),(117,1,114),(118,1,119),(119,1,120),(120,1,121),(121,1,122),(122,1,123),(123,1,124),(124,1,125),(125,1,126),(126,1,127),(87,1,128),(88,1,129),(89,1,130),(90,1,131),(91,1,132),(92,1,133),(93,1,134),(94,1,135),(95,1,136),(45,2,115); + +/*Table structure for table `auth_permission` */ + +DROP TABLE IF EXISTS `auth_permission`; + +CREATE TABLE `auth_permission` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `content_type_id` int(11) NOT NULL, + `codename` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `content_type_id` (`content_type_id`,`codename`), + CONSTRAINT `auth_permissi_content_type_id_51277a81_fk_django_content_type_id` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=153 DEFAULT CHARSET=utf8; + +/*Data for the table `auth_permission` */ + +insert into `auth_permission`(`id`,`name`,`content_type_id`,`codename`) values (1,'Can add log entry',1,'add_logentry'),(2,'Can change log entry',1,'change_logentry'),(3,'Can delete log entry',1,'delete_logentry'),(4,'Can add permission',2,'add_permission'),(5,'Can change permission',2,'change_permission'),(6,'Can delete permission',2,'delete_permission'),(7,'Can add group',3,'add_group'),(8,'Can change group',3,'change_group'),(9,'Can delete group',3,'delete_group'),(10,'Can add user',4,'add_user'),(11,'Can change user',4,'change_user'),(12,'Can delete user',4,'delete_user'),(13,'Can add content type',5,'add_contenttype'),(14,'Can change content type',5,'change_contenttype'),(15,'Can delete content type',5,'delete_contenttype'),(16,'Can add session',6,'add_session'),(17,'Can change session',6,'change_session'),(18,'Can delete session',6,'delete_session'),(19,'Can add Site',7,'add_site'),(20,'Can change Site',7,'change_site'),(21,'Can delete Site',7,'delete_site'),(22,'Can add module',8,'add_module'),(23,'Can change module',8,'change_module'),(24,'Can delete module',8,'delete_module'),(25,'Can add menu',9,'add_menu'),(26,'Can change menu',9,'change_menu'),(27,'Can delete menu',9,'delete_menu'),(28,'Can add role',10,'add_role'),(29,'Can change role',10,'change_role'),(30,'Can delete role',10,'delete_role'),(31,'Can add value list',11,'add_valuelist'),(32,'Can change value list',11,'change_valuelist'),(33,'Can delete value list',11,'delete_valuelist'),(34,'Can add list item',12,'add_valuelistitem'),(35,'Can change list item',12,'change_valuelistitem'),(36,'Can delete list item',12,'delete_valuelistitem'),(37,'Can add address',13,'add_address'),(38,'Can change address',13,'change_address'),(39,'Can delete address',13,'delete_address'),(40,'Can add partner',14,'add_partner'),(41,'Can change partner',14,'change_partner'),(42,'Can delete partner',14,'delete_partner'),(43,'Can add bank account',15,'add_bankaccount'),(44,'Can change bank account',15,'change_bankaccount'),(45,'Can delete bank account',15,'delete_bankaccount'),(46,'Can add organization',16,'add_organization'),(47,'Can change organization',16,'change_organization'),(48,'Can delete organization',16,'delete_organization'),(49,'Can add org unit',17,'add_orgunit'),(50,'Can change org unit',17,'change_orgunit'),(51,'Can delete org unit',17,'delete_orgunit'),(52,'Can add position',18,'add_position'),(53,'Can change position',18,'change_position'),(54,'Can delete position',18,'delete_position'),(55,'Can add project',19,'add_project'),(56,'Can change project',19,'change_project'),(57,'Can delete project',19,'delete_project'),(58,'Can add warehouse',20,'add_warehouse'),(59,'Can change warehouse',20,'change_warehouse'),(60,'Can delete warehouse',20,'delete_warehouse'),(61,'Can add measure',21,'add_measure'),(62,'Can change measure',21,'change_measure'),(63,'Can delete measure',21,'delete_measure'),(64,'Can add trade',22,'add_trade'),(65,'Can change trade',22,'change_trade'),(66,'Can delete trade',22,'delete_trade'),(67,'Can add brand',23,'add_brand'),(68,'Can change brand',23,'change_brand'),(69,'Can delete brand',23,'delete_brand'),(70,'Can add category',24,'add_category'),(71,'Can change category',24,'change_category'),(72,'Can delete category',24,'delete_category'),(73,'Can add technical parameter',25,'add_technicalparametername'),(74,'Can change technical parameter',25,'change_technicalparametername'),(75,'Can delete technical parameter',25,'delete_technicalparametername'),(76,'Can add technical value',26,'add_technicalparametervalue'),(77,'Can change technical value',26,'change_technicalparametervalue'),(78,'Can delete technical value',26,'delete_technicalparametervalue'),(79,'Can add material',27,'add_material'),(80,'Can change material',27,'change_material'),(81,'Can delete material',27,'delete_material'),(82,'Can add material parameter',28,'add_materialparam'),(83,'Can change material parameter',28,'change_materialparam'),(84,'Can delete material parameter',28,'delete_materialparam'),(85,'Can add expenses account',29,'add_expenseaccount'),(86,'Can change expenses account',29,'change_expenseaccount'),(87,'Can delete expenses account',29,'delete_expenseaccount'),(88,'Can add employee',30,'add_employee'),(89,'Can change employee',30,'change_employee'),(90,'Can delete employee',30,'delete_employee'),(91,'Can add family member',31,'add_family'),(92,'Can change family member',31,'change_family'),(93,'Can delete family member',31,'delete_family'),(94,'Can add education experience',32,'add_education'),(95,'Can change education experience',32,'change_education'),(96,'Can delete education experience',32,'delete_education'),(97,'Can add work experience',33,'add_workexperience'),(98,'Can change work experience',33,'change_workexperience'),(99,'Can delete work experience',33,'delete_workexperience'),(100,'Can add workflow model',34,'add_modal'),(101,'Can change workflow model',34,'change_modal'),(102,'Can delete workflow model',34,'delete_modal'),(103,'Can add workflow node',35,'add_node'),(104,'Can change workflow node',35,'change_node'),(105,'Can delete workflow node',35,'delete_node'),(106,'Can add workflow instance',36,'add_instance'),(107,'Can change workflow instance',36,'change_instance'),(108,'Can delete workflow instance',36,'delete_instance'),(109,'Can add workflow history',37,'add_history'),(110,'Can change workflow history',37,'change_history'),(111,'Can delete workflow history',37,'delete_history'),(112,'Can add workflow todo',38,'add_todolist'),(113,'Can change workflow todo',38,'change_todolist'),(114,'Can delete workflow todo',38,'delete_todolist'),(115,'view all employee',30,'view_all_employee'),(116,'Can add extra param',39,'add_extraparam'),(117,'Can change extra param',39,'change_extraparam'),(118,'Can delete extra param',39,'delete_extraparam'),(119,'Can add work order',40,'add_workorder'),(120,'Can change work order',40,'change_workorder'),(121,'Can delete work order',40,'delete_workorder'),(122,'Can add wo extra value',41,'add_woextravalue'),(123,'Can change wo extra value',41,'change_woextravalue'),(124,'Can delete wo extra value',41,'delete_woextravalue'),(125,'Can add wo item',42,'add_woitem'),(126,'Can change wo item',42,'change_woitem'),(127,'Can delete wo item',42,'delete_woitem'),(128,'Can add loan',43,'add_loan'),(129,'Can change loan',43,'change_loan'),(130,'Can delete loan',43,'delete_loan'),(131,'Can add reimbursement',44,'add_reimbursement'),(132,'Can change reimbursement',44,'change_reimbursement'),(133,'Can delete reimbursement',44,'delete_reimbursement'),(134,'Can add fee item ',45,'add_reimbursementitem'),(135,'Can change fee item ',45,'change_reimbursementitem'),(136,'Can delete fee item ',45,'delete_reimbursementitem'),(137,'Can add salary item',46,'add_salaryitem'),(138,'Can change salary item',46,'change_salaryitem'),(139,'Can delete salary item',46,'delete_salaryitem'),(140,'Can add employee entry',47,'add_entry'),(141,'Can change employee entry',47,'change_entry'),(142,'Can delete employee entry',47,'delete_entry'),(143,'Can add salary item',48,'add_employeesalaryitem'),(144,'Can change salary item',48,'change_employeesalaryitem'),(145,'Can delete salary item',48,'delete_employeesalaryitem'),(146,'Can add employee transfer',49,'add_transfer'),(147,'Can change employee transfer',49,'change_transfer'),(148,'Can delete employee transfer',49,'delete_transfer'),(149,'Can add employee departure',50,'add_departure'),(150,'Can change employee departure',50,'change_departure'),(151,'Can delete employee departure',50,'delete_departure'),(152,'modify salary item',47,'modify_salary_item'); + +/*Table structure for table `auth_user` */ + +DROP TABLE IF EXISTS `auth_user`; + +CREATE TABLE `auth_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `password` varchar(128) NOT NULL, + `last_login` datetime DEFAULT NULL, + `is_superuser` tinyint(1) NOT NULL, + `username` varchar(30) NOT NULL, + `first_name` varchar(30) NOT NULL, + `last_name` varchar(30) NOT NULL, + `email` varchar(254) DEFAULT NULL, + `is_staff` tinyint(1) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `date_joined` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `username` (`username`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `auth_user` */ + +insert into `auth_user`(`id`,`password`,`last_login`,`is_superuser`,`username`,`first_name`,`last_name`,`email`,`is_staff`,`is_active`,`date_joined`) values (1,'pbkdf2_sha256$20000$Cr1ZLAvD7UNR$rtQpXM9iVLITGsqlNuckLmxew/te4/wFkuAt5A8hr8c=','2015-05-24 08:33:50',1,'zhugl','国良','朱','zhuinfo@126.com',1,1,'2015-05-01 07:28:00'),(2,'pbkdf2_sha256$20000$yHALLf8oZTHr$vAIEBzQtknyeyBhEnFKXRyqoBplytPGLjQPkWZyN42c=','2015-05-24 08:04:02',0,'luy','阳','陆','luy@126.com',1,1,'2015-05-10 16:36:00'),(3,'pbkdf2_sha256$20000$cC4dja4Kouje$m4brdyu6sT2FtmWuUf8oJtfvUki5lCf0ol/3h4uVqRs=','2015-05-24 08:01:56',0,'zhangliangjun','良君','张','zhanglj@qiteng.com',1,1,'2015-05-24 08:00:00'); + +/*Table structure for table `auth_user_groups` */ + +DROP TABLE IF EXISTS `auth_user_groups`; + +CREATE TABLE `auth_user_groups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL, + `group_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user_id` (`user_id`,`group_id`), + KEY `auth_user_groups_group_id_30a071c9_fk_auth_group_id` (`group_id`), + CONSTRAINT `auth_user_groups_group_id_30a071c9_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`), + CONSTRAINT `auth_user_groups_user_id_24702650_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `auth_user_groups` */ + +insert into `auth_user_groups`(`id`,`user_id`,`group_id`) values (2,2,1),(3,2,2),(5,3,1); + +/*Table structure for table `auth_user_user_permissions` */ + +DROP TABLE IF EXISTS `auth_user_user_permissions`; + +CREATE TABLE `auth_user_user_permissions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL, + `permission_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user_id` (`user_id`,`permission_id`), + KEY `auth_user_user_perm_permission_id_3d7071f0_fk_auth_permission_id` (`permission_id`), + CONSTRAINT `auth_user_user_permissions_user_id_7cd7acb6_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `auth_user_user_perm_permission_id_3d7071f0_fk_auth_permission_id` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `auth_user_user_permissions` */ + +/*Table structure for table `basedata_address` */ + +DROP TABLE IF EXISTS `basedata_address`; + +CREATE TABLE `basedata_address` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `zipcode` varchar(8) DEFAULT NULL, + `address` varchar(120) DEFAULT NULL, + `phone` varchar(20) DEFAULT NULL, + `contacts` varchar(40) DEFAULT NULL, + `address_type` varchar(2), + `content_type_id` int(11), + `object_id` int(10) unsigned, + PRIMARY KEY (`id`), + KEY `basedata_address_417f1b1c` (`content_type_id`), + CONSTRAINT `basedata_addr_content_type_id_17983026_fk_django_content_type_id` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_address` */ + +/*Table structure for table `basedata_bankaccount` */ + +DROP TABLE IF EXISTS `basedata_bankaccount`; + +CREATE TABLE `basedata_bankaccount` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `account` varchar(40) NOT NULL, + `title` varchar(40) NOT NULL, + `memo` varchar(20) DEFAULT NULL, + `partner_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `basedata_bankaccount_partner_id_561018ee_fk_basedata_partner_id` (`partner_id`), + CONSTRAINT `basedata_bankaccount_partner_id_561018ee_fk_basedata_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `basedata_partner` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_bankaccount` */ + +/*Table structure for table `basedata_brand` */ + +DROP TABLE IF EXISTS `basedata_brand`; + +CREATE TABLE `basedata_brand` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(120) NOT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `trade_id` int(11), + `weight` int(11), + PRIMARY KEY (`id`), + KEY `basedata_brand_09249466` (`trade_id`), + CONSTRAINT `basedata_brand_trade_id_bdcfb86_fk_basedata_trade_id` FOREIGN KEY (`trade_id`) REFERENCES `basedata_trade` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_brand` */ + +insert into `basedata_brand`(`id`,`name`,`pinyin`,`trade_id`,`weight`) values (1,'LENOVO-联想','',NULL,99),(2,'DELL','',3,99); + +/*Table structure for table `basedata_category` */ + +DROP TABLE IF EXISTS `basedata_category`; + +CREATE TABLE `basedata_category` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(6) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `path` varchar(200) DEFAULT NULL, + `parent_id` int(11) DEFAULT NULL, + `trade_id` int(11), + PRIMARY KEY (`id`), + KEY `basedata_category_parent_id_43280ad5_fk_basedata_category_id` (`parent_id`), + KEY `basedata_category_09249466` (`trade_id`), + CONSTRAINT `basedata_category_parent_id_43280ad5_fk_basedata_category_id` FOREIGN KEY (`parent_id`) REFERENCES `basedata_category` (`id`), + CONSTRAINT `basedata_category_trade_id_7d069922_fk_basedata_trade_id` FOREIGN KEY (`trade_id`) REFERENCES `basedata_trade` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_category` */ + +insert into `basedata_category`(`id`,`code`,`name`,`path`,`parent_id`,`trade_id`) values (1,'F01','内部服务','',NULL,NULL),(2,'F02','办公设备','',NULL,NULL),(3,'F03','笔记本电脑','办公设备',2,NULL); + +/*Table structure for table `basedata_education` */ + +DROP TABLE IF EXISTS `basedata_education`; + +CREATE TABLE `basedata_education` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `edu_type` varchar(2) NOT NULL, + `school` varchar(120) NOT NULL, + `major` varchar(120) DEFAULT NULL, + `degree` varchar(2) DEFAULT NULL, + `employee_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_education_employee_id_54096a10_fk_basedata_employee_id` (`employee_id`), + CONSTRAINT `basedata_education_employee_id_54096a10_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_education` */ + +insert into `basedata_education`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`edu_type`,`school`,`major`,`degree`,`employee_id`) values (1,'2004-09-01','2008-07-01',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','20','南京中医药大学','计算机科学与技术','4',1),(2,'2003-09-01','2004-07-01',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','60','山西省运城中学','','9',1),(3,'2000-09-01','2003-07-01',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','60','山西省闻喜中学','','9',1),(5,'2005-09-10','2009-09-10',NULL,NULL,'2015-05-10 16:45:33','2015-05-10 16:45:33','20','江苏教育学院','英语','4',3); + +/*Table structure for table `basedata_employee` */ + +DROP TABLE IF EXISTS `basedata_employee`; + +CREATE TABLE `basedata_employee` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `birthday` date DEFAULT NULL, + `gender` varchar(2) NOT NULL, + `idcard` varchar(20) NOT NULL, + `country` varchar(2) DEFAULT NULL, + `hometown` varchar(40) DEFAULT NULL, + `address` varchar(120) DEFAULT NULL, + `banknum` varchar(40) DEFAULT NULL, + `bankname` varchar(80) DEFAULT NULL, + `emergency` varchar(40) DEFAULT NULL, + `rank` varchar(2) NOT NULL, + `workday` date DEFAULT NULL, + `startday` date DEFAULT NULL, + `religion` varchar(2) DEFAULT NULL, + `marital` varchar(2), + `party` varchar(2), + `nation` varchar(2), + `ygxs` varchar(2), + `status` varchar(2), + `category` varchar(2), + `literacy` varchar(2) DEFAULT NULL, + `major` varchar(2), + `degree` varchar(2), + `tag1` varchar(2), + `tag2` varchar(2), + `tag3` varchar(2), + `tag4` varchar(2), + `organization_id` int(11) DEFAULT NULL, + `position_id` int(11) NOT NULL, + `user_id` int(11) DEFAULT NULL, + `email` varchar(20), + `office` varchar(20), + `phone` varchar(20), + `health` varchar(2), + `spjob` varchar(2), + PRIMARY KEY (`id`), + KEY `basedata_emplo_organization_id_3b46dfdc_fk_organ_organization_id` (`organization_id`), + KEY `basedata_employee_position_id_3d7368b4_fk_organ_position_id` (`position_id`), + KEY `basedata_employee_user_id_6883fc78_fk_auth_user_id` (`user_id`), + CONSTRAINT `basedata_employee_position_id_3d7368b4_fk_organ_position_id` FOREIGN KEY (`position_id`) REFERENCES `organ_position` (`id`), + CONSTRAINT `basedata_employee_user_id_6883fc78_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `basedata_emplo_organization_id_3b46dfdc_fk_organ_organization_id` FOREIGN KEY (`organization_id`) REFERENCES `organ_organization` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_employee` */ + +insert into `basedata_employee`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`pinyin`,`birthday`,`gender`,`idcard`,`country`,`hometown`,`address`,`banknum`,`bankname`,`emergency`,`rank`,`workday`,`startday`,`religion`,`marital`,`party`,`nation`,`ygxs`,`status`,`category`,`literacy`,`major`,`degree`,`tag1`,`tag2`,`tag3`,`tag4`,`organization_id`,`position_id`,`user_id`,`email`,`office`,`phone`,`health`,`spjob`) values (1,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 15:38:58','2015-05-24 19:02:34','22538','朱国良','zhuguoliang','1985-05-03','1','142729198502052119','CN','山西闻喜','南京市浦口区珍珠南路2号明发城市广场','6225102450982716','招商银行','陆阳 13814050418','23','2008-09-01','2014-01-13','10','20','03','01','2','10','30','10','08','4','99','9','00','0',NULL,3,1,'zhugl@asiainfo.com','','13851668514','1','00'),(3,'2015-05-10','9999-12-31','zhugl','luy','2015-05-10 16:45:33','2015-05-10 17:04:41','10003','陆阳','luyang','1988-11-12','2','32102919881112574X','CN','','','','','','10','2009-09-10','2015-05-10','00','10','13','01','2','10','21','10','99','4','99','9','00','0',NULL,2,2,'zhuinfo@126.com','','13814050418','1','00'),(4,'2015-05-16','9999-12-31','zhugl','zhugl','2015-05-16 22:54:31','2015-05-16 22:56:39','60059','刘三姐','liusanjie','1988-11-12','2','412328198811128742','CN','','','','','','12','1978-09-01','2015-05-16','00','10','13','01','2','10','21','10','99','4','99','9','00','0',NULL,3,NULL,'sanjie.liu@126.com','','13913931587','1','00'),(5,'2015-05-17','9999-12-31','zhugl',NULL,'2015-05-17 09:44:58','2015-05-17 09:44:58','60060','郑三炮','zhengsanpao','1956-08-09','1','320123195608092321','CN','','','','','','15','1976-09-01','2015-05-17','00','10','13','01','2','10','21','10','99','4','99','9','00','0',NULL,2,NULL,'sanpao.z@126.com','','13212341234','1','00'); + +/*Table structure for table `basedata_expenseaccount` */ + +DROP TABLE IF EXISTS `basedata_expenseaccount`; + +CREATE TABLE `basedata_expenseaccount` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `category` varchar(4) NOT NULL, + `description` longtext, + `status` tinyint(1) NOT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `basedata_expens_parent_id_61334aac_fk_basedata_expenseaccount_id` (`parent_id`), + CONSTRAINT `basedata_expens_parent_id_61334aac_fk_basedata_expenseaccount_id` FOREIGN KEY (`parent_id`) REFERENCES `basedata_expenseaccount` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_expenseaccount` */ + +insert into `basedata_expenseaccount`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`category`,`description`,`status`,`parent_id`) values (1,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:03:23','2015-05-02 21:03:23','FC0001','差旅补助','PU','',1,NULL),(2,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:03:28','2015-05-02 21:03:28','FC0002','住宿费','PU','',1,NULL),(3,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:03:45','2015-05-02 21:03:45','FC0003','市内交通费','PU','',1,NULL),(4,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:04:00','2015-05-02 21:04:00','FC0004','长途交通(大巴)费','PU','',1,NULL),(5,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:04:11','2015-05-02 21:04:11','FC0005','长途交通(火车)费','PU','',1,NULL),(6,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:04:22','2015-05-02 21:04:22','FC0006','机票费','PU','',1,NULL),(7,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:04:31','2015-05-02 21:04:31','FC0007','业务咨询费','PU','',1,NULL),(8,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:05:09','2015-05-02 21:05:09','FC0008','赞助费','PU','',1,NULL),(9,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:05:32','2015-05-02 21:05:32','FC0009','教育培训费','HR','',1,NULL),(10,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:05:55','2015-05-02 21:05:55','FC0010','集体活动费','HR','',1,NULL),(11,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:06:16','2015-05-02 21:06:16','FC0011','劳务外包费','HR','',1,NULL),(12,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:06:33','2015-05-02 21:06:33','FC0012','结婚礼金','HR','',1,NULL),(13,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:06:43','2015-05-02 21:06:43','FC0013','生育礼金','HR','',1,NULL),(14,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:06:54','2015-05-02 21:06:54','FC0014','丧葬抚恤','HR','',1,NULL),(15,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:07:08','2015-05-02 21:07:08','FC0015','独生子女费','HR','',1,NULL),(16,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:09:31','2015-05-02 21:09:31','FC0016','IT设备及服务费用','OF','',1,NULL),(17,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:09:48','2015-05-02 21:09:48','FC0017','通信及网络费用','OF','',1,NULL),(18,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:10:06','2015-05-02 21:10:06','FC0018','印刷品费用','OF','',1,NULL),(19,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:10:30','2015-05-02 21:10:30','FC0019','劳保用品费用','OF','',1,NULL),(20,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:10:58','2015-05-02 21:10:58','FC0020','办公用品费用','OF','',1,NULL),(21,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:11:32','2015-05-02 21:11:32','FC0021','车辆维修营运保养费','OF','',1,NULL),(22,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:12:00','2015-05-02 21:12:00','FC0022','固定资产购置修缮费','OF','',1,NULL),(23,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:13:39','2015-05-02 21:13:39','FC0023','运输费','MU','',1,NULL),(24,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:13:49','2015-05-02 21:13:49','FC0024','包装费','MU','',1,NULL),(25,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:14:08','2015-05-02 21:14:08','FC0025','设备维修费','MU','',1,NULL),(26,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:14:33','2015-05-02 21:14:33','FC0026','技术咨询费','MU','',1,NULL),(27,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:14:58','2015-05-02 21:14:58','FC0027','礼品费','BU','',1,NULL),(28,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:15:10','2015-05-02 21:15:10','FC0028','业务招待费','BU','',1,NULL),(29,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:15:25','2015-05-02 21:15:25','FC0029','广告费','BU','',1,NULL),(30,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:19:28','2015-05-02 21:19:28','FC0030','土地房屋设备租赁费','OF','',1,NULL),(31,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:20:46','2015-05-02 21:20:46','FC0031','诉讼费','PU','',1,NULL),(32,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:21:07','2015-05-02 21:21:07','FC0032','审计费','PU','',1,NULL),(33,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:22:52','2015-05-02 21:22:52','FC0033','商业保险费','PU','',1,NULL),(34,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:23:31','2015-05-02 21:23:31','FC0034','代理服务费','PU','',1,NULL),(35,'2015-05-02','9999-12-31','zhugl',NULL,'2015-05-02 21:26:27','2015-05-02 21:26:27','FC0035','其他不便归类的费用','OT','',1,NULL); + +/*Table structure for table `basedata_extraparam` */ + +DROP TABLE IF EXISTS `basedata_extraparam`; + +CREATE TABLE `basedata_extraparam` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(40) NOT NULL, + `data_type` varchar(6) NOT NULL, + `data_source` varchar(40) DEFAULT NULL, + `material_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_extraparam_material_id_615a14c3_fk_basedata_material_id` (`material_id`), + CONSTRAINT `basedata_extraparam_material_id_615a14c3_fk_basedata_material_id` FOREIGN KEY (`material_id`) REFERENCES `basedata_material` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_extraparam` */ + +insert into `basedata_extraparam`(`id`,`name`,`data_type`,`data_source`,`material_id`) values (1,'出发日期','DATE','',1),(2,'预计返回日期','DATE','',1),(3,'目的地','CHAR','',1),(4,'起始地','CHAR','',3),(5,'目的地','CHAR','',3),(6,'里程','NUM','',3),(7,'出发时间','CHAR','',3); + +/*Table structure for table `basedata_family` */ + +DROP TABLE IF EXISTS `basedata_family`; + +CREATE TABLE `basedata_family` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `relation` varchar(2) DEFAULT NULL, + `status` varchar(2) DEFAULT NULL, + `name` varchar(60) NOT NULL, + `birthday` date DEFAULT NULL, + `organization` varchar(120) DEFAULT NULL, + `phone` varchar(120) DEFAULT NULL, + `emergency` tinyint(1) NOT NULL, + `employee_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_family_employee_id_2c56437d_fk_basedata_employee_id` (`employee_id`), + CONSTRAINT `basedata_family_employee_id_2c56437d_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_family` */ + +insert into `basedata_family`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`relation`,`status`,`name`,`birthday`,`organization`,`phone`,`emergency`,`employee_id`) values (1,NULL,NULL,NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','12','17','陆阳','1988-05-04','南京朗坤软件有限公司','13814050418',1,1),(2,NULL,NULL,NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','51','27','朱元泽','1957-05-04','务农','15035409224',0,1),(3,NULL,NULL,NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','52','27','张艮平','1959-05-04','务农','15035409224',0,1),(4,NULL,NULL,NULL,NULL,'2015-05-10 16:51:24','2015-05-10 16:51:24','11','13','朱国良','1985-02-05','亚信科技有限公司','13851668514',1,3); + +/*Table structure for table `basedata_material` */ + +DROP TABLE IF EXISTS `basedata_material`; + +CREATE TABLE `basedata_material` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `barcode` varchar(40) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `spec` varchar(120) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `status` tinyint(1) NOT NULL, + `is_equip` tinyint(1) NOT NULL, + `can_sale` tinyint(1) NOT NULL, + `is_virtual` tinyint(1) NOT NULL, + `stock_price` decimal(14,4) DEFAULT NULL, + `purchase_price` decimal(14,4) DEFAULT NULL, + `sale_price` decimal(14,4) DEFAULT NULL, + `brand_id` int(11) DEFAULT NULL, + `category_id` int(11) DEFAULT NULL, + `warehouse_id` int(11), + PRIMARY KEY (`id`), + KEY `basedata_material_brand_id_70cca220_fk_basedata_brand_id` (`brand_id`), + KEY `basedata_material_category_id_7ca5506e_fk_basedata_category_id` (`category_id`), + KEY `basedata_material_9744817e` (`warehouse_id`), + CONSTRAINT `basedata_material_brand_id_70cca220_fk_basedata_brand_id` FOREIGN KEY (`brand_id`) REFERENCES `basedata_brand` (`id`), + CONSTRAINT `basedata_material_category_id_7ca5506e_fk_basedata_category_id` FOREIGN KEY (`category_id`) REFERENCES `basedata_category` (`id`), + CONSTRAINT `basedata_material_warehouse_id_1e7533f6_fk_basedata_warehouse_id` FOREIGN KEY (`warehouse_id`) REFERENCES `basedata_warehouse` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_material` */ + +insert into `basedata_material`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`barcode`,`name`,`spec`,`pinyin`,`status`,`is_equip`,`can_sale`,`is_virtual`,`stock_price`,`purchase_price`,`sale_price`,`brand_id`,`category_id`,`warehouse_id`) values (1,'2015-05-22','9999-12-31','zhugl','zhugl','2015-05-22 22:03:36','2015-05-22 22:10:34','IT00001','','出差申请','',NULL,1,0,0,1,NULL,NULL,NULL,NULL,1,2),(2,'2015-05-23','9999-12-31','zhugl',NULL,'2015-05-23 07:47:02','2015-05-23 07:47:02','IT00002','','戴尔(DELL)Inspiron 3455-R1248 灵越23.8英寸一体电脑 ','E2-7110 4G 500G WIFI 蓝牙 WIN8.1 3年上门',NULL,1,1,0,0,NULL,NULL,NULL,2,3,3),(3,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 15:13:47','2015-05-24 15:14:11','IT00003','','用车申请','',NULL,1,0,0,1,NULL,NULL,NULL,NULL,1,NULL); + +/*Table structure for table `basedata_material_measure` */ + +DROP TABLE IF EXISTS `basedata_material_measure`; + +CREATE TABLE `basedata_material_measure` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `material_id` int(11) NOT NULL, + `measure_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `material_id` (`material_id`,`measure_id`), + KEY `basedata_material_mea_measure_id_5c0d90fc_fk_basedata_measure_id` (`measure_id`), + CONSTRAINT `basedata_material_mea_measure_id_5c0d90fc_fk_basedata_measure_id` FOREIGN KEY (`measure_id`) REFERENCES `basedata_measure` (`id`), + CONSTRAINT `basedata_material_me_material_id_572f4c8_fk_basedata_material_id` FOREIGN KEY (`material_id`) REFERENCES `basedata_material` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_material_measure` */ + +insert into `basedata_material_measure`(`id`,`material_id`,`measure_id`) values (4,1,8),(5,2,9),(7,3,8); + +/*Table structure for table `basedata_materialparam` */ + +DROP TABLE IF EXISTS `basedata_materialparam`; + +CREATE TABLE `basedata_materialparam` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `creation` date NOT NULL, + `material_id` int(11) NOT NULL, + `param_name_id` int(11), + `param_value_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_materialpa_material_id_666e08d1_fk_basedata_material_id` (`material_id`), + KEY `basedata_materialparam_996e5113` (`param_name_id`), + KEY `basedata_materialparam_2f9b9c2f` (`param_value_id`), + CONSTRAINT `basedata_materialpa_material_id_666e08d1_fk_basedata_material_id` FOREIGN KEY (`material_id`) REFERENCES `basedata_material` (`id`), + CONSTRAINT `bas_param_name_id_3c50302d_fk_basedata_technicalparametername_id` FOREIGN KEY (`param_name_id`) REFERENCES `basedata_technicalparametername` (`id`), + CONSTRAINT `b_param_value_id_18882fba_fk_basedata_technicalparametervalue_id` FOREIGN KEY (`param_value_id`) REFERENCES `basedata_technicalparametervalue` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_materialparam` */ + +/*Table structure for table `basedata_measure` */ + +DROP TABLE IF EXISTS `basedata_measure`; + +CREATE TABLE `basedata_measure` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(6) DEFAULT NULL, + `name` varchar(20) NOT NULL, + `status` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_measure` */ + +insert into `basedata_measure`(`id`,`code`,`name`,`status`) values (1,'ge','个',1),(2,'zhi','只',1),(3,'kg','千克',1),(4,'t','吨',1),(5,'g','克',1),(6,'gen','根',1),(7,'xi','箱',1),(8,'CI','次',1),(9,'TAI','台',1); + +/*Table structure for table `basedata_partner` */ + +DROP TABLE IF EXISTS `basedata_partner`; + +CREATE TABLE `basedata_partner` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `short` varchar(20) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `partner_type` varchar(2) NOT NULL, + `level` varchar(2) NOT NULL, + `tax_num` varchar(40) DEFAULT NULL, + `tax_address` varchar(40) DEFAULT NULL, + `tax_account` varchar(80) DEFAULT NULL, + `contacts` varchar(40), + `memo` longtext, + `phone` varchar(40), + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_partner` */ + +insert into `basedata_partner`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`short`,`pinyin`,`partner_type`,`level`,`tax_num`,`tax_address`,`tax_account`,`contacts`,`memo`,`phone`) values (1,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 15:21:46','2015-05-01 15:21:46','90001','中国移动通信集团','','','C','A','','','',NULL,NULL,NULL); + +/*Table structure for table `basedata_project` */ + +DROP TABLE IF EXISTS `basedata_project`; + +CREATE TABLE `basedata_project` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `short` varchar(20) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `status` varchar(2) DEFAULT NULL, + `prj_type` varchar(2), + `description` longtext, + `budget` decimal(10,2) DEFAULT NULL, + `income` decimal(10,2) DEFAULT NULL, + `expand` decimal(10,2) DEFAULT NULL, + `blueprint` varchar(100) DEFAULT NULL, + `offer` varchar(100) DEFAULT NULL, + `business` varchar(100) DEFAULT NULL, + `partner_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `basedata_project_partner_id_36721156_fk_basedata_partner_id` (`partner_id`), + CONSTRAINT `basedata_project_partner_id_36721156_fk_basedata_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `basedata_partner` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_project` */ + +insert into `basedata_project`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`short`,`pinyin`,`status`,`prj_type`,`description`,`budget`,`income`,`expand`,`blueprint`,`offer`,`business`,`partner_id`) values (1,'2015-05-02','9999-12-31','zhugl','zhugl','2015-05-02 09:48:49','2015-05-02 17:53:46','PJ0001','浦东机场2015年建设修补项目','','','00','10','',NULL,NULL,NULL,'','','',1),(2,'2015-05-23','9999-12-31','zhugl',NULL,'2015-05-23 20:47:55','2015-05-23 20:47:55','PJ0002','2015年设备维修项目','','','00','20','',NULL,NULL,NULL,'','','',NULL),(3,'2015-05-23','9999-12-31','zhugl',NULL,'2015-05-23 21:38:56','2015-05-23 21:38:56','PJ0003','2015年人事行政费用项目','','','00','00','',NULL,NULL,NULL,'','','',NULL); + +/*Table structure for table `basedata_project_users` */ + +DROP TABLE IF EXISTS `basedata_project_users`; + +CREATE TABLE `basedata_project_users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `project_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `project_id` (`project_id`,`user_id`), + KEY `basedata_project_users_user_id_2b10e1a1_fk_auth_user_id` (`user_id`), + CONSTRAINT `basedata_project_users_project_id_1560ad8_fk_basedata_project_id` FOREIGN KEY (`project_id`) REFERENCES `basedata_project` (`id`), + CONSTRAINT `basedata_project_users_user_id_2b10e1a1_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_project_users` */ + +insert into `basedata_project_users`(`id`,`project_id`,`user_id`) values (5,1,1); + +/*Table structure for table `basedata_technicalparametername` */ + +DROP TABLE IF EXISTS `basedata_technicalparametername`; + +CREATE TABLE `basedata_technicalparametername` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(40) NOT NULL, + `status` tinyint(1) NOT NULL, + `category_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_technicalpa_category_id_8e419b4_fk_basedata_category_id` (`category_id`), + CONSTRAINT `basedata_technicalpa_category_id_8e419b4_fk_basedata_category_id` FOREIGN KEY (`category_id`) REFERENCES `basedata_category` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_technicalparametername` */ + +/*Table structure for table `basedata_technicalparametervalue` */ + +DROP TABLE IF EXISTS `basedata_technicalparametervalue`; + +CREATE TABLE `basedata_technicalparametervalue` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `value` varchar(80) NOT NULL, + `description` varchar(80) DEFAULT NULL, + `tech_name_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `base_tech_name_id_401b4baa_fk_basedata_technicalparametername_id` (`tech_name_id`), + CONSTRAINT `base_tech_name_id_401b4baa_fk_basedata_technicalparametername_id` FOREIGN KEY (`tech_name_id`) REFERENCES `basedata_technicalparametername` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_technicalparametervalue` */ + +/*Table structure for table `basedata_trade` */ + +DROP TABLE IF EXISTS `basedata_trade`; + +CREATE TABLE `basedata_trade` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(6) NOT NULL, + `name` varchar(120) NOT NULL, + `memo` varchar(120) DEFAULT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `basedata_trade_parent_id_40eb4a8a_fk_basedata_trade_id` (`parent_id`), + CONSTRAINT `basedata_trade_parent_id_40eb4a8a_fk_basedata_trade_id` FOREIGN KEY (`parent_id`) REFERENCES `basedata_trade` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_trade` */ + +insert into `basedata_trade`(`id`,`code`,`name`,`memo`,`parent_id`) values (1,'A','农、林、牧、渔业','',NULL),(2,'B','采矿业','',NULL),(3,'C','制造业','',NULL),(4,'D','电力、燃气及水的生产和供应业','',NULL),(5,'E','建筑业','',NULL),(6,'F','交通运输、仓储和邮政业','',NULL),(7,'G','信息传输、计算机服务和软件业','',NULL),(8,'H','批发和零售业','',NULL),(9,'I','住宿和餐饮业','',NULL),(10,'J','金融业','',NULL),(11,'K','房地产业','',NULL),(12,'L','租赁和商务服务业','',NULL),(13,'M','科学研究、技术服务和地质勘查业','',NULL),(14,'N','水利、环境和公共设施管理业','',NULL),(15,'O','居民服务和其他服务业','',NULL),(16,'P','教育','',NULL),(17,'Q','卫生、社会保障和社会福利业','',NULL),(18,'R','文化、体育和娱乐业','',NULL),(19,'S','公共管理和社会组织','',NULL),(20,'T','国际组织','',NULL); + +/*Table structure for table `basedata_valuelist` */ + +DROP TABLE IF EXISTS `basedata_valuelist`; + +CREATE TABLE `basedata_valuelist` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `status` tinyint(1) NOT NULL, + `init` tinyint(1) NOT NULL, + `locked` tinyint(1) NOT NULL, + `lock_time` datetime DEFAULT NULL, + `locked_by_id` int(11) DEFAULT NULL, + `module_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `basedata_valuelist_module_id_249f4ef9_fk_syscfg_module_id` (`module_id`), + KEY `basedata_valuelist_locked_by_id_3ddaefa_fk_auth_user_id` (`locked_by_id`), + CONSTRAINT `basedata_valuelist_locked_by_id_3ddaefa_fk_auth_user_id` FOREIGN KEY (`locked_by_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `basedata_valuelist_module_id_249f4ef9_fk_syscfg_module_id` FOREIGN KEY (`module_id`) REFERENCES `syscfg_module` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_valuelist` */ + +insert into `basedata_valuelist`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`status`,`init`,`locked`,`lock_time`,`locked_by_id`,`module_id`) values (10,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 09:58:32','2015-05-03 08:16:48','gender','性别',1,0,0,NULL,NULL,2),(11,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 10:31:10','2015-05-03 07:08:51','S011','地址类型',1,0,0,NULL,NULL,2),(12,'2015-05-02','9999-12-31','zhugl','zhugl','2015-05-02 10:00:30','2015-05-03 07:08:44','S012','项目状态',1,0,0,NULL,NULL,2),(13,'2015-05-02','9999-12-31','zhugl','zhugl','2015-05-02 10:03:27','2015-05-03 07:08:28','S013','项目类别',1,0,0,NULL,NULL,2),(14,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 06:49:41','2015-05-03 06:49:41','S014','岗位序列',1,0,0,NULL,NULL,2),(15,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 06:56:08','2015-05-09 15:41:55','S015','岗位级别',1,0,0,NULL,NULL,2),(16,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 07:13:31','2015-05-03 07:13:31','S016','人员状态',1,0,0,NULL,NULL,2),(17,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 07:19:43','2015-05-03 07:19:50','S017','职员级别',1,0,0,NULL,NULL,2),(18,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 07:22:10','2015-05-03 07:22:10','S018','人员类别',1,0,0,NULL,NULL,2),(19,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 07:24:00','2015-05-03 15:12:54','S019','用工形式',1,0,0,NULL,NULL,2),(20,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 07:33:41','2015-05-03 07:33:41','S020','宗教信仰',1,0,0,NULL,NULL,2),(21,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 07:42:12','2015-05-03 08:32:32','S021','民族',1,0,0,NULL,NULL,2),(22,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 07:54:20','2015-05-03 07:54:20','S022','国家',1,0,0,NULL,NULL,2),(23,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:00:47','2015-05-03 08:33:02','S023','婚姻状况',1,0,0,NULL,NULL,2),(24,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:11:20','2015-05-03 08:32:51','S024','文化程度',1,0,0,NULL,NULL,2),(25,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:26:49','2015-05-03 08:32:42','S025','家庭关系',1,0,0,NULL,NULL,2),(26,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:39:02','2015-05-03 08:43:11','S026','政治面貌',1,0,0,NULL,NULL,2),(27,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:41:44','2015-05-03 08:41:44','S027','兵役状况',1,0,0,NULL,NULL,2),(28,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:44:29','2015-05-03 08:44:29','S028','血型',1,0,0,NULL,NULL,2),(29,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:51:03','2015-05-03 08:51:03','S029','人员身份',1,0,0,NULL,NULL,2),(30,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:52:49','2015-05-03 08:52:49','S030','合同类型',1,0,0,NULL,NULL,2),(31,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:54:11','2015-05-03 08:54:19','S031','合同期限类型',1,0,0,NULL,NULL,2),(32,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 08:55:13','2015-05-03 08:56:32','S032','合同密级',1,0,0,NULL,NULL,2),(33,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:56:17','2015-05-03 08:56:17','S033','合同变动类型',1,0,0,NULL,NULL,2),(34,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 08:58:32','2015-05-03 08:58:32','S034','工时制度',1,0,0,NULL,NULL,2),(35,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 09:56:24','2015-05-03 09:56:24','S035','教育类型',1,0,0,NULL,NULL,2),(36,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 10:02:20','2015-05-03 10:02:38','S036','从学单位类别',1,0,0,NULL,NULL,2),(37,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 10:13:32','2015-05-03 10:16:48','S037','学位',1,0,0,NULL,NULL,2),(38,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 10:16:17','2015-05-03 10:17:06','S038','专业类别',1,0,0,NULL,NULL,2),(39,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 13:41:51','2015-05-03 13:41:51','S039','复转军人标识',1,0,0,NULL,NULL,2),(40,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 14:04:26','2015-05-03 14:07:50','S040','党委负责人标识',1,0,0,NULL,NULL,2),(41,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 14:07:37','2015-05-03 14:08:16','S041','董事监事标识',1,0,0,NULL,NULL,2),(42,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 14:14:35','2015-05-03 14:18:08','S042','特殊工种',1,0,0,NULL,NULL,2),(43,'2015-05-03','9999-12-31','zhugl',NULL,'2015-05-03 14:21:31','2015-05-03 14:21:31','S043','身体状况',1,0,0,NULL,NULL,2),(44,'2015-05-22','9999-12-31','zhugl','zhugl','2015-05-22 22:38:58','2015-05-25 20:58:34','S044','工单类型',1,0,0,NULL,NULL,2),(45,'2015-05-22','9999-12-31','zhugl','zhugl','2015-05-22 22:41:19','2015-05-25 20:26:41','S045','业务域',1,0,0,NULL,NULL,4),(46,'2015-05-22','9999-12-31','zhugl','zhugl','2015-05-22 22:44:49','2015-05-24 20:07:18','S046','工单状态',1,0,0,NULL,NULL,4),(47,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 20:04:37','2015-05-24 20:06:09','S047','试用期',1,1,1,NULL,NULL,3),(48,'2015-05-24','9999-12-31','zhugl',NULL,'2015-05-24 20:11:06','2015-05-24 20:11:06','S048','工资项类别',1,0,0,NULL,NULL,3),(49,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 20:13:08','2015-05-24 20:13:15','S049','增减属性',1,0,0,NULL,NULL,3),(50,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 20:20:10','2015-05-24 20:37:22','S050','计算方式',1,0,0,NULL,NULL,3),(51,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 21:32:21','2015-05-24 21:32:31','S051','离职类别',1,0,0,NULL,NULL,3); + +/*Table structure for table `basedata_valuelistitem` */ + +DROP TABLE IF EXISTS `basedata_valuelistitem`; + +CREATE TABLE `basedata_valuelistitem` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `group_code` varchar(6) DEFAULT NULL, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `status` tinyint(1) NOT NULL, + `weight` int(11) DEFAULT NULL, + `group_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_valuelistitem_group_id_13b9f5f2_idx` (`group_id`,`group_code`), + CONSTRAINT `basedata_valuelistite_group_id_435c66f8_fk_basedata_valuelist_id` FOREIGN KEY (`group_id`) REFERENCES `basedata_valuelist` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=398 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_valuelistitem` */ + +insert into `basedata_valuelistitem`(`id`,`group_code`,`code`,`name`,`status`,`weight`,`group_id`) values (13,'S011','01','送货地址',1,9,11),(14,'S011','02','发票地址',1,9,11),(15,'S011','03','临时地址',1,9,11),(16,'S011','04','家庭地址',0,9,11),(17,'S012','00','跟踪/新建',1,1,12),(18,'S012','01','投标/报价',1,2,12),(19,'S012','02','签订合同',1,3,12),(20,'S012','03','生产/交付',1,4,12),(21,'S012','04','验收/回款',1,5,12),(22,'S012','99','关闭',1,6,12),(23,'S013','00','产品/服务交付类',1,9,13),(24,'S013','10','技术/设备改造类',1,9,13),(25,'S013','20','内部运营类',1,9,13),(26,'S013','40','其他临时项目',1,9,13),(27,'S014','A','管理/行政类',1,9,14),(28,'S014','S','营销/市场类',1,9,14),(29,'S014','T','技术/研发类',1,9,14),(30,'S014','P','生产/操作类',1,9,14),(31,'S015','01','员级',1,9,15),(32,'S015','02','初级',1,9,15),(33,'S015','03','中级',1,9,15),(34,'S015','04','高级',1,9,15),(35,'S015','05','专家',1,9,15),(36,'S016','10','在岗工作',1,9,16),(37,'S016','11','见习期(试用)',1,9,16),(38,'S016','12','待岗',1,9,16),(39,'S016','20','离职',1,9,16),(40,'S016','21','退休',1,9,16),(41,'S016','22','终止劳动合同',1,9,16),(42,'S016','23','协商解除劳动合同',1,9,16),(43,'S016','24','劳动者主张解除劳动合同',1,9,16),(44,'S016','25','用人单位主张解除劳动合同',1,9,16),(45,'S016','30','死亡',1,9,16),(46,'S017','10','领导班子',1,9,17),(47,'S017','11','副总师(助理)',1,9,17),(48,'S017','12','部门负责人(正职)',1,9,17),(49,'S017','13','部门负责人(副职)',1,9,17),(50,'S017','14','部门内设机构负责人(正职)',1,9,17),(51,'S017','15','部门内设机构负责人(副职)',1,9,17),(52,'S017','20','一级职员',1,9,17),(53,'S017','21','二级职员',1,9,17),(54,'S017','22','三级职员',1,9,17),(55,'S017','23','四级职员',1,9,17),(56,'S017','24','五级职员',1,9,17),(57,'S017','25','六级职员',1,9,17),(58,'S017','26','七级职员',1,9,17),(59,'S017','27','八级职员',1,9,17),(60,'S018','10','经营者',1,9,18),(61,'S018','20','中层管理人员',1,9,18),(62,'S018','21','一般管理人员',1,9,18),(63,'S018','30','专业技术人员',1,9,18),(64,'S018','40','技能人员',1,9,18),(65,'S018','50','服务人员',1,9,18),(66,'S018','90','其他人员',1,9,18),(67,'S019','1','劳动合同制(长期)',1,9,19),(68,'S019','2','劳动合同制(短期)',1,9,19),(69,'S019','3','人事代理制',1,9,19),(70,'S019','4','劳务派遣制',1,9,19),(71,'S019','5','非全日制',1,9,19),(72,'S019','6','业务外包',1,9,19),(73,'S019','9','其他',1,9,19),(74,'S020','00','无宗教信仰',1,9,20),(75,'S020','10','佛教',1,9,20),(76,'S020','20','喇嘛教',1,9,20),(77,'S020','30','道教',1,9,20),(78,'S020','40','天主教',1,9,20),(79,'S020','50','基督教',1,9,20),(80,'S020','70','东正教',1,9,20),(81,'S020','80','伊斯兰教',1,9,20),(82,'S020','99','其他',1,9,20),(83,'S021','01','汉族',1,9,21),(84,'S021','02','蒙古族',1,9,21),(85,'S021','03','回族',1,9,21),(86,'S021','04','藏族',1,9,21),(87,'S021','05','维吾尔族',1,9,21),(88,'S021','06','苗族',1,9,21),(89,'S021','07','彝族',1,9,21),(90,'S021','08','壮族',1,9,21),(91,'S021','09','布依族',1,9,21),(92,'S021','10','朝鲜族',1,9,21),(93,'S021','11','满族',1,9,21),(94,'S022','CN','中国',1,9,22),(95,'S022','EG','埃及',1,9,22),(96,'S022','AT','奥地利',1,9,22),(97,'S022','AU','澳大利亚',1,9,22),(98,'S022','PK','巴基斯坦',1,9,22),(99,'S022','BR','巴西',1,9,22),(100,'S022','KP','北朝鲜',1,9,22),(101,'S022','BE','比利时',1,9,22),(102,'S022','IS','冰岛',1,9,22),(103,'S022','PL','波兰',1,9,22),(104,'S022','DK','丹麦',1,9,22),(105,'S022','DE','德国',1,9,22),(106,'S022','FR','法国',1,9,22),(107,'S022','KR','韩国',1,9,22),(108,'S022','NL','荷兰',1,9,22),(109,'S022','CA','加拿大',1,9,22),(110,'S022','US','美国',1,9,22),(111,'S022','JP','日本',1,9,22),(112,'S022','TW','中国台湾',1,9,22),(113,'S022','HK','中国香港',1,9,22),(114,'S022','ES','西班牙',1,9,22),(115,'S022','GR','希腊',1,9,22),(116,'S022','SG','新加坡',1,9,22),(117,'S022','NZ','新西兰',1,9,22),(118,'S022','IT','意大利',1,9,22),(119,'S022','GB','英国',1,9,22),(120,'S022','MO','中国澳门',1,9,22),(121,'S022','IL','以色列',1,9,22),(122,'S023','10','未婚',1,9,23),(123,'S023','20','初婚',1,9,23),(124,'S023','21','再婚',1,9,23),(125,'S023','22','复婚',1,9,23),(126,'S023','30','丧偶',1,9,23),(127,'S023','40','离婚',1,9,23),(128,'S023','90','其他',1,9,23),(129,'S024','0','研究生',1,9,24),(132,'S024','10','大学本科',1,9,24),(136,'S024','20','大学专科和专科学校',1,9,24),(144,'S024','40','技工学校',1,9,24),(146,'S024','50','高中',1,9,24),(147,'S024','60','初中',1,9,24),(148,'S024','70','小学',1,9,24),(149,'S024','80','文盲或半文盲',1,9,24),(150,'gender','0','未知的性别',1,9,10),(151,'gender','1','男性',1,9,10),(152,'gender','2','女性',1,9,10),(153,'gender','9','未说明的性别',1,9,10),(154,'S025','11','丈夫',1,9,25),(155,'S025','12','妻子',1,9,25),(156,'S025','21','独生子',1,9,25),(157,'S025','22','长子',1,9,25),(158,'S025','23','次子',1,9,25),(159,'S025','24','三子',1,9,25),(160,'S025','25','四子',1,9,25),(161,'S025','26','五子',1,9,25),(162,'S025','27','养子或继子',1,9,25),(163,'S025','28','女婿',1,9,25),(164,'S025','31','独生女',1,9,25),(165,'S025','32','长女',1,9,25),(166,'S025','33','次女',1,9,25),(167,'S025','34','三女',1,9,25),(168,'S025','35','四女',1,9,25),(169,'S025','36','五女',1,9,25),(170,'S025','37','养女或继女',1,9,25),(171,'S025','51','父亲',1,9,25),(172,'S025','52','母亲',1,9,25),(173,'S025','53','公公',1,9,25),(174,'S025','54','婆婆',1,9,25),(175,'S025','55','岳父',1,9,25),(176,'S025','56','岳母',1,9,25),(177,'S025','57','继父或养父',1,9,25),(178,'S025','58','继母或养母',1,9,25),(179,'S025','71','兄',1,9,25),(180,'S025','72','嫂',1,9,25),(181,'S025','73','弟',1,9,25),(182,'S025','74','弟媳',1,9,25),(183,'S025','75','姐姐',1,9,25),(184,'S025','76','姐夫',1,9,25),(185,'S025','77','妹妹',1,9,25),(186,'S025','78','妹夫',1,9,25),(187,'S026','01','中国共产党党员',1,9,26),(188,'S026','02','中国共产党预备党员',1,9,26),(189,'S026','03','中国共产主义青年团团员',1,9,26),(190,'S026','04','中国国民党革命委员会会员',1,9,26),(191,'S026','05','中国民主同盟盟员',1,9,26),(192,'S026','06','中国民主建国会会员',1,9,26),(193,'S026','07','中国民主促进会会员',1,9,26),(194,'S026','08','中国农工民主党党员',1,9,26),(195,'S026','09','中国致公党党员',1,9,26),(196,'S026','10','九三学社社员',1,9,26),(197,'S026','11','台湾民主自治同盟盟员',1,9,26),(198,'S026','12','无党派民主人士',1,9,26),(199,'S026','13','群众',1,9,26),(200,'S027','0','未服兵役',1,9,27),(201,'S027','1','退出现役',1,9,27),(202,'S027','2','士兵预备役',1,9,27),(203,'S027','3','军官预备役',1,9,27),(204,'S027','4','服现役',1,9,27),(205,'S027','9','其他',1,9,27),(206,'S028','0','不明',1,9,28),(207,'S028','1','A型',1,9,28),(208,'S028','2','B型',1,9,28),(209,'S028','3','O型',1,9,28),(210,'S028','4','AB型',1,9,28),(211,'S028','9','其他',1,9,28),(212,'S029','11','国家公务员',1,9,29),(213,'S029','13','专业技术人员',1,9,29),(214,'S029','17','职员',1,9,29),(215,'S029','21','企业管理人员',1,9,29),(216,'S029','24','工人',1,9,29),(217,'S029','27','农民',1,9,29),(218,'S029','31','学生',1,9,29),(219,'S029','37','现役军人',1,9,29),(220,'S029','51','自由职业者',1,9,29),(221,'S029','54','个人经营者',1,9,29),(222,'S029','70','无业人员',1,9,29),(223,'S029','80','退(离)休人员',1,9,29),(224,'S029','90','其他',1,9,29),(225,'S030','1','劳动合同',1,9,30),(226,'S030','2','岗位聘用合同',1,9,30),(227,'S030','3','聘任合同',1,9,30),(228,'S030','9','其他',1,9,30),(229,'S031','1','有固定期限',1,9,31),(230,'S031','2','无固定期限',1,9,31),(231,'S031','3','以任务为限',1,9,31),(232,'S031','9','其他',1,9,31),(233,'S032','1','严格保密',1,9,32),(234,'S032','2','需要保密',1,9,32),(235,'S032','3','无需保密',1,9,32),(236,'S033','01','初定',1,9,33),(237,'S033','02','续订',1,9,33),(238,'S033','03','变更',1,9,33),(239,'S033','04','终止',1,9,33),(240,'S033','05','解除',1,9,33),(241,'S034','1','定时',1,9,34),(242,'S034','2','不定时',1,9,34),(243,'S034','3','综合计算工时',1,9,34),(244,'S035','10','研究生教育',1,9,35),(245,'S035','20','大学本科教育',1,9,35),(246,'S035','30','大学专科教育',1,9,35),(247,'S035','40','中等职业教育',1,9,35),(248,'S035','60','普通高级中学教育',1,9,35),(249,'S035','70','初级中学教育',1,9,35),(250,'S035','80','小学教育',1,9,35),(251,'S035','90','其他',1,9,35),(252,'S035','99','非学历教育',1,9,35),(254,'S036','11','全日制小学',1,9,36),(255,'S036','12','全日制中学',1,9,36),(256,'S036','13','全日制中专',1,9,36),(257,'S036','14','全日制高等学校',1,9,36),(259,'S036','41','国家行政学院',1,9,36),(260,'S036','42','省行政学院',1,9,36),(261,'S036','49','其他行政学院(校)',1,9,36),(262,'S036','71','中央党校',1,9,36),(263,'S036','72','省委党校',1,9,36),(264,'S036','73','地、市委党校',1,9,36),(265,'S036','81','军队(武警)高等院校',1,9,36),(266,'S036','82','军队(武警)中等专科学校',1,9,36),(267,'S036','83','军队(武警)党校',1,9,36),(268,'S036','84','军队(武警)科研机构',1,9,36),(269,'S036','85','军队(武警)医院',1,9,36),(270,'S037','1','名誉博士 ',1,9,37),(271,'S037','2','博士',1,9,37),(272,'S037','3','硕士',1,9,37),(273,'S037','4','学士',1,9,37),(274,'S037','5','双学士',1,9,37),(275,'S038','01','哲学',1,9,38),(276,'S038','02','经济学',1,9,38),(277,'S038','03','法学',1,9,38),(278,'S038','04','教育学',1,9,38),(279,'S038','05','文学',1,9,38),(280,'S038','06','历史学',1,9,38),(281,'S038','07','理学',1,9,38),(282,'S038','08','工学',1,9,38),(283,'S038','09','农学',1,9,38),(284,'S038','10','医学',1,9,38),(285,'S038','11','军事学',1,9,38),(286,'S038','12','管理学',1,9,38),(287,'S038','14','建筑学',1,9,38),(288,'S037','9','其他',1,9,37),(289,'S038','99','其他',1,9,38),(290,'S039','15','复员干部',1,9,39),(291,'S039','10','军转干部',1,9,39),(292,'S039','20','转业士官',1,9,39),(293,'S039','30','复员士官',1,9,39),(294,'S039','40','退役士兵',1,9,39),(295,'S039','99','非复转军人',1,9,39),(296,'S040','1','党委(党组)书记',1,9,40),(297,'S040','2','党委(党组)副书记',1,9,40),(298,'S040','3','党委常委(党组成员)',1,9,40),(299,'S040','4','纪委书记(纪检组组长)',1,9,40),(300,'S040','6','工会主席',1,9,40),(301,'S040','8','其他党委(党组)负责人',1,9,40),(302,'S040','9','非党委负责人',1,9,40),(303,'S041','010101','董事长',1,9,41),(304,'S041','010102','副董事长',1,9,41),(305,'S041','010103','董事',1,9,41),(306,'S041','010104','职工董事',1,9,41),(307,'S041','0201','监事会主席',1,9,41),(308,'S041','0202','监事会副主席',1,9,41),(309,'S041','0203','监事',1,9,41),(310,'S041','0204','国资委派出监事',1,9,41),(311,'S041','0205','职工监事',1,9,41),(312,'S041','00','非董事监事',1,9,41),(313,'S042','00','非特殊工种',1,9,42),(314,'S042','11','汽机运行值班工',1,9,42),(315,'S042','12','锅炉运行值班工',1,9,42),(316,'S042','13','燃料运行值班工',1,9,42),(317,'S042','14','锅炉本体检修工',1,9,42),(318,'S042','15','保温工',1,9,42),(319,'S042','16','钢球磨煤机及制粉系统检修工',1,9,42),(320,'S042','17','水轮机检修工',1,9,42),(321,'S042','6','其他(由地方社会保障部门认可的特殊工种)',1,9,42),(322,'S042','21','锅炉本体安装工',1,9,42),(323,'S042','22','管道安装工',1,9,42),(324,'S042','23','筑炉瓦工',1,9,42),(325,'S042','24','装模工',1,9,42),(326,'S042','31','水轮机安装工',1,9,42),(327,'S042','32','采石工',1,9,42),(328,'S042','33','爆破',1,9,42),(329,'S042','34','石料粉碎工',1,9,42),(330,'S042','35','潜水员',1,9,42),(331,'S042','35','轮机工',1,9,42),(332,'S042','37','水手',1,9,42),(333,'S042','41','翻砂铸造工',1,9,42),(334,'S042','42','喷砂工',1,9,42),(335,'S042','43','镀锌工',1,9,42),(336,'S042','44','电镀工',1,9,42),(337,'S042','45','印刷线路制板工',1,9,42),(338,'S042','46','浸漆工',1,9,42),(339,'S042','47','电焊条制作工',1,9,42),(340,'S042','48','注塑工',1,9,42),(341,'S042','49','铆工',1,9,42),(342,'S042','51','混凝土工',1,9,42),(343,'S042','52','钢筋工',1,9,42),(344,'S042','53','架子工',1,9,42),(345,'S042','54','推土机司机',1,9,42),(346,'S042','55','挖土机司机',1,9,42),(347,'S042','56','重型载重汽车司机',1,9,42),(348,'S042','57','野外勘测工',1,9,42),(349,'S042','58','沥青工',1,9,42),(350,'S042','59','环氧树脂工',1,9,42),(351,'S043','1','健康或良好',1,9,43),(352,'S043','2','一般或较弱',1,9,43),(353,'S043','3','有慢性病(一)',1,9,43),(354,'S043','4','有慢性病(二)',1,9,43),(355,'S043','6','残疾',1,9,43),(356,'S043','7','军残',1,9,43),(357,'S044','S','内部服务',1,9,44),(358,'S044','R','设备维修',1,9,44),(359,'S044','Q','问题咨询',1,9,44),(360,'S045','HR','人事',1,1,45),(361,'S045','FI','财务',1,2,45),(362,'S045','AD','行政',1,4,45),(363,'S045','MA','市场',1,4,45),(364,'S045','BU','商务',1,5,45),(365,'S045','CS','客服',1,6,45),(366,'S045','OT','其他',1,7,45),(367,'S046','NEW','新建',1,9,46),(368,'S046','SCHE','调度',1,9,46),(369,'S046','PROC','处理',1,9,46),(370,'S046','CLOSE','关闭',1,9,46),(371,'S044','D','采购申请',1,9,44),(372,'S047','0','无试用期',1,1,47),(373,'S047','1','1个月',1,2,47),(374,'S047','2','2个月',1,2,47),(375,'S047','3','3个月',1,3,47),(376,'S047','4','4个月',1,4,47),(377,'S047','5','5个月',1,5,47),(378,'S047','6','6个月',1,6,47),(379,'S047','12','1年',1,12,47),(380,'S048','10','工资',1,9,48),(381,'S048','20','社保',1,9,48),(382,'S048','30','奖金',1,9,48),(383,'S048','40','福利',1,9,48),(384,'S048','99','其他',1,9,48),(385,'S049','+','增加',1,9,49),(386,'S049','-','扣款',1,9,49),(387,'S050','10','固定值',1,9,50),(388,'S050','20','比例值',1,9,50),(390,'S050','30','计算值',1,9,50),(391,'S051','10','个人辞职',1,9,51),(392,'S051','20','合同到期',1,9,51),(393,'S051','30','公司辞退',1,9,51),(394,'S051','40','人员死亡',1,9,51),(395,'S051','50','法定退休',1,9,51),(396,'S051','60','其他',1,9,51),(397,'S045','PO','采购',1,3,45); + +/*Table structure for table `basedata_warehouse` */ + +DROP TABLE IF EXISTS `basedata_warehouse`; + +CREATE TABLE `basedata_warehouse` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `status` tinyint(1) NOT NULL, + `location` varchar(120) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_warehouse` */ + +insert into `basedata_warehouse`(`id`,`code`,`name`,`status`,`location`) values (1,'A01','电力信息一号库',1,''),(2,'A02','内部运营服务',1,''),(3,'A03','办公用品仓库',1,''); + +/*Table structure for table `basedata_warehouse_users` */ + +DROP TABLE IF EXISTS `basedata_warehouse_users`; + +CREATE TABLE `basedata_warehouse_users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `warehouse_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `warehouse_id` (`warehouse_id`,`user_id`), + KEY `basedata_warehouse_users_user_id_c95aacd_fk_auth_user_id` (`user_id`), + CONSTRAINT `basedata_warehouse_users_user_id_c95aacd_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `basedata_warehous_warehouse_id_2b476168_fk_basedata_warehouse_id` FOREIGN KEY (`warehouse_id`) REFERENCES `basedata_warehouse` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_warehouse_users` */ + +/*Table structure for table `basedata_workexperience` */ + +DROP TABLE IF EXISTS `basedata_workexperience`; + +CREATE TABLE `basedata_workexperience` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `organization` varchar(120) NOT NULL, + `position` varchar(120) NOT NULL, + `employee_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `basedata_workexperi_employee_id_1ccfb6d0_fk_basedata_employee_id` (`employee_id`), + CONSTRAINT `basedata_workexperi_employee_id_1ccfb6d0_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `basedata_workexperience` */ + +insert into `basedata_workexperience`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`organization`,`position`,`employee_id`) values (1,'2008-07-01','2010-09-28',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','南京朗坤软件有限公司','项目经理',1),(2,'2010-10-10','2012-01-10',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','上海启腾电气股份有限公司','信息主管',1),(3,'2012-09-20','2014-01-13',NULL,NULL,'2015-05-04 22:22:18','2015-05-04 22:22:18','江苏电力信息技术有限公司','需求分析',1); + +/*Table structure for table `django_admin_log` */ + +DROP TABLE IF EXISTS `django_admin_log`; + +CREATE TABLE `django_admin_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `action_time` datetime NOT NULL, + `object_id` longtext, + `object_repr` varchar(200) NOT NULL, + `action_flag` smallint(5) unsigned NOT NULL, + `change_message` longtext NOT NULL, + `content_type_id` int(11) DEFAULT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `django_admin__content_type_id_5151027a_fk_django_content_type_id` (`content_type_id`), + KEY `django_admin_log_user_id_1c5f563_fk_auth_user_id` (`user_id`), + CONSTRAINT `django_admin_log_user_id_1c5f563_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `django_admin__content_type_id_5151027a_fk_django_content_type_id` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=420 DEFAULT CHARSET=utf8; + +/*Data for the table `django_admin_log` */ + +insert into `django_admin_log`(`id`,`action_time`,`object_id`,`object_repr`,`action_flag`,`change_message`,`content_type_id`,`user_id`) values (1,'2015-05-01 07:30:01','1','系统管理',1,'',8,1),(2,'2015-05-01 07:30:19','1','模块管理',1,'',9,1),(3,'2015-05-01 07:30:32','2','菜单管理',1,'',9,1),(4,'2015-05-01 07:31:17','1','启腾控股集团',1,'',7,1),(5,'2015-05-01 07:31:46','1','职员',1,'',10,1),(6,'2015-05-01 07:31:55','1','职员',2,'已修改 status 。',10,1),(7,'2015-05-01 07:51:45','2','基础数据',1,'',8,1),(8,'2015-05-01 07:52:20','3','角色管理',1,'',9,1),(9,'2015-05-01 09:31:25','1','性别',1,'',11,1),(10,'2015-05-01 09:31:59','1','性别',2,'已添加 list item \"ValueListItem object\". 已添加 list item \"ValueListItem object\".',11,1),(11,'2015-05-01 09:42:07','6','test',1,'',11,1),(12,'2015-05-01 09:43:45','6','test',3,'',11,1),(13,'2015-05-01 09:43:55','7','test',1,'',11,1),(14,'2015-05-01 09:44:34','7','test',3,'',11,1),(15,'2015-05-01 09:44:45','8','test',1,'',11,1),(16,'2015-05-01 09:51:55','8','test2',2,'已修改 name 。',11,1),(17,'2015-05-01 09:57:13','8','test2',3,'',11,1),(18,'2015-05-01 09:57:21','9','test',1,'',11,1),(19,'2015-05-01 09:57:43','1','性别',2,'已修改 init 。',11,1),(20,'2015-05-01 09:58:03','9','test',3,'',11,1),(21,'2015-05-01 09:58:03','1','性别',3,'',11,1),(22,'2015-05-01 09:58:32','10','性别',1,'',11,1),(23,'2015-05-01 10:00:45','10','性别2',2,'已修改 name 。',11,1),(24,'2015-05-01 10:03:06','10','性别3',2,'已修改 name 。',11,1),(25,'2015-05-01 10:03:14','10','性别4',2,'已修改 name 。',11,1),(26,'2015-05-01 10:03:37','10','性别4',2,'已修改 code 。',11,1),(27,'2015-05-01 10:15:20','10','性别',2,'已修改 code 和 name 。',11,1),(28,'2015-05-01 10:31:10','11','地址类型',1,'',11,1),(29,'2015-05-01 10:55:26','1',' ',1,'',13,1),(30,'2015-05-01 15:21:46','1','中国移动通信集团',1,'',14,1),(31,'2015-05-01 20:26:05','1','启腾控股集团',1,'',16,1),(32,'2015-05-01 20:26:20','1','启腾控股集团',2,'已修改 represent 。',16,1),(33,'2015-05-01 20:27:41','1','董事会',1,'',17,1),(34,'2015-05-01 20:27:55','2','集团财务部',1,'',17,1),(35,'2015-05-01 20:28:12','3','人事行政部',1,'',17,1),(36,'2015-05-01 20:29:49','4','人事部',1,'',17,1),(37,'2015-05-01 20:33:18','5','行政部',1,'',17,1),(38,'2015-05-01 20:34:06','5','行政部',2,'已修改 unit_type 。',17,1),(39,'2015-05-01 20:37:19','1','董事长',1,'',18,1),(40,'2015-05-01 20:38:26','1','董事长',2,'已修改 grade 。',18,1),(41,'2015-05-01 20:39:12','1','董事长',2,'已修改 unit 。',18,1),(42,'2015-05-01 20:47:51','2','董事长',1,'',18,1),(43,'2015-05-01 20:48:05','2','董事长',2,'已修改 grade 。',18,1),(44,'2015-05-01 21:06:40','1','上海机场(集团)有限公司',2,'已修改 name,short,pinyin,tax_num,tax_account,tax_address,represent,email,address,zipcode,contacts,phone,fax,website,lic_code 和 cer_code 。',16,1),(45,'2015-05-02 08:52:25','11','地址类型',2,'已变更 status for 列表项 \"04-家庭地址\".',11,1),(46,'2015-05-02 09:48:49','1','浦东机场2015年建设修补项目',1,'',19,1),(47,'2015-05-02 09:49:01','1','浦东机场2015年建设修补项目',2,'已修改 users 。',19,1),(48,'2015-05-02 10:00:30','12','项目状态',1,'',11,1),(49,'2015-05-02 10:03:27','13','项目类别',1,'',11,1),(50,'2015-05-02 10:05:06','1','浦东机场2015年建设修补项目',2,'已修改 prj_type 。',19,1),(51,'2015-05-02 10:06:24','1','浦东机场2015年建设修补项目',2,'已修改 partner 。',19,1),(52,'2015-05-02 13:32:00','1','Measure object',1,'',21,1),(53,'2015-05-02 13:32:11','2','Measure object',1,'',21,1),(54,'2015-05-02 13:32:18','3','Measure object',1,'',21,1),(55,'2015-05-02 13:32:23','4','Measure object',1,'',21,1),(56,'2015-05-02 13:32:31','5','Measure object',1,'',21,1),(57,'2015-05-02 13:32:39','6','Measure object',1,'',21,1),(58,'2015-05-02 13:32:59','7','Measure object',1,'',21,1),(59,'2015-05-02 14:01:22','1','LENOVO-联想',1,'',23,1),(60,'2015-05-02 17:16:53','1','电力信息一号库',1,'',20,1),(61,'2015-05-02 17:17:20','1','物料分类',1,'',24,1),(62,'2015-05-02 17:17:54','2','生产物资',1,'',24,1),(63,'2015-05-02 17:18:11','3','办公物资',1,'',24,1),(64,'2015-05-02 17:23:10','3','办公物资',3,'',24,1),(65,'2015-05-02 17:23:11','2','生产物资',3,'',24,1),(66,'2015-05-02 17:23:41','4','生产物资',1,'',24,1),(67,'2015-05-02 17:24:11','5','元器件',1,'',24,1),(68,'2015-05-02 17:24:23','6','开关设备',1,'',24,1),(69,'2015-05-02 17:25:55','7','IT物资',1,'',24,1),(70,'2015-05-02 17:26:08','8','办公物资',1,'',24,1),(71,'2015-05-02 17:26:30','9','路由器',1,'',24,1),(72,'2015-05-02 17:26:39','10','交换机',1,'',24,1),(73,'2015-05-02 17:26:58','11','信息安全设备',1,'',24,1),(74,'2015-05-02 17:27:33','12','台式机',1,'',24,1),(75,'2015-05-02 17:27:40','13','笔记本',1,'',24,1),(76,'2015-05-02 17:33:19','1','显示器尺寸',1,'',25,1),(77,'2015-05-02 17:50:04','1','浦东机场2015年建设修补项目',2,'已修改 blueprint,offer 和 business 。',19,1),(78,'2015-05-02 17:53:46','1','浦东机场2015年建设修补项目',2,'已修改 blueprint,offer 和 business 。',19,1),(79,'2015-05-02 17:59:37','1','农、林、牧、渔业',1,'',22,1),(80,'2015-05-02 17:59:51','2','采矿业',1,'',22,1),(81,'2015-05-02 18:00:06','3','制造业',1,'',22,1),(82,'2015-05-02 18:00:55','4','电力、燃气及水的生产和供应业',1,'',22,1),(83,'2015-05-02 18:01:10','5','建筑业',1,'',22,1),(84,'2015-05-02 18:01:21','6','交通运输、仓储和邮政业',1,'',22,1),(85,'2015-05-02 18:01:35','7','信息传输、计算机服务和软件业',1,'',22,1),(86,'2015-05-02 18:01:49','8','批发和零售业',1,'',22,1),(87,'2015-05-02 18:02:09','9','住宿和餐饮业',1,'',22,1),(88,'2015-05-02 18:02:22','10','金融业',1,'',22,1),(89,'2015-05-02 18:02:39','11','房地产业',1,'',22,1),(90,'2015-05-02 18:02:50','12','租赁和商务服务业',1,'',22,1),(91,'2015-05-02 18:03:11','13','科学研究、技术服务和地质勘查业',1,'',22,1),(92,'2015-05-02 18:03:29','14','水利、环境和公共设施管理业',1,'',22,1),(93,'2015-05-02 18:03:40','15','居民服务和其他服务业',1,'',22,1),(94,'2015-05-02 18:03:56','16','教育',1,'',22,1),(95,'2015-05-02 18:04:14','17','卫生、社会保障和社会福利业',1,'',22,1),(96,'2015-05-02 18:04:27','18','文化、体育和娱乐业',1,'',22,1),(97,'2015-05-02 18:04:48','19','公共管理和社会组织',1,'',22,1),(98,'2015-05-02 18:06:14','20','国际组织',1,'',22,1),(99,'2015-05-02 18:09:37','1','DELL 笔记本',1,'',27,1),(100,'2015-05-02 18:10:07','1','DELL 笔记本',2,'已修改 category 。',27,1),(101,'2015-05-02 18:10:39','2','DELL',1,'',23,1),(102,'2015-05-02 18:10:43','1','DELL 笔记本',2,'已修改 brand 。',27,1),(103,'2015-05-02 18:12:24','2','联想(Lenovo)小新V2000 Bigger版 ',1,'',27,1),(104,'2015-05-02 21:03:23','1','差旅补助',1,'',29,1),(105,'2015-05-02 21:03:28','2','住宿费',1,'',29,1),(106,'2015-05-02 21:03:45','3','市内交通费',1,'',29,1),(107,'2015-05-02 21:04:00','4','长途交通(大巴)费',1,'',29,1),(108,'2015-05-02 21:04:11','5','长途交通(火车)费',1,'',29,1),(109,'2015-05-02 21:04:22','6','机票费',1,'',29,1),(110,'2015-05-02 21:04:31','7','业务咨询费',1,'',29,1),(111,'2015-05-02 21:05:09','8','赞助费',1,'',29,1),(112,'2015-05-02 21:05:32','9','教育培训费',1,'',29,1),(113,'2015-05-02 21:05:55','10','集体活动费',1,'',29,1),(114,'2015-05-02 21:06:16','11','劳务外包费',1,'',29,1),(115,'2015-05-02 21:06:33','12','结婚礼金',1,'',29,1),(116,'2015-05-02 21:06:43','13','生育礼金',1,'',29,1),(117,'2015-05-02 21:06:54','14','丧葬抚恤',1,'',29,1),(118,'2015-05-02 21:07:08','15','独生子女费',1,'',29,1),(119,'2015-05-02 21:09:31','16','IT设备及服务费用',1,'',29,1),(120,'2015-05-02 21:09:48','17','通信及网络费用',1,'',29,1),(121,'2015-05-02 21:10:06','18','印刷品费用',1,'',29,1),(122,'2015-05-02 21:10:30','19','劳保用品费用',1,'',29,1),(123,'2015-05-02 21:10:58','20','办公用品费用',1,'',29,1),(124,'2015-05-02 21:11:32','21','车辆维修营运保养费',1,'',29,1),(125,'2015-05-02 21:12:00','22','固定资产购置修缮费',1,'',29,1),(126,'2015-05-02 21:13:39','23','运输费',1,'',29,1),(127,'2015-05-02 21:13:49','24','包装费',1,'',29,1),(128,'2015-05-02 21:14:08','25','设备维修费',1,'',29,1),(129,'2015-05-02 21:14:33','26','技术咨询费',1,'',29,1),(130,'2015-05-02 21:14:58','27','礼品费',1,'',29,1),(131,'2015-05-02 21:15:10','28','业务招待费',1,'',29,1),(132,'2015-05-02 21:15:25','29','广告费',1,'',29,1),(133,'2015-05-02 21:19:28','30','土地房屋设备租赁费',1,'',29,1),(134,'2015-05-02 21:20:46','31','诉讼费',1,'',29,1),(135,'2015-05-02 21:21:07','32','审计费',1,'',29,1),(136,'2015-05-02 21:22:52','33','商业保险费',1,'',29,1),(137,'2015-05-02 21:23:31','34','代理服务费',1,'',29,1),(138,'2015-05-02 21:26:27','35','其他不便归类的费用',1,'',29,1),(139,'2015-05-03 06:49:41','14','岗位序列',1,'',11,1),(140,'2015-05-03 06:56:08','15','岗位级别',1,'',11,1),(141,'2015-05-03 07:08:28','13','项目类别',2,'已修改 module 。',11,1),(142,'2015-05-03 07:08:36','15','岗位级别',2,'已修改 module 。',11,1),(143,'2015-05-03 07:08:44','12','项目状态',2,'已修改 module 。',11,1),(144,'2015-05-03 07:08:51','11','地址类型',2,'已修改 module 。',11,1),(145,'2015-05-03 07:08:59','10','性别',2,'已修改 module 。',11,1),(146,'2015-05-03 07:13:31','16','人员状态',1,'',11,1),(147,'2015-05-03 07:19:43','17','职员级别',1,'',11,1),(148,'2015-05-03 07:19:50','17','职员级别',2,'已修改 module 。',11,1),(149,'2015-05-03 07:22:10','18','人员类别',1,'',11,1),(150,'2015-05-03 07:24:00','19','用工形式',1,'',11,1),(151,'2015-05-03 07:33:41','20','宗教信仰',1,'',11,1),(152,'2015-05-03 07:42:12','21','民族',1,'',11,1),(153,'2015-05-03 07:43:22','21','民族',2,'已添加 列表项 \"09-布依族\". 已添加 列表项 \"10-朝鲜族\". 已添加 列表项 \"11-满族\".',11,1),(154,'2015-05-03 07:54:20','22','国家',1,'',11,1),(155,'2015-05-03 08:00:47','23','婚姻状况',1,'',11,1),(156,'2015-05-03 08:11:20','24','文化程度',1,'',11,1),(157,'2015-05-03 08:13:18','24','文化程度',2,'已添加 列表项 \"50-高中\". 已添加 列表项 \"60-初中\". 已添加 列表项 \"70-小学\". 已添加 列表项 \"80-文盲或半文盲\".',11,1),(158,'2015-05-03 08:14:10','24','文化程度',2,'已删除 列表项 \"1-研究生毕业\". 已删除 列表项 \"11-大学毕业\". 已删除 列表项 \"18-相当大学毕业\". 已删除 列表项 \"19-大学肄业\". 已删除 列表项 \"21-专科毕业\". 已删除 列表项 \"29-专科肄业\". 已删除 列表项 \"30-中等专业学校或中等技术学校\". 已删除 列表项 \"31-中专毕业\". 已删除 列表项 \"32-中技毕业\". 已删除 列表项 \"38-相当中专或中技毕业\". 已删除 列表项 \"39-中专或中技肄业\". 已删除 列表项 \"41-技工学校毕业\".',11,1),(159,'2015-05-03 08:14:20','24','文化程度',2,'已删除 列表项 \"9-研究生肄业\".',11,1),(160,'2015-05-03 08:16:00','10','性别',2,'已删除 列表项 \"F-女\". 已删除 列表项 \"M-男\".',11,1),(161,'2015-05-03 08:16:48','10','性别',2,'已添加 列表项 \"0-未知的性别\". 已添加 列表项 \"1-男性\". 已添加 列表项 \"2-女性\". 已添加 列表项 \"9-未说明的性别\".',11,1),(162,'2015-05-03 08:26:49','25','家庭关系',1,'',11,1),(163,'2015-05-03 08:31:20','25','家庭关系',2,'已添加 列表项 \"51-父亲\". 已添加 列表项 \"52-母亲\". 已添加 列表项 \"53-公公\". 已添加 列表项 \"54-婆婆\". 已添加 列表项 \"55-岳父\". 已添加 列表项 \"56-岳母\". 已添加 列表项 \"57-继父或养父\". 已添加 列表项 \"58-继母或养母\". 已添加 列表项 \"71-兄\". 已添加 列表项 \"72-嫂\". 已添加 列表项 \"73-弟\". 已添加 列表项 \"74-弟媳\". 已添加 列表项 \"75-姐姐\". 已添加 列表项 \"76-姐夫\". 已添加 列表项 \"77-妹妹\". 已添加 列表项 \"78-妹夫\".',11,1),(164,'2015-05-03 08:32:32','21','民族',2,'已修改 module 。',11,1),(165,'2015-05-03 08:32:42','25','家庭关系',2,'已修改 module 。',11,1),(166,'2015-05-03 08:32:51','24','文化程度',2,'已修改 module 。',11,1),(167,'2015-05-03 08:33:02','23','婚姻状况',2,'已修改 module 。',11,1),(168,'2015-05-03 08:39:02','26','政治面貌',1,'',11,1),(169,'2015-05-03 08:41:44','27','兵役状况',1,'',11,1),(170,'2015-05-03 08:43:11','26','政治面貌',2,'已修改 module 。',11,1),(171,'2015-05-03 08:44:29','28','血型',1,'',11,1),(172,'2015-05-03 08:51:03','29','人员身份',1,'',11,1),(173,'2015-05-03 08:52:49','30','合同类型',1,'',11,1),(174,'2015-05-03 08:54:11','31','合同期限类型',1,'',11,1),(175,'2015-05-03 08:54:19','31','合同期限类型',2,'已修改 module 。',11,1),(176,'2015-05-03 08:55:13','32','合同密级',1,'',11,1),(177,'2015-05-03 08:56:17','33','合同变动类型',1,'',11,1),(178,'2015-05-03 08:56:32','32','合同密级',2,'已修改 module 。',11,1),(179,'2015-05-03 08:58:32','34','工时制度',1,'',11,1),(180,'2015-05-03 09:56:24','35','教育类型',1,'',11,1),(181,'2015-05-03 10:02:20','36','从学单位类别',1,'',11,1),(182,'2015-05-03 10:02:30','36','从学单位类别',2,'已删除 列表项 \"1-全日制学校\". 已删除 列表项 \"2-成人教育培训机构\".',11,1),(183,'2015-05-03 10:02:38','36','从学单位类别',2,'已修改 module 。',11,1),(184,'2015-05-03 10:13:32','37','学位',1,'',11,1),(185,'2015-05-03 10:16:17','38','专业类别',1,'',11,1),(186,'2015-05-03 10:16:48','37','学位',2,'已添加 列表项 \"9-其他\".',11,1),(187,'2015-05-03 10:17:06','38','专业类别',2,'已添加 列表项 \"99-其他\".',11,1),(188,'2015-05-03 13:41:51','39','复转军人标识',1,'',11,1),(189,'2015-05-03 14:04:26','40','党委负责人标识',1,'',11,1),(190,'2015-05-03 14:07:37','41','董事监事标识',1,'',11,1),(191,'2015-05-03 14:07:50','40','党委负责人标识',2,'已修改 module 。',11,1),(192,'2015-05-03 14:08:16','41','董事监事标识',2,'已添加 列表项 \"00-非董事监事\".',11,1),(193,'2015-05-03 14:14:35','42','特殊工种',1,'',11,1),(194,'2015-05-03 14:18:08','42','特殊工种',2,'已添加 列表项 \"41-翻砂铸造工\". 已添加 列表项 \"42-喷砂工\". 已添加 列表项 \"43-镀锌工\". 已添加 列表项 \"44-电镀工\". 已添加 列表项 \"45-印刷线路制板工\". 已添加 列表项 \"46-浸漆工\". 已添加 列表项 \"47-电焊条制作工\". 已添加 列表项 \"48-注塑工\". 已添加 列表项 \"49-铆工\". 已添加 列表项 \"51-混凝土工\". 已添加 列表项 \"52-钢筋工\". 已添加 列表项 \"53-架子工\". 已添加 列表项 \"54-推土机司机\". 已添加 列表项 \"55-挖土机司机\". 已添加 列表项 \"56-重型载重汽车司机\". 已添加 列表项 \"57-野外勘测工\". 已添加 列表项 \"58-沥青工\". 已添加 列表项 \"59-环氧树脂工\".',11,1),(195,'2015-05-03 14:21:31','43','身体状况',1,'',11,1),(196,'2015-05-03 15:12:54','19','用工形式',2,'已变更 name for 列表项 \"2-劳动合同制(短期)\".',11,1),(197,'2015-05-03 15:38:58','1','朱国良',1,'',30,1),(198,'2015-05-03 15:46:16','1','朱国良',2,'已修改 startday 。',30,1),(199,'2015-05-03 15:50:00','3','人事经理',1,'',18,1),(200,'2015-05-03 15:50:13','1','朱国良',2,'已修改 position 。',30,1),(201,'2015-05-04 22:22:18','1','朱国良',2,'已添加 家庭成员 \"陆阳\". 已添加 家庭成员 \"朱元泽\". 已添加 家庭成员 \"张艮平\". 已添加 教育履历 \" \". 已添加 教育履历 \" \". 已添加 教育履历 \" \". 已添加 工作履历 \" \". 已添加 工作履历 \" \". 已添加 工作履历 \" \".',30,1),(202,'2015-05-09 08:52:57','3','新员工入职',1,'',34,1),(203,'2015-05-09 08:58:16','1','N01-人事专员',2,'已修改 next 。',35,1),(204,'2015-05-09 08:58:53','3','N03-薪酬专员',2,'已修改 next 。',35,1),(205,'2015-05-09 08:59:07','4','N04-人事经理',2,'已修改 next 。',35,1),(206,'2015-05-09 09:00:44','1','N01-人事专员',2,'已修改 next 。',35,1),(207,'2015-05-09 09:00:53','3','N03-薪酬专员',2,'已修改 next 。',35,1),(208,'2015-05-09 09:01:02','4','N04-人事经理',2,'已修改 next 。',35,1),(209,'2015-05-09 09:01:14','4','N04-人事经理',2,'已修改 next 。',35,1),(210,'2015-05-09 09:01:21','3','N03-薪酬专员',2,'已修改 next 。',35,1),(211,'2015-05-09 09:01:30','2','N02-合同专员',2,'已修改 next 。',35,1),(212,'2015-05-09 09:01:40','1','N01-人事专员',2,'已修改 next 。',35,1),(213,'2015-05-09 09:03:53','4','合作伙伴审批',1,'',34,1),(214,'2015-05-09 09:12:50','2','N02-合同专员',2,'已修改 next 。',35,1),(215,'2015-05-09 09:12:55','5','N05-总经理',2,'已修改 next 。',35,1),(216,'2015-05-09 09:13:05','3','N03-薪酬专员',2,'已修改 next 。',35,1),(217,'2015-05-09 09:13:21','1','N01-人事专员',2,'已修改 next 。',35,1),(218,'2015-05-09 09:32:42','1','N01-人事专员',2,'已修改 next 。',35,1),(219,'2015-05-09 09:32:56','2','N02-合同专员',2,'已修改 next 。',35,1),(220,'2015-05-09 09:33:07','3','N03-薪酬专员',2,'已修改 next 。',35,1),(221,'2015-05-09 09:33:12','4','N04-人事经理',2,'已修改 next 。',35,1),(222,'2015-05-09 09:33:29','6','N01-商务主管审批',2,'已修改 next 。',35,1),(223,'2015-05-09 09:33:54','7','N02-营销总监审批',2,'已修改 next 。',35,1),(224,'2015-05-09 09:34:06','8','N03-总经理审批',2,'已修改 next 。',35,1),(225,'2015-05-09 09:57:21','4','合作伙伴审批',2,'已修改 description 。',34,1),(226,'2015-05-09 09:58:36','4','合作伙伴审批',2,'已修改 description 。',34,1),(227,'2015-05-09 10:00:03','3','新员工入职',2,'已修改 description 。',34,1),(228,'2015-05-09 15:41:55','15','岗位级别',2,'已变更 name for 列表项 \"01-员级\". 已变更 name for 列表项 \"02-初级\". 已变更 name for 列表项 \"03-中级\". 已变更 name for 列表项 \"04-高级\". 已变更 name for 列表项 \"05-专家\".',11,1),(229,'2015-05-10 07:05:46','1','合伙伙伴备案审批',1,'',34,1),(230,'2015-05-10 07:18:55','2','新员工入职流程',1,'',34,1),(231,'2015-05-10 07:19:07','1','合伙伙伴审批流程',2,'已修改 name 。',34,1),(232,'2015-05-10 07:19:25','2','新员工入职流程',2,'已修改 end 。',34,1),(233,'2015-05-10 07:32:46','2','新员工入职流程',2,'已添加 工作流节点 \"N01-合同专员\". 已添加 工作流节点 \"N02-薪酬专员\". 已添加 工作流节点 \"N03-人事经理\". 已添加 工作流节点 \"N04-总经理\".',34,1),(234,'2015-05-10 07:33:37','1','合伙伙伴审批流程',2,'已添加 工作流节点 \"N01-商务主管审批\". 已添加 工作流节点 \"N02-营销总监审批\". 已添加 工作流节点 \"N03-总经理审批\". 已添加 工作流节点 \"N04-客服部备案\".',34,1),(235,'2015-05-10 07:33:51','1','合伙伙伴审批流程',2,'已修改 end 。',34,1),(236,'2015-05-10 07:34:38','1','N01-合同专员',2,'已修改 next 。',35,1),(237,'2015-05-10 07:34:49','4','N04-总经理',2,'已修改 stop 和 approve_node 。',35,1),(238,'2015-05-10 07:35:02','3','N03-人事经理',2,'已修改 next 。',35,1),(239,'2015-05-10 07:35:11','2','N02-薪酬专员',2,'已修改 next 。',35,1),(240,'2015-05-10 08:33:44','1','合伙伙伴审批流程',2,'已修改 begin 和 end 。',34,1),(241,'2015-05-10 08:44:42','1','合伙伙伴审批流程',2,'已修改 end 。',34,1),(242,'2015-05-10 09:22:03','5','N01-商务主管审批',2,'已修改 handler 。',35,1),(243,'2015-05-10 11:50:32','4','N04-总经理',2,'没有字段被修改。',35,1),(244,'2015-05-10 12:19:39','1','新员工入职流程',1,'',34,1),(245,'2015-05-10 16:36:06','2','luy',1,'',4,1),(246,'2015-05-10 16:36:33','2','luy',2,'已修改 first_name,last_name 和 is_staff 。',4,1),(247,'2015-05-10 16:36:48','1','zhugl',2,'已修改 first_name,last_name 和 last_login 。',4,1),(248,'2015-05-10 16:37:06','2','luy',2,'已修改 email 。',4,1),(249,'2015-05-10 16:38:30','1','职员',2,'已修改 users 。',10,1),(250,'2015-05-10 16:45:01','2','陆阳',1,'',30,1),(251,'2015-05-10 16:45:33','3','陆阳',1,'',30,1),(252,'2015-05-10 16:47:38','2','陆阳',3,'',30,1),(253,'2015-05-10 16:49:49','3','陆阳',2,'已修改 phone 。',30,1),(254,'2015-05-10 16:51:24','3','陆阳',2,'已添加 家庭成员 \"朱国良\".',30,1),(255,'2015-05-10 16:51:55','3','人事经理',2,'已修改 parent 。',18,1),(256,'2015-05-10 16:53:23','1','职员',2,'已修改 status 。',10,1),(257,'2015-05-10 17:00:39','1','朱国良',2,'已修改 user 。',30,1),(258,'2015-05-10 17:00:47','3','陆阳',2,'已修改 rank 和 user 。',30,1),(259,'2015-05-10 17:02:09','1','职员',1,'',3,1),(260,'2015-05-10 17:02:25','2','luy',2,'已修改 groups 。',4,1),(261,'2015-05-10 17:04:41','3','陆阳',2,'已修改 email 。',30,2),(262,'2015-05-10 17:16:23','1','N01-合同专员',2,'已修改 next,users,positions 和 roles 。',35,1),(263,'2015-05-10 17:16:45','1','N01-合同专员',2,'已修改 departments 。',35,1),(264,'2015-05-10 20:23:14','2','ceshi',1,'',20,1),(265,'2015-05-10 20:23:30','2','ceshi',3,'',20,1),(266,'2015-05-10 20:27:50','3','test',1,'',20,1),(267,'2015-05-10 20:27:55','3','test',3,'',20,1),(268,'2015-05-13 21:10:09','13','笔记本',3,'',24,1),(269,'2015-05-13 21:10:09','12','台式机',3,'',24,1),(270,'2015-05-13 21:10:09','11','信息安全设备',3,'',24,1),(271,'2015-05-13 21:10:09','10','交换机',3,'',24,1),(272,'2015-05-13 21:10:09','9','路由器',3,'',24,1),(273,'2015-05-13 21:10:09','8','办公物资',3,'',24,1),(274,'2015-05-13 21:10:09','7','IT物资',3,'',24,1),(275,'2015-05-13 21:10:09','6','开关设备',3,'',24,1),(276,'2015-05-13 21:10:09','5','元器件',3,'',24,1),(277,'2015-05-13 21:10:09','4','生产物资',3,'',24,1),(278,'2015-05-13 21:10:09','1','物料分类',3,'',24,1),(279,'2015-05-13 21:26:12','3','TodoList object',2,'没有字段被修改。',38,1),(280,'2015-05-13 21:26:16','1','TodoList object',2,'没有字段被修改。',38,1),(281,'2015-05-13 21:26:20','4','TodoList object',2,'没有字段被修改。',38,1),(282,'2015-05-13 21:26:22','2','TodoList object',2,'没有字段被修改。',38,1),(283,'2015-05-16 17:57:31','1','职员',2,'已修改 permissions 。',3,1),(284,'2015-05-16 18:31:01','2','人事',1,'',3,1),(285,'2015-05-16 18:31:16','2','luy',2,'已修改 groups 和 last_login 。',4,1),(286,'2015-05-16 22:54:31','4','刘三姐',1,'',30,1),(287,'2015-05-16 22:56:02','4','刘三姐',2,'已修改 workday 和 startday 。',30,1),(288,'2015-05-16 22:56:39','4','刘三姐',2,'已修改 email 。',30,1),(289,'2015-05-17 09:44:58','5','郑三炮',1,'',30,1),(290,'2015-05-17 14:28:23','2','N02-薪酬专员',2,'已修改 users 。',35,1),(291,'2015-05-17 16:21:02','2','N02-薪酬专员',2,'已修改 users 。',35,1),(292,'2015-05-17 16:36:09','2','N02-薪酬专员',2,'已修改 users 。',35,1),(293,'2015-05-18 18:55:53','1','新员工入职流程',2,'已删除 工作流节点 \"N02-薪酬专员\".',34,1),(294,'2015-05-18 18:56:41','1','新员工入职流程',2,'已添加 工作流节点 \"N01-薪酬专员审批\". 已添加 工作流节点 \"N02-合同专员审批\".',34,1),(295,'2015-05-18 18:57:12','3','N01-薪酬专员审批',2,'已修改 next 和 users 。',35,1),(296,'2015-05-18 18:57:32','4','N02-合同专员审批',2,'已修改 users 。',35,1),(297,'2015-05-19 20:34:24','10','S00010',3,'',36,1),(298,'2015-05-19 20:34:42','11','S00011',3,'',36,1),(299,'2015-05-19 20:34:59','9','S00009',3,'',36,1),(300,'2015-05-19 20:35:27','8','S00008',3,'',36,1),(301,'2015-05-19 22:36:09','13','S00013',3,'',36,1),(302,'2015-05-19 22:36:23','12','S00012',3,'',36,1),(303,'2015-05-19 22:39:38','14','S00014',3,'',36,1),(304,'2015-05-19 22:45:02','16','S00016',3,'',36,1),(305,'2015-05-19 22:45:02','15','S00015',3,'',36,1),(306,'2015-05-20 05:16:49','19','S00019',3,'',36,1),(307,'2015-05-20 05:16:49','18','S00018',3,'',36,1),(308,'2015-05-20 05:16:49','17','S00017',3,'',36,1),(309,'2015-05-22 22:03:15','2','内部运营服务',1,'',20,1),(310,'2015-05-22 22:03:29','8','次',1,'',21,1),(311,'2015-05-22 22:03:36','1','出差申请',1,'',27,1),(312,'2015-05-22 22:04:57','1','出差申请',2,'已添加 extra param \"ExtraParam object\". 已添加 extra param \"ExtraParam object\". 已添加 extra param \"ExtraParam object\".',27,1),(313,'2015-05-22 22:10:07','1','出差申请',2,'已修改 can_sale 。',27,1),(314,'2015-05-22 22:10:23','1','内部服务',1,'',24,1),(315,'2015-05-22 22:10:34','1','出差申请',2,'已修改 category 。',27,1),(316,'2015-05-22 22:38:58','44','工单类型',1,'',11,1),(317,'2015-05-22 22:41:19','45','业务域',1,'',11,1),(318,'2015-05-22 22:44:49','46','工单状态',1,'',11,1),(319,'2015-05-22 22:56:20','44','工单类型',2,'已添加 列表项 \"D-采购申请\".',11,1),(320,'2015-05-22 23:58:53','1','采购一批物资',1,'',40,1),(321,'2015-05-23 00:18:58','1','采购一批物资',2,'已添加 wo item \"WOItem object\".',40,1),(322,'2015-05-23 06:23:01','1','采购一批物资',2,'没有字段被修改。',40,1),(323,'2015-05-23 06:47:06','2','WO00002-出差申请(重庆)',1,'',40,1),(324,'2015-05-23 07:13:44','2','WO00002-出差申请(重庆)',2,'已修改 description 。',40,1),(325,'2015-05-23 07:45:43','2','办公设备',1,'',24,1),(326,'2015-05-23 07:45:58','3','笔记本电脑',1,'',24,1),(327,'2015-05-23 07:46:20','9','台',1,'',21,1),(328,'2015-05-23 07:46:40','3','办公用品仓库',1,'',20,1),(329,'2015-05-23 07:47:02','2','IT00002 戴尔(DELL)Inspiron 3455-R1248 灵越23.8英寸一体电脑 ',1,'',27,1),(330,'2015-05-23 08:14:53','3','WO00003-请问如何办理公积金取款',1,'',40,1),(331,'2015-05-23 08:16:25','4','WO00004-报修:7号楼2楼男厕小便池堵塞',1,'',40,1),(332,'2015-05-23 08:16:40','3','WO00003-咨询:如何办理公积金取款',2,'已修改 title 。',40,1),(333,'2015-05-23 20:47:55','2','2015年设备维修项目',1,'',19,1),(334,'2015-05-23 20:52:29','2','小便池维修费用',1,'',44,1),(335,'2015-05-23 21:07:11','1','WO00001-采购一批物资',2,'已删除 workorder item \"WOItem object\".',40,1),(336,'2015-05-23 21:07:43','1','WO00001-采购一批物资',2,'已添加 workorder item \"WOItem object\".',40,1),(337,'2015-05-23 21:33:34','3','礼金费用',1,'',44,1),(338,'2015-05-23 21:37:11','3','礼金费用',2,'已修改 wo 和 org 。',44,1),(339,'2015-05-23 21:37:28','3','礼金费用',2,'已添加 费用明细 \"ReimbursementItem object\".',44,1),(340,'2015-05-23 21:38:25','3','礼金费用',2,'没有字段被修改。',44,1),(341,'2015-05-23 21:38:56','3','2015年人事行政费用项目',1,'',19,1),(342,'2015-05-23 21:40:02','4','独生子女费',1,'',44,1),(343,'2015-05-23 21:41:31','4','独生子女费',2,'没有字段被修改。',44,1),(344,'2015-05-23 22:19:38','7','测试',1,'',44,1),(345,'2015-05-23 22:24:29','8','测试2',1,'',44,1),(346,'2015-05-23 22:26:00','7','测试',3,'',44,1),(347,'2015-05-23 22:31:18','8','测试2',2,'已修改 description 。',44,1),(348,'2015-05-23 22:31:54','8','测试2',2,'已修改 description 。',44,1),(349,'2015-05-23 22:34:53','8','测试2',2,'已修改 description 。',44,1),(350,'2015-05-23 22:39:04','8','测试2',2,'已修改 description 。',44,1),(351,'2015-05-23 22:44:42','9','xxx测试',1,'',44,1),(352,'2015-05-24 08:00:01','3','zhangliangjun',1,'',4,1),(353,'2015-05-24 08:00:36','3','zhangliangjun',2,'已修改 first_name,last_name,is_staff 和 groups 。',4,1),(354,'2015-05-24 08:00:54','3','zhangliangjun',2,'已修改 email 。',4,1),(355,'2015-05-24 08:01:40','1','职员',2,'已修改 permissions 。',3,1),(356,'2015-05-24 08:03:53','1','职员',2,'已修改 permissions 。',3,1),(357,'2015-05-24 15:13:47','3','IT00003 用车申请',1,'',27,1),(358,'2015-05-24 15:14:11','3','IT00003 用车申请',2,'已修改 category 。',27,1),(359,'2015-05-24 15:15:09','5','WO00005-接送X集团客户',1,'',40,1),(360,'2015-05-24 19:02:34','1','朱国良',2,'已修改 banknum 和 bankname 。',30,1),(361,'2015-05-24 20:02:43','3','人力资源',1,'',8,1),(362,'2015-05-24 20:04:37','47','试用期',1,'',11,1),(363,'2015-05-24 20:05:21','47','试用期',2,'已变更 weight for 列表项 \"0-无试用期\". 已变更 weight for 列表项 \"1-1个月\". 已变更 weight for 列表项 \"12-1年\". 已变更 weight for 列表项 \"2-2个月\". 已变更 weight for 列表项 \"3-3个月\". 已变更 weight for 列表项 \"4-4个月\". 已变更 weight for 列表项 \"5-5个月\". 已变更 weight for 列表项 \"6-6个月\".',11,1),(364,'2015-05-24 20:06:09','47','试用期',2,'已修改 init 和 locked 。',11,1),(365,'2015-05-24 20:07:15','4','个人自助',1,'',8,1),(366,'2015-05-24 20:07:18','46','工单状态',2,'已修改 module 。',11,1),(367,'2015-05-24 20:07:28','45','业务域',2,'已修改 module 。',11,1),(368,'2015-05-24 20:11:06','48','工资项类别',1,'',11,1),(369,'2015-05-24 20:13:08','49','增减属性',1,'',11,1),(370,'2015-05-24 20:13:15','49','增减属性',2,'已修改 module 。',11,1),(371,'2015-05-24 20:20:10','50','计算方式',1,'',11,1),(372,'2015-05-24 20:20:18','50','计算方式',2,'已修改 module 。',11,1),(373,'2015-05-24 20:25:36','50','计算方式',2,'已删除 列表项 \"30-计算值\".',11,1),(374,'2015-05-24 20:37:22','50','计算方式',2,'已添加 列表项 \"30-计算值\".',11,1),(375,'2015-05-24 21:32:21','51','离职类别',1,'',11,1),(376,'2015-05-24 21:32:31','51','离职类别',2,'已修改 module 。',11,1),(377,'2015-05-24 22:55:18','1','SalaryItem object',1,'',46,1),(378,'2015-05-24 22:57:49','2','1002 岗位工资',1,'',46,1),(379,'2015-05-24 22:57:57','3','1003 学历工资',1,'',46,1),(380,'2015-05-24 23:01:31','4','1004 工龄工资',1,'',46,1),(381,'2015-05-24 23:02:31','5','2001 养老保险',1,'',46,1),(382,'2015-05-24 23:02:48','6','2002 医疗保险',1,'',46,1),(383,'2015-05-24 23:03:06','7','2003 失业保险',1,'',46,1),(384,'2015-05-24 23:03:23','8','2004 工伤保险',1,'',46,1),(385,'2015-05-24 23:03:41','9','2005 生育保险',1,'',46,1),(386,'2015-05-24 23:03:57','10','2006 住房公积金',1,'',46,1),(387,'2015-05-24 23:05:06','11','3001 年终奖',1,'',46,1),(388,'2015-05-24 23:05:17','12','3002 销售佣金',1,'',46,1),(389,'2015-05-24 23:05:53','13','3003 人才推荐奖金',1,'',46,1),(390,'2015-05-24 23:06:48','14','4001 住房补贴',1,'',46,1),(391,'2015-05-24 23:07:12','15','4002 交通补贴',1,'',46,1),(392,'2015-05-24 23:07:33','16','4003 取暖补贴',1,'',46,1),(393,'2015-05-24 23:07:45','17','4004 高温费',1,'',46,1),(394,'2015-05-24 23:09:58','16','4003 暖气费',2,'已修改 name 。',46,1),(395,'2015-05-24 23:14:14','18','9001 考勤扣款',1,'',46,1),(396,'2015-05-24 23:14:51','19','9002 请假扣款',1,'',46,1),(397,'2015-05-24 23:16:05','20','9003 个人所得税',1,'',46,1),(398,'2015-05-24 23:16:40','21','9004 违规罚款',1,'',46,1),(399,'2015-05-24 23:17:53','13','3003 伯乐奖',2,'已修改 name 。',46,1),(400,'2015-05-25 20:10:20','1','1001 基本工资',2,'已修改 required 。',46,1),(401,'2015-05-25 20:10:26','2','1002 岗位工资',2,'已修改 required 。',46,1),(402,'2015-05-25 20:10:30','3','1003 学历工资',2,'已修改 required 。',46,1),(403,'2015-05-25 20:10:36','4','1004 工龄工资',2,'已修改 required 。',46,1),(404,'2015-05-25 20:10:42','5','2001 养老保险',2,'已修改 required 。',46,1),(405,'2015-05-25 20:10:47','6','2002 医疗保险',2,'已修改 required 。',46,1),(406,'2015-05-25 20:11:00','7','2003 失业保险',2,'已修改 required 。',46,1),(407,'2015-05-25 20:11:08','8','2004 工伤保险',2,'已修改 required 。',46,1),(408,'2015-05-25 20:11:54','9','2005 生育保险',2,'已修改 required 。',46,1),(409,'2015-05-25 20:11:58','10','2006 住房公积金',2,'已修改 required 。',46,1),(410,'2015-05-25 20:26:31','45','业务域',2,'已添加 列表项 \"PO-采购\".',11,1),(411,'2015-05-25 20:26:41','45','业务域',2,'已变更 weight for 列表项 \"AD-行政\".',11,1),(412,'2015-05-25 20:58:34','44','工单类型',2,'已变更 name for 列表项 \"S-内部服务\".',11,1),(413,'2015-05-25 21:02:27','5','WO00005-接送X集团客户',2,'已修改 refer 。',40,1),(414,'2015-05-25 21:04:38','5','WO00005-接送X集团客户',2,'已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\".',40,1),(415,'2015-05-25 21:06:11','5','WO00005-接送X集团客户',2,'已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\". 已删除 扩展信息 \"WOExtraValue object\".',40,1),(416,'2015-05-25 21:10:10','9','xxx测试',2,'已修改 wo 。',44,1),(417,'2015-05-25 21:52:22','4','IT主管',1,'',18,1),(418,'2015-05-25 21:55:27','1','周树锋',1,'',47,1),(419,'2015-05-25 21:56:11','1','周树锋',2,'已添加 工资项 \"EmployeeSalaryItem object\".',47,1); + +/*Table structure for table `django_content_type` */ + +DROP TABLE IF EXISTS `django_content_type`; + +CREATE TABLE `django_content_type` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `app_label` varchar(100) NOT NULL, + `model` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `django_content_type_app_label_3ec8c61c_uniq` (`app_label`,`model`) +) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8; + +/*Data for the table `django_content_type` */ + +insert into `django_content_type`(`id`,`app_label`,`model`) values (1,'admin','logentry'),(3,'auth','group'),(2,'auth','permission'),(4,'auth','user'),(13,'basedata','address'),(15,'basedata','bankaccount'),(23,'basedata','brand'),(24,'basedata','category'),(32,'basedata','education'),(30,'basedata','employee'),(29,'basedata','expenseaccount'),(39,'basedata','extraparam'),(31,'basedata','family'),(27,'basedata','material'),(28,'basedata','materialparam'),(21,'basedata','measure'),(14,'basedata','partner'),(19,'basedata','project'),(25,'basedata','technicalparametername'),(26,'basedata','technicalparametervalue'),(22,'basedata','trade'),(11,'basedata','valuelist'),(12,'basedata','valuelistitem'),(20,'basedata','warehouse'),(33,'basedata','workexperience'),(5,'contenttypes','contenttype'),(50,'hr','departure'),(48,'hr','employeesalaryitem'),(47,'hr','entry'),(46,'hr','salaryitem'),(49,'hr','transfer'),(16,'organ','organization'),(17,'organ','orgunit'),(18,'organ','position'),(43,'selfhelp','loan'),(44,'selfhelp','reimbursement'),(45,'selfhelp','reimbursementitem'),(41,'selfhelp','woextravalue'),(42,'selfhelp','woitem'),(40,'selfhelp','workorder'),(6,'sessions','session'),(9,'syscfg','menu'),(8,'syscfg','module'),(10,'syscfg','role'),(7,'syscfg','site'),(37,'workflow','history'),(36,'workflow','instance'),(34,'workflow','modal'),(35,'workflow','node'),(38,'workflow','todolist'); + +/*Table structure for table `django_migrations` */ + +DROP TABLE IF EXISTS `django_migrations`; + +CREATE TABLE `django_migrations` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `app` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `applied` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8; + +/*Data for the table `django_migrations` */ + +insert into `django_migrations`(`id`,`app`,`name`,`applied`) values (1,'contenttypes','0001_initial','2015-05-01 07:28:26'),(2,'auth','0001_initial','2015-05-01 07:28:26'),(3,'admin','0001_initial','2015-05-01 07:28:26'),(4,'contenttypes','0002_remove_content_type_name','2015-05-01 07:28:26'),(5,'auth','0002_alter_permission_name_max_length','2015-05-01 07:28:26'),(6,'auth','0003_alter_user_email_max_length','2015-05-01 07:28:26'),(7,'auth','0004_alter_user_username_opts','2015-05-01 07:28:26'),(8,'auth','0005_alter_user_last_login_null','2015-05-01 07:28:26'),(9,'auth','0006_require_contenttypes_0002','2015-05-01 07:28:26'),(10,'sessions','0001_initial','2015-05-01 07:28:26'),(11,'syscfg','0001_initial','2015-05-01 07:28:27'),(12,'basedata','0001_initial','2015-05-01 09:25:30'),(13,'basedata','0002_auto_20150501_0929','2015-05-01 09:30:01'),(14,'basedata','0003_auto_20150501_0931','2015-05-01 09:31:07'),(15,'basedata','0004_address','2015-05-01 10:52:00'),(16,'basedata','0005_auto_20150501_1121','2015-05-01 11:21:30'),(17,'basedata','0006_partner','2015-05-01 12:02:16'),(18,'basedata','0007_bankaccount','2015-05-01 15:35:20'),(19,'basedata','0008_auto_20150501_1547','2015-05-01 15:48:03'),(20,'organ','0001_initial','2015-05-01 19:14:41'),(21,'organ','0002_auto_20150501_2036','2015-05-01 20:36:43'),(22,'organ','0003_auto_20150501_2045','2015-05-01 20:46:03'),(23,'basedata','0009_auto_20150502_0817','2015-05-02 08:17:55'),(24,'basedata','0010_auto_20150502_0851','2015-05-02 08:51:53'),(25,'basedata','0011_auto_20150502_0934','2015-05-02 09:34:17'),(26,'basedata','0012_auto_20150502_0946','2015-05-02 09:46:24'),(27,'basedata','0013_auto_20150502_1311','2015-05-02 13:11:33'),(28,'basedata','0014_auto_20150502_1314','2015-05-02 13:14:16'),(29,'basedata','0015_brand_weight','2015-05-02 13:21:10'),(30,'basedata','0016_auto_20150502_1402','2015-05-02 14:04:33'),(31,'basedata','0017_auto_20150502_1731','2015-05-02 17:31:10'),(32,'basedata','0018_auto_20150502_2100','2015-05-02 21:00:06'),(33,'organ','0004_auto_20150503_1445','2015-05-03 14:46:12'),(34,'basedata','0019_auto_20150503_1445','2015-05-03 14:46:12'),(35,'basedata','0020_auto_20150503_1501','2015-05-03 15:01:41'),(36,'basedata','0021_auto_20150503_1518','2015-05-03 15:18:14'),(37,'basedata','0022_auto_20150503_1538','2015-05-03 15:38:24'),(38,'basedata','0023_auto_20150504_2120','2015-05-04 21:20:32'),(39,'basedata','0024_education_family_workexperience','2015-05-04 21:59:53'),(44,'organ','0005_auto_20150510_1141','2015-05-10 11:41:46'),(49,'workflow','0001_initial','2015-05-10 12:18:40'),(50,'workflow','0002_auto_20150513_2124','2015-05-13 21:24:50'),(51,'basedata','0025_auto_20150516_1829','2015-05-16 18:30:12'),(52,'basedata','0026_extraparam','2015-05-22 22:01:36'),(53,'selfhelp','0001_initial','2015-05-22 23:06:19'),(54,'selfhelp','0002_auto_20150522_2330','2015-05-22 23:30:14'),(55,'selfhelp','0003_auto_20150523_0621','2015-05-23 06:21:46'),(56,'basedata','0027_auto_20150523_2007','2015-05-23 20:07:34'),(57,'selfhelp','0004_auto_20150523_2007','2015-05-23 20:07:35'),(58,'selfhelp','0005_auto_20150523_2031','2015-05-23 20:31:54'),(59,'selfhelp','0006_auto_20150523_2050','2015-05-23 20:50:08'),(60,'selfhelp','0007_auto_20150523_2052','2015-05-23 20:52:17'),(61,'selfhelp','0008_auto_20150523_2133','2015-05-23 21:33:23'),(62,'selfhelp','0009_auto_20150523_2146','2015-05-23 21:46:15'),(65,'workflow','0003_auto_20150524_2208','2015-05-24 22:23:11'),(67,'hr','0001_initial','2015-05-25 22:12:43'),(68,'selfhelp','0010_auto_20150525_2255','2015-05-25 22:55:20'); + +/*Table structure for table `django_session` */ + +DROP TABLE IF EXISTS `django_session`; + +CREATE TABLE `django_session` ( + `session_key` varchar(40) NOT NULL, + `session_data` longtext NOT NULL, + `expire_date` datetime NOT NULL, + PRIMARY KEY (`session_key`), + KEY `django_session_de54fa62` (`expire_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `django_session` */ + +insert into `django_session`(`session_key`,`session_data`,`expire_date`) values ('2rdw4agh630yjfqhy14jie3dgzhi8v8i','OGEyMjM1MDM3YmU1ZmE4NjYxNmIzOWE5MTY3NjYzZjhhNDUyMWQxMDp7Il9hdXRoX3VzZXJfaGFzaCI6IjUzODFkNDg2MjM0YTlmMTQ0YjBkM2Y4ZWY4NWNmMDZlMmRkYjE1MWMiLCJfYXV0aF91c2VyX2JhY2tlbmQiOiJkamFuZ28uY29udHJpYi5hdXRoLmJhY2tlbmRzLk1vZGVsQmFja2VuZCIsIl9hdXRoX3VzZXJfaWQiOiIxIn0=','2015-05-16 08:18:20'),('bffad131mfdzd3ti0eat4ixwbaedqqfn','OGEyMjM1MDM3YmU1ZmE4NjYxNmIzOWE5MTY3NjYzZjhhNDUyMWQxMDp7Il9hdXRoX3VzZXJfaGFzaCI6IjUzODFkNDg2MjM0YTlmMTQ0YjBkM2Y4ZWY4NWNmMDZlMmRkYjE1MWMiLCJfYXV0aF91c2VyX2JhY2tlbmQiOiJkamFuZ28uY29udHJpYi5hdXRoLmJhY2tlbmRzLk1vZGVsQmFja2VuZCIsIl9hdXRoX3VzZXJfaWQiOiIxIn0=','2015-05-15 07:39:11'),('nwfmn1dz9wc0p72yy5h8p1xs289a43e3','OGEyMjM1MDM3YmU1ZmE4NjYxNmIzOWE5MTY3NjYzZjhhNDUyMWQxMDp7Il9hdXRoX3VzZXJfaGFzaCI6IjUzODFkNDg2MjM0YTlmMTQ0YjBkM2Y4ZWY4NWNmMDZlMmRkYjE1MWMiLCJfYXV0aF91c2VyX2JhY2tlbmQiOiJkamFuZ28uY29udHJpYi5hdXRoLmJhY2tlbmRzLk1vZGVsQmFja2VuZCIsIl9hdXRoX3VzZXJfaWQiOiIxIn0=','2015-06-07 08:33:50'); + +/*Table structure for table `hr_departure` */ + +DROP TABLE IF EXISTS `hr_departure`; + +CREATE TABLE `hr_departure` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `employee_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `hr_departure_employee_id_cd15087_fk_basedata_employee_id` (`employee_id`), + CONSTRAINT `hr_departure_employee_id_cd15087_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `hr_departure` */ + +/*Table structure for table `hr_employeesalaryitem` */ + +DROP TABLE IF EXISTS `hr_employeesalaryitem`; + +CREATE TABLE `hr_employeesalaryitem` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `calculate_way` varchar(2) NOT NULL, + `fixed_value` decimal(10,2) DEFAULT NULL, + `base_value` decimal(10,2) DEFAULT NULL, + `org_percent` decimal(4,2) DEFAULT NULL, + `employee_percent` decimal(4,2) DEFAULT NULL, + `employee_id` int(11) DEFAULT NULL, + `entry_id` int(11) NOT NULL, + `salary_item_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `hr_employeesalaryitem_entry_id_3a7aa921_uniq` (`entry_id`,`salary_item_id`), + KEY `hr_employeesalaryit_employee_id_3ca63cb3_fk_basedata_employee_id` (`employee_id`), + KEY `hr_employeesalaryitem_b64a62ea` (`entry_id`), + KEY `hr_employeesalaryitem_dc6d0554` (`salary_item_id`), + CONSTRAINT `hr_employeesalaryitem_entry_id_24d5804c_fk_hr_entry_id` FOREIGN KEY (`entry_id`) REFERENCES `hr_entry` (`id`), + CONSTRAINT `hr_employeesalaryite_salary_item_id_308f4922_fk_hr_salaryitem_id` FOREIGN KEY (`salary_item_id`) REFERENCES `hr_salaryitem` (`id`), + CONSTRAINT `hr_employeesalaryit_employee_id_3ca63cb3_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `hr_employeesalaryitem` */ + +/*Table structure for table `hr_entry` */ + +DROP TABLE IF EXISTS `hr_entry`; + +CREATE TABLE `hr_entry` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `birthday` date DEFAULT NULL, + `gender` varchar(2) NOT NULL, + `idcard` varchar(20) NOT NULL, + `address` varchar(120) DEFAULT NULL, + `zipcode` varchar(8) NOT NULL, + `phone` varchar(20) DEFAULT NULL, + `rank` varchar(2) NOT NULL, + `ygxs` varchar(2) DEFAULT NULL, + `category` varchar(2) DEFAULT NULL, + `probation_months` varchar(2) NOT NULL, + `probation_begin` date NOT NULL, + `probation_end` date DEFAULT NULL, + `memo` longtext, + `profile` varchar(100) DEFAULT NULL, + `guider_id` int(11) NOT NULL, + `position_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `hr_entry_guider_id_677409a1_fk_basedata_employee_id` (`guider_id`), + KEY `hr_entry_position_id_70f8683c_fk_organ_position_id` (`position_id`), + CONSTRAINT `hr_entry_guider_id_677409a1_fk_basedata_employee_id` FOREIGN KEY (`guider_id`) REFERENCES `basedata_employee` (`id`), + CONSTRAINT `hr_entry_position_id_70f8683c_fk_organ_position_id` FOREIGN KEY (`position_id`) REFERENCES `organ_position` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `hr_entry` */ + +/*Table structure for table `hr_salaryitem` */ + +DROP TABLE IF EXISTS `hr_salaryitem`; + +CREATE TABLE `hr_salaryitem` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(10) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `classification` varchar(2) NOT NULL, + `plus_or_minus` varchar(2) NOT NULL, + `required` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `hr_salaryitem` */ + +/*Table structure for table `hr_transfer` */ + +DROP TABLE IF EXISTS `hr_transfer`; + +CREATE TABLE `hr_transfer` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `employee_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `hr_transfer_employee_id_58f1c915_fk_basedata_employee_id` (`employee_id`), + CONSTRAINT `hr_transfer_employee_id_58f1c915_fk_basedata_employee_id` FOREIGN KEY (`employee_id`) REFERENCES `basedata_employee` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `hr_transfer` */ + +/*Table structure for table `organ_organization` */ + +DROP TABLE IF EXISTS `organ_organization`; + +CREATE TABLE `organ_organization` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(20) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `short` varchar(20) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `status` tinyint(1) NOT NULL, + `tax_num` varchar(40) DEFAULT NULL, + `tax_address` varchar(40) DEFAULT NULL, + `tax_account` varchar(80) DEFAULT NULL, + `represent` varchar(40) DEFAULT NULL, + `address` varchar(120) DEFAULT NULL, + `zipcode` varchar(8) DEFAULT NULL, + `fax` varchar(20) DEFAULT NULL, + `contacts` varchar(40) DEFAULT NULL, + `phone` varchar(40) DEFAULT NULL, + `website` varchar(40) DEFAULT NULL, + `email` varchar(40) DEFAULT NULL, + `lic_code` varchar(40) DEFAULT NULL, + `cer_code` varchar(40) DEFAULT NULL, + `license` varchar(100) DEFAULT NULL, + `certificate` varchar(100) DEFAULT NULL, + `weight` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `organ_organization` */ + +insert into `organ_organization`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`short`,`pinyin`,`status`,`tax_num`,`tax_address`,`tax_account`,`represent`,`address`,`zipcode`,`fax`,`contacts`,`phone`,`website`,`email`,`lic_code`,`cer_code`,`license`,`certificate`,`weight`) values (1,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 20:26:05','2015-05-01 21:06:40','O01','上海机场(集团)有限公司','上海机场','Shanghai Airport',1,'310120000001357','上海市浦东机场启航路900号','交通银行上海分行浦东支行','李德润','上海市肇嘉浜路301号','200032','021-58698201','王勇','021-58698202','www.shairport.com','webadmin@sgs.gov.cn','310120000001357','20120620102952945','','',9); + +/*Table structure for table `organ_orgunit` */ + +DROP TABLE IF EXISTS `organ_orgunit`; + +CREATE TABLE `organ_orgunit` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(8) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `short` varchar(20) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `unit_type` int(11) NOT NULL, + `status` tinyint(1) NOT NULL, + `virtual` tinyint(1) NOT NULL, + `fax` varchar(20) DEFAULT NULL, + `phone` varchar(40) DEFAULT NULL, + `contacts` varchar(40) DEFAULT NULL, + `email` varchar(40) DEFAULT NULL, + `weight` int(11) NOT NULL, + `organization_id` int(11) DEFAULT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `organ_orgunit_organization_id_56741454_fk_organ_organization_id` (`organization_id`), + KEY `organ_orgunit_parent_id_20b497af_fk_organ_orgunit_id` (`parent_id`), + CONSTRAINT `organ_orgunit_organization_id_56741454_fk_organ_organization_id` FOREIGN KEY (`organization_id`) REFERENCES `organ_organization` (`id`), + CONSTRAINT `organ_orgunit_parent_id_20b497af_fk_organ_orgunit_id` FOREIGN KEY (`parent_id`) REFERENCES `organ_orgunit` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `organ_orgunit` */ + +insert into `organ_orgunit`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`short`,`pinyin`,`unit_type`,`status`,`virtual`,`fax`,`phone`,`contacts`,`email`,`weight`,`organization_id`,`parent_id`) values (1,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 20:27:41','2015-05-01 20:27:41','S001','董事会','','',2,1,1,'','','','',99,1,NULL),(2,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 20:27:55','2015-05-01 20:27:55','S002','集团财务部','','',2,1,0,'','','','',99,1,NULL),(3,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 20:28:12','2015-05-01 20:28:12','S003','人事行政部','','',2,1,0,'','','','',99,1,NULL),(4,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 20:29:49','2015-05-01 20:29:49','S004','人事部','','',3,1,0,'','','','',99,1,3),(5,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 20:33:18','2015-05-01 20:34:06','S005','行政部','','',3,1,0,'','','','',99,1,3); + +/*Table structure for table `organ_position` */ + +DROP TABLE IF EXISTS `organ_position`; + +CREATE TABLE `organ_position` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(8) DEFAULT NULL, + `name` varchar(120) NOT NULL, + `short` varchar(20) DEFAULT NULL, + `pinyin` varchar(120) DEFAULT NULL, + `series` varchar(1) NOT NULL, + `grade` varchar(2) DEFAULT NULL, + `virtual` tinyint(1) NOT NULL, + `description` longtext, + `qualification` longtext, + `document` varchar(100) DEFAULT NULL, + `weight` int(11) NOT NULL, + `parent_id` int(11) DEFAULT NULL, + `unit_id` int(11) NOT NULL, + `organization_id` int(11), + `status` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + KEY `organ_position_parent_id_1d9e732d_fk_organ_position_id` (`parent_id`), + KEY `organ_position_unit_id_411e3ee9_fk_organ_orgunit_id` (`unit_id`), + KEY `organ_position_26b2345e` (`organization_id`), + CONSTRAINT `organ_position_organization_id_3435c72a_fk_organ_organization_id` FOREIGN KEY (`organization_id`) REFERENCES `organ_organization` (`id`), + CONSTRAINT `organ_position_parent_id_1d9e732d_fk_organ_position_id` FOREIGN KEY (`parent_id`) REFERENCES `organ_position` (`id`), + CONSTRAINT `organ_position_unit_id_411e3ee9_fk_organ_orgunit_id` FOREIGN KEY (`unit_id`) REFERENCES `organ_orgunit` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +/*Data for the table `organ_position` */ + +insert into `organ_position`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`short`,`pinyin`,`series`,`grade`,`virtual`,`description`,`qualification`,`document`,`weight`,`parent_id`,`unit_id`,`organization_id`,`status`) values (2,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 20:47:51','2015-05-01 20:48:05','P0002','董事长','','','A','05',0,'','','',99,NULL,1,1,1),(3,'2015-05-03','9999-12-31','zhugl','zhugl','2015-05-03 15:50:00','2015-05-10 16:51:55','P0003','人事经理','','','A','02',0,'','','',99,2,4,1,1),(4,'2015-05-25','9999-12-31','zhugl',NULL,'2015-05-25 21:52:22','2015-05-25 21:52:22','P0004','IT主管','','','A','02',0,'','','',99,NULL,5,1,1); + +/*Table structure for table `selfhelp_loan` */ + +DROP TABLE IF EXISTS `selfhelp_loan`; + +CREATE TABLE `selfhelp_loan` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(10) DEFAULT NULL, + `title` varchar(120) NOT NULL, + `status` varchar(2) DEFAULT NULL, + `logout_time` datetime DEFAULT NULL, + `loan_amount` decimal(10,2) NOT NULL, + `logout_amount` decimal(10,2) NOT NULL, + `project_id` int(11) NOT NULL, + `user_id` int(11) DEFAULT NULL, + `description` longtext, + PRIMARY KEY (`id`), + KEY `selfhelp_loan_project_id_7b541607_fk_basedata_project_id` (`project_id`), + KEY `selfhelp_loan_user_id_1d36464e_fk_auth_user_id` (`user_id`), + CONSTRAINT `selfhelp_loan_project_id_7b541607_fk_basedata_project_id` FOREIGN KEY (`project_id`) REFERENCES `basedata_project` (`id`), + CONSTRAINT `selfhelp_loan_user_id_1d36464e_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_loan` */ + +/*Table structure for table `selfhelp_reimbursement` */ + +DROP TABLE IF EXISTS `selfhelp_reimbursement`; + +CREATE TABLE `selfhelp_reimbursement` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(10) DEFAULT NULL, + `title` varchar(120) NOT NULL, + `bank_account` varchar(120) DEFAULT NULL, + `status` varchar(2) DEFAULT NULL, + `amount` decimal(10,2) DEFAULT NULL, + `loan_amount` decimal(10,2) DEFAULT NULL, + `logout_amount` decimal(10,2) DEFAULT NULL, + `pay_amount` decimal(10,2) DEFAULT NULL, + `pay_time` datetime DEFAULT NULL, + `loan_id` int(11) DEFAULT NULL, + `org_id` int(11) DEFAULT NULL, + `project_id` int(11) NOT NULL, + `user_id` int(11) DEFAULT NULL, + `wo_id` int(11) DEFAULT NULL, + `description` longtext, + PRIMARY KEY (`id`), + KEY `selfhelp_reimbursement_org_id_1e6a35f_fk_organ_orgunit_id` (`org_id`), + KEY `selfhelp_reimbursement_project_id_ed3db4e_fk_basedata_project_id` (`project_id`), + KEY `selfhelp_reimbursement_user_id_5d122f07_fk_auth_user_id` (`user_id`), + KEY `selfhelp_reimbursement_wo_id_ac8ed7a_fk_selfhelp_workorder_id` (`wo_id`), + KEY `selfhelp_reimbursement_loan_id_44fd1f10_fk_selfhelp_loan_id` (`loan_id`), + CONSTRAINT `selfhelp_reimbursement_loan_id_44fd1f10_fk_selfhelp_loan_id` FOREIGN KEY (`loan_id`) REFERENCES `selfhelp_loan` (`id`), + CONSTRAINT `selfhelp_reimbursement_org_id_1e6a35f_fk_organ_orgunit_id` FOREIGN KEY (`org_id`) REFERENCES `organ_orgunit` (`id`), + CONSTRAINT `selfhelp_reimbursement_project_id_ed3db4e_fk_basedata_project_id` FOREIGN KEY (`project_id`) REFERENCES `basedata_project` (`id`), + CONSTRAINT `selfhelp_reimbursement_user_id_5d122f07_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`), + CONSTRAINT `selfhelp_reimbursement_wo_id_ac8ed7a_fk_selfhelp_workorder_id` FOREIGN KEY (`wo_id`) REFERENCES `selfhelp_workorder` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_reimbursement` */ + +insert into `selfhelp_reimbursement`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`title`,`bank_account`,`status`,`amount`,`loan_amount`,`logout_amount`,`pay_amount`,`pay_time`,`loan_id`,`org_id`,`project_id`,`user_id`,`wo_id`,`description`) values (2,'2015-05-23','9999-12-31','zhugl',NULL,'2015-05-23 20:52:29','2015-05-23 20:52:29','BX00002','小便池维修费用','','N','32.00',NULL,NULL,NULL,NULL,NULL,5,2,NULL,4,NULL),(3,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 21:33:34','2015-05-23 21:38:25','BX00003','礼金费用','','N','1000.00',NULL,NULL,NULL,NULL,NULL,3,2,NULL,3,NULL),(4,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 21:40:02','2015-05-23 21:41:31','BX00004','独生子女费','','N','4200.00',NULL,NULL,NULL,NULL,NULL,3,3,NULL,NULL,NULL),(8,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 22:24:29','2015-05-23 22:39:04','BX00008','测试2',NULL,'N','35.00',NULL,NULL,NULL,NULL,NULL,4,1,NULL,NULL,'234567'),(9,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 22:44:42','2015-05-25 21:10:10','BX00009','xxx测试',NULL,'N','1965.00',NULL,NULL,NULL,NULL,NULL,4,3,NULL,2,''); + +/*Table structure for table `selfhelp_reimbursementitem` */ + +DROP TABLE IF EXISTS `selfhelp_reimbursementitem`; + +CREATE TABLE `selfhelp_reimbursementitem` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date NOT NULL, + `amount` decimal(10,2) NOT NULL, + `memo` varchar(40) DEFAULT NULL, + `expense_account_id` int(11) NOT NULL, + `reimbursement_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `selfhelp__reimbursement_id_37efbf0e_fk_selfhelp_reimbursement_id` (`reimbursement_id`), + KEY `selfhe_expense_account_id_65c44030_fk_basedata_expenseaccount_id` (`expense_account_id`), + CONSTRAINT `selfhelp__reimbursement_id_37efbf0e_fk_selfhelp_reimbursement_id` FOREIGN KEY (`reimbursement_id`) REFERENCES `selfhelp_reimbursement` (`id`), + CONSTRAINT `selfhe_expense_account_id_65c44030_fk_basedata_expenseaccount_id` FOREIGN KEY (`expense_account_id`) REFERENCES `basedata_expenseaccount` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_reimbursementitem` */ + +insert into `selfhelp_reimbursementitem`(`id`,`begin`,`amount`,`memo`,`expense_account_id`,`reimbursement_id`) values (1,'2015-05-23','32.00','',22,2),(2,'2015-05-23','500.00','',12,3),(3,'2015-05-23','500.00','',13,3),(4,'2015-05-23','3200.00','100元每人,合计32人',15,4),(5,'2015-05-23','1000.00','2人亲属去世,合计1000元',14,4),(6,'2015-05-23','12.00','',23,8),(7,'2015-05-23','23.00','',24,8),(8,'2015-05-23','320.00','',29,9),(9,'2015-05-23','126.00','',11,9),(10,'2015-05-23','123.00','',10,9),(11,'2015-05-23','521.00','',28,9),(12,'2015-05-23','875.00','',27,9); + +/*Table structure for table `selfhelp_woextravalue` */ + +DROP TABLE IF EXISTS `selfhelp_woextravalue`; + +CREATE TABLE `selfhelp_woextravalue` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `param_value` varchar(40) DEFAULT NULL, + `param_name_id` int(11) NOT NULL, + `workorder_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `selfhelp_woextr_param_name_id_34779449_fk_basedata_extraparam_id` (`param_name_id`), + KEY `selfhelp_woextravalue_be2c0a1b` (`workorder_id`), + CONSTRAINT `selfhelp_woextrav_workorder_id_781e29d2_fk_selfhelp_workorder_id` FOREIGN KEY (`workorder_id`) REFERENCES `selfhelp_workorder` (`id`), + CONSTRAINT `selfhelp_woextr_param_name_id_34779449_fk_basedata_extraparam_id` FOREIGN KEY (`param_name_id`) REFERENCES `basedata_extraparam` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_woextravalue` */ + +insert into `selfhelp_woextravalue`(`id`,`param_value`,`param_name_id`,`workorder_id`) values (1,NULL,1,2),(2,NULL,2,2),(3,NULL,3,2),(4,NULL,4,5),(5,NULL,5,5),(6,NULL,6,5),(7,NULL,7,5); + +/*Table structure for table `selfhelp_woitem` */ + +DROP TABLE IF EXISTS `selfhelp_woitem`; + +CREATE TABLE `selfhelp_woitem` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `amount` decimal(10,4) DEFAULT NULL, + `price` decimal(10,4) DEFAULT NULL, + `material_id` int(11) DEFAULT NULL, + `workorder_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `selfhelp_woitem_material_id_34e897bf_fk_basedata_material_id` (`material_id`), + KEY `selfhelp_woitem_be2c0a1b` (`workorder_id`), + CONSTRAINT `selfhelp_woitem_material_id_34e897bf_fk_basedata_material_id` FOREIGN KEY (`material_id`) REFERENCES `basedata_material` (`id`), + CONSTRAINT `selfhelp_woitem_workorder_id_6a435420_fk_selfhelp_workorder_id` FOREIGN KEY (`workorder_id`) REFERENCES `selfhelp_workorder` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_woitem` */ + +insert into `selfhelp_woitem`(`id`,`amount`,`price`,`material_id`,`workorder_id`) values (2,'1.0000',NULL,2,1); + +/*Table structure for table `selfhelp_workorder` */ + +DROP TABLE IF EXISTS `selfhelp_workorder`; + +CREATE TABLE `selfhelp_workorder` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `title` varchar(120) NOT NULL, + `description` longtext, + `business_domain` varchar(4) NOT NULL, + `classification` varchar(4) NOT NULL, + `status` varchar(6) DEFAULT NULL, + `answer` longtext, + `service_id` int(11) DEFAULT NULL, + `user_id` int(11) DEFAULT NULL, + `project_id` int(11), + `code` varchar(10), + `refer_id` int(11), + PRIMARY KEY (`id`), + KEY `selfhelp_workorder_service_id_17a66979_fk_basedata_material_id` (`service_id`), + KEY `selfhelp_workorder_user_id_72d939fa_fk_auth_user_id` (`user_id`), + KEY `selfhelp_workorder_b098ad43` (`project_id`), + KEY `selfhelp_workorder_12b2c0fd` (`refer_id`), + CONSTRAINT `selfhelp_workorder_project_id_66ab927f_fk_basedata_project_id` FOREIGN KEY (`project_id`) REFERENCES `basedata_project` (`id`), + CONSTRAINT `selfhelp_workorder_refer_id_212bc854_fk_selfhelp_workorder_id` FOREIGN KEY (`refer_id`) REFERENCES `selfhelp_workorder` (`id`), + CONSTRAINT `selfhelp_workorder_service_id_17a66979_fk_basedata_material_id` FOREIGN KEY (`service_id`) REFERENCES `basedata_material` (`id`), + CONSTRAINT `selfhelp_workorder_user_id_72d939fa_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +/*Data for the table `selfhelp_workorder` */ + +insert into `selfhelp_workorder`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`title`,`description`,`business_domain`,`classification`,`status`,`answer`,`service_id`,`user_id`,`project_id`,`code`,`refer_id`) values (1,'2015-05-22','9999-12-31','zhugl','zhugl','2015-05-22 23:58:53','2015-05-23 21:07:43','采购一批物资','','FI','D','NEW',NULL,NULL,1,1,'WO00001',NULL),(2,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 06:47:06','2015-05-23 07:13:44','出差申请(重庆)','123','HR','S','NEW',NULL,1,1,1,'WO00002',NULL),(3,'2015-05-23','9999-12-31','zhugl','zhugl','2015-05-23 08:14:53','2015-05-23 08:16:40','咨询:如何办理公积金取款','您好,我现准备在xx购买新房,请问如何办理公积金取款,谢谢。','HR','Q','NEW',NULL,NULL,1,NULL,'WO00003',NULL),(4,'2015-05-23','9999-12-31','zhugl',NULL,'2015-05-23 08:16:25','2015-05-23 08:16:25','报修:7号楼2楼男厕小便池堵塞','内有烟头,请安排人员处理','AD','R','NEW',NULL,NULL,1,NULL,'WO00004',NULL),(5,'2015-05-24','9999-12-31','zhugl','zhugl','2015-05-24 15:15:09','2015-05-25 21:06:11','接送X集团客户','','OT','S','NEW',NULL,3,1,NULL,'WO00005',2); + +/*Table structure for table `syscfg_menu` */ + +DROP TABLE IF EXISTS `syscfg_menu`; + +CREATE TABLE `syscfg_menu` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `url` varchar(80) DEFAULT NULL, + `weight` int(11) DEFAULT NULL, + `icon` varchar(40) DEFAULT NULL, + `status` tinyint(1) NOT NULL, + `module_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `syscfg_menu_c9799665` (`module_id`), + CONSTRAINT `syscfg_menu_module_id_14fa2e70_fk_syscfg_module_id` FOREIGN KEY (`module_id`) REFERENCES `syscfg_module` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_menu` */ + +insert into `syscfg_menu`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`url`,`weight`,`icon`,`status`,`module_id`) values (1,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 07:30:19','2015-05-01 07:30:19','M001','模块管理','',99,'',1,1),(2,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 07:30:32','2015-05-01 07:30:32','M002','菜单管理','',99,'',1,1),(3,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 07:52:20','2015-05-01 07:52:20','M003','角色管理','',99,'',1,1); + +/*Table structure for table `syscfg_module` */ + +DROP TABLE IF EXISTS `syscfg_module`; + +CREATE TABLE `syscfg_module` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `url` varchar(80) DEFAULT NULL, + `weight` int(11) DEFAULT NULL, + `icon` varchar(40) DEFAULT NULL, + `status` tinyint(1) NOT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `syscfg_module_parent_id_350dc54d_fk_syscfg_module_id` (`parent_id`), + CONSTRAINT `syscfg_module_parent_id_350dc54d_fk_syscfg_module_id` FOREIGN KEY (`parent_id`) REFERENCES `syscfg_module` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_module` */ + +insert into `syscfg_module`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`url`,`weight`,`icon`,`status`,`parent_id`) values (1,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 07:30:01','2015-05-01 07:30:01','U001','系统管理','',99,'',1,NULL),(2,'2015-05-01','9999-12-31','zhugl',NULL,'2015-05-01 07:51:45','2015-05-01 07:51:45','U002','基础数据','',99,'',1,NULL),(3,'2015-05-24','9999-12-31','zhugl',NULL,'2015-05-24 20:02:43','2015-05-24 20:02:43','HR','人力资源','',99,'',1,NULL),(4,'2015-05-24','9999-12-31','zhugl',NULL,'2015-05-24 20:07:15','2015-05-24 20:07:15','U004','个人自助','',99,'',1,NULL); + +/*Table structure for table `syscfg_role` */ + +DROP TABLE IF EXISTS `syscfg_role`; + +CREATE TABLE `syscfg_role` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `creator` varchar(20) DEFAULT NULL, + `modifier` varchar(20) DEFAULT NULL, + `creation` datetime DEFAULT NULL, + `modification` datetime DEFAULT NULL, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `description` varchar(80) DEFAULT NULL, + `status` tinyint(1) NOT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `syscfg_role_parent_id_161850bd_fk_syscfg_role_id` (`parent_id`), + CONSTRAINT `syscfg_role_parent_id_161850bd_fk_syscfg_role_id` FOREIGN KEY (`parent_id`) REFERENCES `syscfg_role` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_role` */ + +insert into `syscfg_role`(`id`,`begin`,`end`,`creator`,`modifier`,`creation`,`modification`,`code`,`name`,`description`,`status`,`parent_id`) values (1,'2015-05-01','9999-12-31','zhugl','zhugl','2015-05-01 07:31:46','2015-05-10 16:53:23','R001','职员','',1,NULL); + +/*Table structure for table `syscfg_role_menus` */ + +DROP TABLE IF EXISTS `syscfg_role_menus`; + +CREATE TABLE `syscfg_role_menus` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL, + `menu_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `role_id` (`role_id`,`menu_id`), + KEY `syscfg_role_menus_menu_id_4fb81053_fk_syscfg_menu_id` (`menu_id`), + CONSTRAINT `syscfg_role_menus_menu_id_4fb81053_fk_syscfg_menu_id` FOREIGN KEY (`menu_id`) REFERENCES `syscfg_menu` (`id`), + CONSTRAINT `syscfg_role_menus_role_id_2c83ed04_fk_syscfg_role_id` FOREIGN KEY (`role_id`) REFERENCES `syscfg_role` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_role_menus` */ + +/*Table structure for table `syscfg_role_users` */ + +DROP TABLE IF EXISTS `syscfg_role_users`; + +CREATE TABLE `syscfg_role_users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `role_id` (`role_id`,`user_id`), + KEY `syscfg_role_users_user_id_3ede60c3_fk_auth_user_id` (`user_id`), + CONSTRAINT `syscfg_role_users_role_id_50b58548_fk_syscfg_role_id` FOREIGN KEY (`role_id`) REFERENCES `syscfg_role` (`id`), + CONSTRAINT `syscfg_role_users_user_id_3ede60c3_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_role_users` */ + +insert into `syscfg_role_users`(`id`,`role_id`,`user_id`) values (3,1,1),(4,1,2); + +/*Table structure for table `syscfg_site` */ + +DROP TABLE IF EXISTS `syscfg_site`; + +CREATE TABLE `syscfg_site` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `name` varchar(40) NOT NULL, + `description` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_site` */ + +insert into `syscfg_site`(`id`,`begin`,`end`,`name`,`description`) values (1,'2015-05-01','9999-05-01','启腾控股集团',''); + +/*Table structure for table `syscfg_site_user` */ + +DROP TABLE IF EXISTS `syscfg_site_user`; + +CREATE TABLE `syscfg_site_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `site_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `site_id` (`site_id`,`user_id`), + KEY `syscfg_site_user_user_id_31f8aecc_fk_auth_user_id` (`user_id`), + CONSTRAINT `syscfg_site_user_site_id_e6ec06c_fk_syscfg_site_id` FOREIGN KEY (`site_id`) REFERENCES `syscfg_site` (`id`), + CONSTRAINT `syscfg_site_user_user_id_31f8aecc_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `syscfg_site_user` */ + +insert into `syscfg_site_user`(`id`,`site_id`,`user_id`) values (1,1,1); + +/*Table structure for table `workflow_history` */ + +DROP TABLE IF EXISTS `workflow_history`; + +CREATE TABLE `workflow_history` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `pro_time` datetime NOT NULL, + `pro_type` int(11) NOT NULL, + `memo` varchar(40) DEFAULT NULL, + `inst_id` int(11) NOT NULL, + `node_id` int(11), + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_history_d2b1b1e1` (`inst_id`), + KEY `workflow_history_c693ebc8` (`node_id`), + KEY `workflow_history_e8701ad4` (`user_id`), + CONSTRAINT `workflow_history_inst_id_2237d3b0_fk_workflow_instance_id` FOREIGN KEY (`inst_id`) REFERENCES `workflow_instance` (`id`), + CONSTRAINT `workflow_history_node_id_54527354_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_history_user_id_4dee98c5_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_history` */ + +insert into `workflow_history`(`id`,`pro_time`,`pro_type`,`memo`,`inst_id`,`node_id`,`user_id`) values (47,'2015-05-20 05:30:08',0,NULL,21,NULL,1),(48,'2015-05-20 06:04:31',3,'',21,3,1); + +/*Table structure for table `workflow_instance` */ + +DROP TABLE IF EXISTS `workflow_instance`; + +CREATE TABLE `workflow_instance` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(10) DEFAULT NULL, + `object_id` int(10) unsigned NOT NULL, + `start_time` datetime NOT NULL, + `approved_time` datetime DEFAULT NULL, + `status` int(11) NOT NULL, + `modal_id` int(11) NOT NULL, + `starter_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_instance_9b2b8663` (`modal_id`), + KEY `workflow_instance_11d91f21` (`starter_id`), + CONSTRAINT `workflow_instance_modal_id_3eb1d1ea_fk_workflow_modal_id` FOREIGN KEY (`modal_id`) REFERENCES `workflow_modal` (`id`), + CONSTRAINT `workflow_instance_starter_id_3e0b14b6_fk_auth_user_id` FOREIGN KEY (`starter_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_instance` */ + +insert into `workflow_instance`(`id`,`code`,`object_id`,`start_time`,`approved_time`,`status`,`modal_id`,`starter_id`) values (21,'S00021',4,'2015-05-20 05:30:08',NULL,3,1,1); + +/*Table structure for table `workflow_instance_current_nodes` */ + +DROP TABLE IF EXISTS `workflow_instance_current_nodes`; + +CREATE TABLE `workflow_instance_current_nodes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `instance_id` int(11) NOT NULL, + `node_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `instance_id` (`instance_id`,`node_id`), + KEY `workflow_instance_current_n_node_id_54bc8d3a_fk_workflow_node_id` (`node_id`), + CONSTRAINT `workflow_instance_current_n_node_id_54bc8d3a_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_instance_cu_instance_id_556870f_fk_workflow_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `workflow_instance` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_instance_current_nodes` */ + +/*Table structure for table `workflow_modal` */ + +DROP TABLE IF EXISTS `workflow_modal`; + +CREATE TABLE `workflow_modal` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(6) DEFAULT NULL, + `name` varchar(40) NOT NULL, + `description` longtext, + `app_name` varchar(60) DEFAULT NULL, + `model_name` varchar(60) DEFAULT NULL, + `begin` date DEFAULT NULL, + `end` date DEFAULT NULL, + `content_type_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_moda_content_type_id_7646d9af_fk_django_content_type_id` (`content_type_id`), + CONSTRAINT `workflow_moda_content_type_id_7646d9af_fk_django_content_type_id` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_modal` */ + +insert into `workflow_modal`(`id`,`code`,`name`,`description`,`app_name`,`model_name`,`begin`,`end`,`content_type_id`) values (1,'WF001','新员工入职流程','','basedata','employee','2015-05-10','9999-12-31',30); + +/*Table structure for table `workflow_node` */ + +DROP TABLE IF EXISTS `workflow_node`; + +CREATE TABLE `workflow_node` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(4) DEFAULT NULL, + `name` varchar(80) NOT NULL, + `tooltip` varchar(120) DEFAULT NULL, + `start` tinyint(1) NOT NULL, + `stop` tinyint(1) NOT NULL, + `can_terminate` tinyint(1) NOT NULL, + `can_deny` tinyint(1) NOT NULL, + `email_notice` tinyint(1) NOT NULL, + `short_message_notice` tinyint(1) NOT NULL, + `approve_node` tinyint(1) NOT NULL, + `handler` longtext, + `handler_type` int(11) NOT NULL, + `modal_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_node_modal_id_3aa9d381_fk_workflow_modal_id` (`modal_id`), + CONSTRAINT `workflow_node_modal_id_3aa9d381_fk_workflow_modal_id` FOREIGN KEY (`modal_id`) REFERENCES `workflow_modal` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node` */ + +insert into `workflow_node`(`id`,`code`,`name`,`tooltip`,`start`,`stop`,`can_terminate`,`can_deny`,`email_notice`,`short_message_notice`,`approve_node`,`handler`,`handler_type`,`modal_id`) values (3,'N01','薪酬专员审批','',0,0,0,1,1,0,0,'',1,1),(4,'N02','合同专员审批','',0,0,0,1,1,0,0,'',1,1); + +/*Table structure for table `workflow_node_departments` */ + +DROP TABLE IF EXISTS `workflow_node_departments`; + +CREATE TABLE `workflow_node_departments` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `node_id` int(11) NOT NULL, + `orgunit_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `node_id` (`node_id`,`orgunit_id`), + KEY `workflow_node_department_orgunit_id_276f2bb6_fk_organ_orgunit_id` (`orgunit_id`), + CONSTRAINT `workflow_node_departments_node_id_379e5725_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_node_department_orgunit_id_276f2bb6_fk_organ_orgunit_id` FOREIGN KEY (`orgunit_id`) REFERENCES `organ_orgunit` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node_departments` */ + +/*Table structure for table `workflow_node_next` */ + +DROP TABLE IF EXISTS `workflow_node_next`; + +CREATE TABLE `workflow_node_next` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `from_node_id` int(11) NOT NULL, + `to_node_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `from_node_id` (`from_node_id`,`to_node_id`), + KEY `workflow_node_next_to_node_id_71e709f3_fk_workflow_node_id` (`to_node_id`), + CONSTRAINT `workflow_node_next_from_node_id_78e6ce74_fk_workflow_node_id` FOREIGN KEY (`from_node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_node_next_to_node_id_71e709f3_fk_workflow_node_id` FOREIGN KEY (`to_node_id`) REFERENCES `workflow_node` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node_next` */ + +insert into `workflow_node_next`(`id`,`from_node_id`,`to_node_id`) values (3,3,4); + +/*Table structure for table `workflow_node_positions` */ + +DROP TABLE IF EXISTS `workflow_node_positions`; + +CREATE TABLE `workflow_node_positions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `node_id` int(11) NOT NULL, + `position_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `node_id` (`node_id`,`position_id`), + KEY `workflow_node_position_position_id_187bce75_fk_organ_position_id` (`position_id`), + CONSTRAINT `workflow_node_positions_node_id_64f898c6_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_node_position_position_id_187bce75_fk_organ_position_id` FOREIGN KEY (`position_id`) REFERENCES `organ_position` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node_positions` */ + +/*Table structure for table `workflow_node_roles` */ + +DROP TABLE IF EXISTS `workflow_node_roles`; + +CREATE TABLE `workflow_node_roles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `node_id` int(11) NOT NULL, + `role_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `node_id` (`node_id`,`role_id`), + KEY `workflow_node_roles_role_id_1b05e9ff_fk_syscfg_role_id` (`role_id`), + CONSTRAINT `workflow_node_roles_node_id_c6ea3f5_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_node_roles_role_id_1b05e9ff_fk_syscfg_role_id` FOREIGN KEY (`role_id`) REFERENCES `syscfg_role` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node_roles` */ + +/*Table structure for table `workflow_node_users` */ + +DROP TABLE IF EXISTS `workflow_node_users`; + +CREATE TABLE `workflow_node_users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `node_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `node_id` (`node_id`,`user_id`), + KEY `workflow_node_users_user_id_36b0d3c5_fk_auth_user_id` (`user_id`), + CONSTRAINT `workflow_node_users_node_id_4b2940ca_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_node_users_user_id_36b0d3c5_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_node_users` */ + +insert into `workflow_node_users`(`id`,`node_id`,`user_id`) values (7,3,1),(8,3,2),(9,4,2); + +/*Table structure for table `workflow_todolist` */ + +DROP TABLE IF EXISTS `workflow_todolist`; + +CREATE TABLE `workflow_todolist` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `app_name` varchar(60) DEFAULT NULL, + `model_name` varchar(60) DEFAULT NULL, + `arrived_time` datetime NOT NULL, + `is_read` tinyint(1) NOT NULL, + `read_time` datetime DEFAULT NULL, + `inst_id` int(11) NOT NULL, + `node_id` int(11) DEFAULT NULL, + `user_id` int(11) NOT NULL, + `code` varchar(10), + `status` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_todolist_inst_id_5f7d95_fk_workflow_instance_id` (`inst_id`), + KEY `workflow_todolist_user_id_5209b40_fk_auth_user_id` (`user_id`), + KEY `workflow_todolist_node_id_6be79401_fk_workflow_node_id` (`node_id`), + CONSTRAINT `workflow_todolist_inst_id_5f7d95_fk_workflow_instance_id` FOREIGN KEY (`inst_id`) REFERENCES `workflow_instance` (`id`), + CONSTRAINT `workflow_todolist_node_id_6be79401_fk_workflow_node_id` FOREIGN KEY (`node_id`) REFERENCES `workflow_node` (`id`), + CONSTRAINT `workflow_todolist_user_id_5209b40_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8; + +/*Data for the table `workflow_todolist` */ + +insert into `workflow_todolist`(`id`,`app_name`,`model_name`,`arrived_time`,`is_read`,`read_time`,`inst_id`,`node_id`,`user_id`,`code`,`status`) values (57,'basedata','employee','2015-05-20 05:30:08',1,'2015-05-20 05:30:08',21,3,1,'TD00057',1),(58,'basedata','employee','2015-05-20 05:30:08',0,NULL,21,3,2,'TD00058',1); + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/upload/inventory/INVENTORY.csv b/upload/inventory/INVENTORY.csv new file mode 100644 index 0000000..beffe50 --- /dev/null +++ b/upload/inventory/INVENTORY.csv @@ -0,0 +1,11 @@ +ϱ,,ͺ,,λ,ֿ,ֿ,, +IT9001,츻ʿƻ,#80,KG,ǧˣ,FR,ˮ,5.6,120 +IT9002,ˮ,#75,KG,ǧˣ,FR,ˮ,8.2,105 +IT9003,ĸʿ,#80,KG,ǧˣ,FR,ˮ,9.5,569 +IT9004,,,KG,ǧˣ,FR,ˮ,6.5,159 +IT9005,ɽ,,KG,ǧˣ,FR,ˮ,7.8,276 +IT9006,ϳ,,KG,ǧˣ,FR,ˮ,6.9,309 +IT9007,ë,,KG,ǧˣ,FR,ˮ,12.6,38 +IT9008,Ļ,,KG,ǧˣ,FR,ˮ,8.2,98 +IT9009,ʥŮ,,KG,ǧˣ,FR,ˮ,8.9,315 +IT9010,,,KG,ǧˣ,FR,ˮ,14.6,212 diff --git a/upload/inventory/INVENTORY_PPfDioe.csv b/upload/inventory/INVENTORY_PPfDioe.csv new file mode 100644 index 0000000..beffe50 --- /dev/null +++ b/upload/inventory/INVENTORY_PPfDioe.csv @@ -0,0 +1,11 @@ +ϱ,,ͺ,,λ,ֿ,ֿ,, +IT9001,츻ʿƻ,#80,KG,ǧˣ,FR,ˮ,5.6,120 +IT9002,ˮ,#75,KG,ǧˣ,FR,ˮ,8.2,105 +IT9003,ĸʿ,#80,KG,ǧˣ,FR,ˮ,9.5,569 +IT9004,,,KG,ǧˣ,FR,ˮ,6.5,159 +IT9005,ɽ,,KG,ǧˣ,FR,ˮ,7.8,276 +IT9006,ϳ,,KG,ǧˣ,FR,ˮ,6.9,309 +IT9007,ë,,KG,ǧˣ,FR,ˮ,12.6,38 +IT9008,Ļ,,KG,ǧˣ,FR,ˮ,8.2,98 +IT9009,ʥŮ,,KG,ǧˣ,FR,ˮ,8.9,315 +IT9010,,,KG,ǧˣ,FR,ˮ,14.6,212 diff --git a/upload/offer sheet/backbone.js b/upload/offer sheet/backbone.js new file mode 100644 index 0000000..09c855a --- /dev/null +++ b/upload/offer sheet/backbone.js @@ -0,0 +1,1745 @@ +// Backbone.js 1.1.2 + +// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://backbonejs.org + +(function(root, factory) { + + // Set up Backbone appropriately for the environment. Start with AMD. + if (typeof define === 'function' && define.amd) { + define(['underscore', 'jquery', 'exports'], function(_, $, exports) { + // Export global even in AMD case in case this script is loaded with + // others that may still expect a global Backbone. + root.Backbone = factory(root, exports, _, $); + }); + + // Next for Node.js or CommonJS. jQuery may not be needed as a module. + } else if (typeof exports !== 'undefined') { + var _ = require('underscore'); + factory(root, exports, _); + + // Finally, as a browser global. + } else { + root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$)); + } + +}(this, function(root, Backbone, _, $) { + + // Initial Setup + // ------------- + + // Save the previous value of the `Backbone` variable, so that it can be + // restored later on, if `noConflict` is used. + var previousBackbone = root.Backbone; + + // Create local references to array methods we'll want to use later. + var array = []; + var slice = array.slice; + + // Current version of the library. Keep in sync with `package.json`. + Backbone.VERSION = '1.1.2'; + + // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns + // the `$` variable. + Backbone.$ = $; + + // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable + // to its previous owner. Returns a reference to this Backbone object. + Backbone.noConflict = function() { + root.Backbone = previousBackbone; + return this; + }; + + // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option + // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and + // set a `X-Http-Method-Override` header. + Backbone.emulateHTTP = false; + + // Turn on `emulateJSON` to support legacy servers that can't deal with direct + // `application/json` requests ... this will encode the body as + // `application/x-www-form-urlencoded` instead and will send the model in a + // form param named `model`. + Backbone.emulateJSON = false; + + // Backbone.Events + // --------------- + + // A module that can be mixed in to *any object* in order to provide it with + // custom events. You may bind with `on` or remove with `off` callback + // functions to an event; `trigger`-ing an event fires all callbacks in + // succession. + // + // var object = {}; + // _.extend(object, Backbone.Events); + // object.on('expand', function(){ alert('expanded'); }); + // object.trigger('expand'); + // + var Events = Backbone.Events = { + + // Bind an event to a `callback` function. Passing `"all"` will bind + // the callback to all events fired. + on: function(name, callback, context) { + if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; + this._events || (this._events = {}); + var events = this._events[name] || (this._events[name] = []); + events.push({callback: callback, context: context, ctx: context || this}); + return this; + }, + + // Bind an event to only be triggered a single time. After the first time + // the callback is invoked, it will be removed. + once: function(name, callback, context) { + if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this; + var self = this; + var once = _.once(function() { + self.off(name, once); + callback.apply(this, arguments); + }); + once._callback = callback; + return this.on(name, once, context); + }, + + // Remove one or many callbacks. If `context` is null, removes all + // callbacks with that function. If `callback` is null, removes all + // callbacks for the event. If `name` is null, removes all bound + // callbacks for all events. + off: function(name, callback, context) { + if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; + + // Remove all callbacks for all events. + if (!name && !callback && !context) { + this._events = void 0; + return this; + } + + var names = name ? [name] : _.keys(this._events); + for (var i = 0, length = names.length; i < length; i++) { + name = names[i]; + + // Bail out if there are no events stored. + var events = this._events[name]; + if (!events) continue; + + // Remove all callbacks for this event. + if (!callback && !context) { + delete this._events[name]; + continue; + } + + // Find any remaining events. + var remaining = []; + for (var j = 0, k = events.length; j < k; j++) { + var event = events[j]; + if ( + callback && callback !== event.callback && + callback !== event.callback._callback || + context && context !== event.context + ) { + remaining.push(event); + } + } + + // Replace events if there are any remaining. Otherwise, clean up. + if (remaining.length) { + this._events[name] = remaining; + } else { + delete this._events[name]; + } + } + + return this; + }, + + // Trigger one or many events, firing all bound callbacks. Callbacks are + // passed the same arguments as `trigger` is, apart from the event name + // (unless you're listening on `"all"`, which will cause your callback to + // receive the true name of the event as the first argument). + trigger: function(name) { + if (!this._events) return this; + var args = slice.call(arguments, 1); + if (!eventsApi(this, 'trigger', name, args)) return this; + var events = this._events[name]; + var allEvents = this._events.all; + if (events) triggerEvents(events, args); + if (allEvents) triggerEvents(allEvents, arguments); + return this; + }, + + // Inversion-of-control versions of `on` and `once`. Tell *this* object to + // listen to an event in another object ... keeping track of what it's + // listening to. + listenTo: function(obj, name, callback) { + var listeningTo = this._listeningTo || (this._listeningTo = {}); + var id = obj._listenId || (obj._listenId = _.uniqueId('l')); + listeningTo[id] = obj; + if (!callback && typeof name === 'object') callback = this; + obj.on(name, callback, this); + return this; + }, + + listenToOnce: function(obj, name, callback) { + if (typeof name === 'object') { + for (var event in name) this.listenToOnce(obj, event, name[event]); + return this; + } + if (eventSplitter.test(name)) { + var names = name.split(eventSplitter); + for (var i = 0, length = names.length; i < length; i++) { + this.listenToOnce(obj, names[i], callback); + } + return this; + } + if (!callback) return this; + var once = _.once(function() { + this.stopListening(obj, name, once); + callback.apply(this, arguments); + }); + once._callback = callback; + return this.listenTo(obj, name, once); + }, + + // Tell this object to stop listening to either specific events ... or + // to every object it's currently listening to. + stopListening: function(obj, name, callback) { + var listeningTo = this._listeningTo; + if (!listeningTo) return this; + var remove = !name && !callback; + if (!callback && typeof name === 'object') callback = this; + if (obj) (listeningTo = {})[obj._listenId] = obj; + for (var id in listeningTo) { + obj = listeningTo[id]; + obj.off(name, callback, this); + if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id]; + } + return this; + } + + }; + + // Regular expression used to split event strings. + var eventSplitter = /\s+/; + + // Implement fancy features of the Events API such as multiple event + // names `"change blur"` and jQuery-style event maps `{change: action}` + // in terms of the existing API. + var eventsApi = function(obj, action, name, rest) { + if (!name) return true; + + // Handle event maps. + if (typeof name === 'object') { + for (var key in name) { + obj[action].apply(obj, [key, name[key]].concat(rest)); + } + return false; + } + + // Handle space separated event names. + if (eventSplitter.test(name)) { + var names = name.split(eventSplitter); + for (var i = 0, length = names.length; i < length; i++) { + obj[action].apply(obj, [names[i]].concat(rest)); + } + return false; + } + + return true; + }; + + // A difficult-to-believe, but optimized internal dispatch function for + // triggering events. Tries to keep the usual cases speedy (most internal + // Backbone events have 3 arguments). + var triggerEvents = function(events, args) { + var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; + switch (args.length) { + case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; + case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; + case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; + case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; + default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; + } + }; + + // Aliases for backwards compatibility. + Events.bind = Events.on; + Events.unbind = Events.off; + + // Allow the `Backbone` object to serve as a global event bus, for folks who + // want global "pubsub" in a convenient place. + _.extend(Backbone, Events); + + // Backbone.Model + // -------------- + + // Backbone **Models** are the basic data object in the framework -- + // frequently representing a row in a table in a database on your server. + // A discrete chunk of data and a bunch of useful, related methods for + // performing computations and transformations on that data. + + // Create a new model with the specified attributes. A client id (`cid`) + // is automatically generated and assigned for you. + var Model = Backbone.Model = function(attributes, options) { + var attrs = attributes || {}; + options || (options = {}); + this.cid = _.uniqueId('c'); + this.attributes = {}; + if (options.collection) this.collection = options.collection; + if (options.parse) attrs = this.parse(attrs, options) || {}; + attrs = _.defaults({}, attrs, _.result(this, 'defaults')); + this.set(attrs, options); + this.changed = {}; + this.initialize.apply(this, arguments); + }; + + // Attach all inheritable methods to the Model prototype. + _.extend(Model.prototype, Events, { + + // A hash of attributes whose current and previous value differ. + changed: null, + + // The value returned during the last failed validation. + validationError: null, + + // The default name for the JSON `id` attribute is `"id"`. MongoDB and + // CouchDB users may want to set this to `"_id"`. + idAttribute: 'id', + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Return a copy of the model's `attributes` object. + toJSON: function(options) { + return _.clone(this.attributes); + }, + + // Proxy `Backbone.sync` by default -- but override this if you need + // custom syncing semantics for *this* particular model. + sync: function() { + return Backbone.sync.apply(this, arguments); + }, + + // Get the value of an attribute. + get: function(attr) { + return this.attributes[attr]; + }, + + // Get the HTML-escaped value of an attribute. + escape: function(attr) { + return _.escape(this.get(attr)); + }, + + // Returns `true` if the attribute contains a value that is not null + // or undefined. + has: function(attr) { + return this.get(attr) != null; + }, + + // Special-cased proxy to underscore's `_.matches` method. + matches: function(attrs) { + return _.matches(attrs)(this.attributes); + }, + + // Set a hash of model attributes on the object, firing `"change"`. This is + // the core primitive operation of a model, updating the data and notifying + // anyone who needs to know about the change in state. The heart of the beast. + set: function(key, val, options) { + var attr, attrs, unset, changes, silent, changing, prev, current; + if (key == null) return this; + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (typeof key === 'object') { + attrs = key; + options = val; + } else { + (attrs = {})[key] = val; + } + + options || (options = {}); + + // Run validation. + if (!this._validate(attrs, options)) return false; + + // Extract attributes and options. + unset = options.unset; + silent = options.silent; + changes = []; + changing = this._changing; + this._changing = true; + + if (!changing) { + this._previousAttributes = _.clone(this.attributes); + this.changed = {}; + } + current = this.attributes, prev = this._previousAttributes; + + // Check for changes of `id`. + if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; + + // For each `set` attribute, update or delete the current value. + for (attr in attrs) { + val = attrs[attr]; + if (!_.isEqual(current[attr], val)) changes.push(attr); + if (!_.isEqual(prev[attr], val)) { + this.changed[attr] = val; + } else { + delete this.changed[attr]; + } + unset ? delete current[attr] : current[attr] = val; + } + + // Trigger all relevant attribute changes. + if (!silent) { + if (changes.length) this._pending = options; + for (var i = 0, length = changes.length; i < length; i++) { + this.trigger('change:' + changes[i], this, current[changes[i]], options); + } + } + + // You might be wondering why there's a `while` loop here. Changes can + // be recursively nested within `"change"` events. + if (changing) return this; + if (!silent) { + while (this._pending) { + options = this._pending; + this._pending = false; + this.trigger('change', this, options); + } + } + this._pending = false; + this._changing = false; + return this; + }, + + // Remove an attribute from the model, firing `"change"`. `unset` is a noop + // if the attribute doesn't exist. + unset: function(attr, options) { + return this.set(attr, void 0, _.extend({}, options, {unset: true})); + }, + + // Clear all attributes on the model, firing `"change"`. + clear: function(options) { + var attrs = {}; + for (var key in this.attributes) attrs[key] = void 0; + return this.set(attrs, _.extend({}, options, {unset: true})); + }, + + // Determine if the model has changed since the last `"change"` event. + // If you specify an attribute name, determine if that attribute has changed. + hasChanged: function(attr) { + if (attr == null) return !_.isEmpty(this.changed); + return _.has(this.changed, attr); + }, + + // Return an object containing all the attributes that have changed, or + // false if there are no changed attributes. Useful for determining what + // parts of a view need to be updated and/or what attributes need to be + // persisted to the server. Unset attributes will be set to undefined. + // You can also pass an attributes object to diff against the model, + // determining if there *would be* a change. + changedAttributes: function(diff) { + if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; + var val, changed = false; + var old = this._changing ? this._previousAttributes : this.attributes; + for (var attr in diff) { + if (_.isEqual(old[attr], (val = diff[attr]))) continue; + (changed || (changed = {}))[attr] = val; + } + return changed; + }, + + // Get the previous value of an attribute, recorded at the time the last + // `"change"` event was fired. + previous: function(attr) { + if (attr == null || !this._previousAttributes) return null; + return this._previousAttributes[attr]; + }, + + // Get all of the attributes of the model at the time of the previous + // `"change"` event. + previousAttributes: function() { + return _.clone(this._previousAttributes); + }, + + // Fetch the model from the server. If the server's representation of the + // model differs from its current attributes, they will be overridden, + // triggering a `"change"` event. + fetch: function(options) { + options = options ? _.clone(options) : {}; + if (options.parse === void 0) options.parse = true; + var model = this; + var success = options.success; + options.success = function(resp) { + if (!model.set(model.parse(resp, options), options)) return false; + if (success) success(model, resp, options); + model.trigger('sync', model, resp, options); + }; + wrapError(this, options); + return this.sync('read', this, options); + }, + + // Set a hash of model attributes, and sync the model to the server. + // If the server returns an attributes hash that differs, the model's + // state will be `set` again. + save: function(key, val, options) { + var attrs, method, xhr, attributes = this.attributes; + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (key == null || typeof key === 'object') { + attrs = key; + options = val; + } else { + (attrs = {})[key] = val; + } + + options = _.extend({validate: true}, options); + + // If we're not waiting and attributes exist, save acts as + // `set(attr).save(null, opts)` with validation. Otherwise, check if + // the model will be valid when the attributes, if any, are set. + if (attrs && !options.wait) { + if (!this.set(attrs, options)) return false; + } else { + if (!this._validate(attrs, options)) return false; + } + + // Set temporary attributes if `{wait: true}`. + if (attrs && options.wait) { + this.attributes = _.extend({}, attributes, attrs); + } + + // After a successful server-side save, the client is (optionally) + // updated with the server-side state. + if (options.parse === void 0) options.parse = true; + var model = this; + var success = options.success; + options.success = function(resp) { + // Ensure attributes are restored during synchronous saves. + model.attributes = attributes; + var serverAttrs = model.parse(resp, options); + if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); + if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { + return false; + } + if (success) success(model, resp, options); + model.trigger('sync', model, resp, options); + }; + wrapError(this, options); + + method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); + if (method === 'patch' && !options.attrs) options.attrs = attrs; + xhr = this.sync(method, this, options); + + // Restore attributes. + if (attrs && options.wait) this.attributes = attributes; + + return xhr; + }, + + // Destroy this model on the server if it was already persisted. + // Optimistically removes the model from its collection, if it has one. + // If `wait: true` is passed, waits for the server to respond before removal. + destroy: function(options) { + options = options ? _.clone(options) : {}; + var model = this; + var success = options.success; + + var destroy = function() { + model.stopListening(); + model.trigger('destroy', model, model.collection, options); + }; + + options.success = function(resp) { + if (options.wait || model.isNew()) destroy(); + if (success) success(model, resp, options); + if (!model.isNew()) model.trigger('sync', model, resp, options); + }; + + if (this.isNew()) { + options.success(); + return false; + } + wrapError(this, options); + + var xhr = this.sync('delete', this, options); + if (!options.wait) destroy(); + return xhr; + }, + + // Default URL for the model's representation on the server -- if you're + // using Backbone's restful methods, override this to change the endpoint + // that will be called. + url: function() { + var base = + _.result(this, 'urlRoot') || + _.result(this.collection, 'url') || + urlError(); + if (this.isNew()) return base; + return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id); + }, + + // **parse** converts a response into the hash of attributes to be `set` on + // the model. The default implementation is just to pass the response along. + parse: function(resp, options) { + return resp; + }, + + // Create a new model with identical attributes to this one. + clone: function() { + return new this.constructor(this.attributes); + }, + + // A model is new if it has never been saved to the server, and lacks an id. + isNew: function() { + return !this.has(this.idAttribute); + }, + + // Check if the model is currently in a valid state. + isValid: function(options) { + return this._validate({}, _.extend(options || {}, { validate: true })); + }, + + // Run validation against the next complete set of model attributes, + // returning `true` if all is well. Otherwise, fire an `"invalid"` event. + _validate: function(attrs, options) { + if (!options.validate || !this.validate) return true; + attrs = _.extend({}, this.attributes, attrs); + var error = this.validationError = this.validate(attrs, options) || null; + if (!error) return true; + this.trigger('invalid', this, error, _.extend(options, {validationError: error})); + return false; + } + + }); + + // Underscore methods that we want to implement on the Model. + var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit', 'chain', 'isEmpty']; + + // Mix in each Underscore method as a proxy to `Model#attributes`. + _.each(modelMethods, function(method) { + if (!_[method]) return; + Model.prototype[method] = function() { + var args = slice.call(arguments); + args.unshift(this.attributes); + return _[method].apply(_, args); + }; + }); + + // Backbone.Collection + // ------------------- + + // If models tend to represent a single row of data, a Backbone Collection is + // more analogous to a table full of data ... or a small slice or page of that + // table, or a collection of rows that belong together for a particular reason + // -- all of the messages in this particular folder, all of the documents + // belonging to this particular author, and so on. Collections maintain + // indexes of their models, both in order, and for lookup by `id`. + + // Create a new **Collection**, perhaps to contain a specific type of `model`. + // If a `comparator` is specified, the Collection will maintain + // its models in sort order, as they're added and removed. + var Collection = Backbone.Collection = function(models, options) { + options || (options = {}); + if (options.model) this.model = options.model; + if (options.comparator !== void 0) this.comparator = options.comparator; + this._reset(); + this.initialize.apply(this, arguments); + if (models) this.reset(models, _.extend({silent: true}, options)); + }; + + // Default options for `Collection#set`. + var setOptions = {add: true, remove: true, merge: true}; + var addOptions = {add: true, remove: false}; + + // Define the Collection's inheritable methods. + _.extend(Collection.prototype, Events, { + + // The default model for a collection is just a **Backbone.Model**. + // This should be overridden in most cases. + model: Model, + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // The JSON representation of a Collection is an array of the + // models' attributes. + toJSON: function(options) { + return this.map(function(model){ return model.toJSON(options); }); + }, + + // Proxy `Backbone.sync` by default. + sync: function() { + return Backbone.sync.apply(this, arguments); + }, + + // Add a model, or list of models to the set. + add: function(models, options) { + return this.set(models, _.extend({merge: false}, options, addOptions)); + }, + + // Remove a model, or a list of models from the set. + remove: function(models, options) { + var singular = !_.isArray(models); + models = singular ? [models] : _.clone(models); + options || (options = {}); + for (var i = 0, length = models.length; i < length; i++) { + var model = models[i] = this.get(models[i]); + if (!model) continue; + var id = this.modelId(model.attributes); + if (id != null) delete this._byId[id]; + delete this._byId[model.cid]; + var index = this.indexOf(model); + this.models.splice(index, 1); + this.length--; + if (!options.silent) { + options.index = index; + model.trigger('remove', model, this, options); + } + this._removeReference(model, options); + } + return singular ? models[0] : models; + }, + + // Update a collection by `set`-ing a new list of models, adding new ones, + // removing models that are no longer present, and merging models that + // already exist in the collection, as necessary. Similar to **Model#set**, + // the core operation for updating the data contained by the collection. + set: function(models, options) { + options = _.defaults({}, options, setOptions); + if (options.parse) models = this.parse(models, options); + var singular = !_.isArray(models); + models = singular ? (models ? [models] : []) : models.slice(); + var id, model, attrs, existing, sort; + var at = options.at; + if (at != null) at = +at; + if (at < 0) at += this.length + 1; + var sortable = this.comparator && (at == null) && options.sort !== false; + var sortAttr = _.isString(this.comparator) ? this.comparator : null; + var toAdd = [], toRemove = [], modelMap = {}; + var add = options.add, merge = options.merge, remove = options.remove; + var order = !sortable && add && remove ? [] : false; + var orderChanged = false; + + // Turn bare objects into model references, and prevent invalid models + // from being added. + for (var i = 0, length = models.length; i < length; i++) { + attrs = models[i]; + + // If a duplicate is found, prevent it from being added and + // optionally merge it into the existing model. + if (existing = this.get(attrs)) { + if (remove) modelMap[existing.cid] = true; + if (merge && attrs !== existing) { + attrs = this._isModel(attrs) ? attrs.attributes : attrs; + if (options.parse) attrs = existing.parse(attrs, options); + existing.set(attrs, options); + if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; + } + models[i] = existing; + + // If this is a new, valid model, push it to the `toAdd` list. + } else if (add) { + model = models[i] = this._prepareModel(attrs, options); + if (!model) continue; + toAdd.push(model); + this._addReference(model, options); + } + + // Do not add multiple models with the same `id`. + model = existing || model; + if (!model) continue; + id = this.modelId(model.attributes); + if (order && (model.isNew() || !modelMap[id])) { + order.push(model); + + // Check to see if this is actually a new model at this index. + orderChanged = orderChanged || !this.models[i] || model.cid !== this.models[i].cid; + } + + modelMap[id] = true; + } + + // Remove nonexistent models if appropriate. + if (remove) { + for (var i = 0, length = this.length; i < length; i++) { + if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model); + } + if (toRemove.length) this.remove(toRemove, options); + } + + // See if sorting is needed, update `length` and splice in new models. + if (toAdd.length || orderChanged) { + if (sortable) sort = true; + this.length += toAdd.length; + if (at != null) { + for (var i = 0, length = toAdd.length; i < length; i++) { + this.models.splice(at + i, 0, toAdd[i]); + } + } else { + if (order) this.models.length = 0; + var orderedModels = order || toAdd; + for (var i = 0, length = orderedModels.length; i < length; i++) { + this.models.push(orderedModels[i]); + } + } + } + + // Silently sort the collection if appropriate. + if (sort) this.sort({silent: true}); + + // Unless silenced, it's time to fire all appropriate add/sort events. + if (!options.silent) { + var addOpts = at != null ? _.clone(options) : options; + for (var i = 0, length = toAdd.length; i < length; i++) { + if (at != null) addOpts.index = at + i; + (model = toAdd[i]).trigger('add', model, this, addOpts); + } + if (sort || orderChanged) this.trigger('sort', this, options); + } + + // Return the added (or merged) model (or models). + return singular ? models[0] : models; + }, + + // When you have more items than you want to add or remove individually, + // you can reset the entire set with a new list of models, without firing + // any granular `add` or `remove` events. Fires `reset` when finished. + // Useful for bulk operations and optimizations. + reset: function(models, options) { + options = options ? _.clone(options) : {}; + for (var i = 0, length = this.models.length; i < length; i++) { + this._removeReference(this.models[i], options); + } + options.previousModels = this.models; + this._reset(); + models = this.add(models, _.extend({silent: true}, options)); + if (!options.silent) this.trigger('reset', this, options); + return models; + }, + + // Add a model to the end of the collection. + push: function(model, options) { + return this.add(model, _.extend({at: this.length}, options)); + }, + + // Remove a model from the end of the collection. + pop: function(options) { + var model = this.at(this.length - 1); + this.remove(model, options); + return model; + }, + + // Add a model to the beginning of the collection. + unshift: function(model, options) { + return this.add(model, _.extend({at: 0}, options)); + }, + + // Remove a model from the beginning of the collection. + shift: function(options) { + var model = this.at(0); + this.remove(model, options); + return model; + }, + + // Slice out a sub-array of models from the collection. + slice: function() { + return slice.apply(this.models, arguments); + }, + + // Get a model from the set by id. + get: function(obj) { + if (obj == null) return void 0; + var id = this.modelId(this._isModel(obj) ? obj.attributes : obj); + return this._byId[obj] || this._byId[id] || this._byId[obj.cid]; + }, + + // Get the model at the given index. + at: function(index) { + if (index < 0) index += this.length; + return this.models[index]; + }, + + // Return models with matching attributes. Useful for simple cases of + // `filter`. + where: function(attrs, first) { + var matches = _.matches(attrs); + return this[first ? 'find' : 'filter'](function(model) { + return matches(model.attributes); + }); + }, + + // Return the first model with matching attributes. Useful for simple cases + // of `find`. + findWhere: function(attrs) { + return this.where(attrs, true); + }, + + // Force the collection to re-sort itself. You don't need to call this under + // normal circumstances, as the set will maintain sort order as each item + // is added. + sort: function(options) { + if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); + options || (options = {}); + + // Run sort based on type of `comparator`. + if (_.isString(this.comparator) || this.comparator.length === 1) { + this.models = this.sortBy(this.comparator, this); + } else { + this.models.sort(_.bind(this.comparator, this)); + } + + if (!options.silent) this.trigger('sort', this, options); + return this; + }, + + // Pluck an attribute from each model in the collection. + pluck: function(attr) { + return _.invoke(this.models, 'get', attr); + }, + + // Fetch the default set of models for this collection, resetting the + // collection when they arrive. If `reset: true` is passed, the response + // data will be passed through the `reset` method instead of `set`. + fetch: function(options) { + options = options ? _.clone(options) : {}; + if (options.parse === void 0) options.parse = true; + var success = options.success; + var collection = this; + options.success = function(resp) { + var method = options.reset ? 'reset' : 'set'; + collection[method](resp, options); + if (success) success(collection, resp, options); + collection.trigger('sync', collection, resp, options); + }; + wrapError(this, options); + return this.sync('read', this, options); + }, + + // Create a new instance of a model in this collection. Add the model to the + // collection immediately, unless `wait: true` is passed, in which case we + // wait for the server to agree. + create: function(model, options) { + options = options ? _.clone(options) : {}; + if (!(model = this._prepareModel(model, options))) return false; + if (!options.wait) this.add(model, options); + var collection = this; + var success = options.success; + options.success = function(model, resp) { + if (options.wait) collection.add(model, options); + if (success) success(model, resp, options); + }; + model.save(null, options); + return model; + }, + + // **parse** converts a response into a list of models to be added to the + // collection. The default implementation is just to pass it through. + parse: function(resp, options) { + return resp; + }, + + // Create a new collection with an identical list of models as this one. + clone: function() { + return new this.constructor(this.models, { + model: this.model, + comparator: this.comparator + }); + }, + + // Define how to uniquely identify models in the collection. + modelId: function (attrs) { + return attrs[this.model.prototype.idAttribute || 'id']; + }, + + // Private method to reset all internal state. Called when the collection + // is first initialized or reset. + _reset: function() { + this.length = 0; + this.models = []; + this._byId = {}; + }, + + // Prepare a hash of attributes (or other model) to be added to this + // collection. + _prepareModel: function(attrs, options) { + if (this._isModel(attrs)) { + if (!attrs.collection) attrs.collection = this; + return attrs; + } + options = options ? _.clone(options) : {}; + options.collection = this; + var model = new this.model(attrs, options); + if (!model.validationError) return model; + this.trigger('invalid', this, model.validationError, options); + return false; + }, + + // Method for checking whether an object should be considered a model for + // the purposes of adding to the collection. + _isModel: function (model) { + return model instanceof Model; + }, + + // Internal method to create a model's ties to a collection. + _addReference: function(model, options) { + this._byId[model.cid] = model; + var id = this.modelId(model.attributes); + if (id != null) this._byId[id] = model; + model.on('all', this._onModelEvent, this); + }, + + // Internal method to sever a model's ties to a collection. + _removeReference: function(model, options) { + if (this === model.collection) delete model.collection; + model.off('all', this._onModelEvent, this); + }, + + // Internal method called every time a model in the set fires an event. + // Sets need to update their indexes when models change ids. All other + // events simply proxy through. "add" and "remove" events that originate + // in other collections are ignored. + _onModelEvent: function(event, model, collection, options) { + if ((event === 'add' || event === 'remove') && collection !== this) return; + if (event === 'destroy') this.remove(model, options); + if (event === 'change') { + var prevId = this.modelId(model.previousAttributes()); + var id = this.modelId(model.attributes); + if (prevId !== id) { + if (prevId != null) delete this._byId[prevId]; + if (id != null) this._byId[id] = model; + } + } + this.trigger.apply(this, arguments); + } + + }); + + // Underscore methods that we want to implement on the Collection. + // 90% of the core usefulness of Backbone Collections is actually implemented + // right here: + var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', + 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', + 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', + 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest', + 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle', + 'lastIndexOf', 'isEmpty', 'chain', 'sample', 'partition']; + + // Mix in each Underscore method as a proxy to `Collection#models`. + _.each(methods, function(method) { + if (!_[method]) return; + Collection.prototype[method] = function() { + var args = slice.call(arguments); + args.unshift(this.models); + return _[method].apply(_, args); + }; + }); + + // Underscore methods that take a property name as an argument. + var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy']; + + // Use attributes instead of properties. + _.each(attributeMethods, function(method) { + if (!_[method]) return; + Collection.prototype[method] = function(value, context) { + var iterator = _.isFunction(value) ? value : function(model) { + return model.get(value); + }; + return _[method](this.models, iterator, context); + }; + }); + + // Backbone.View + // ------------- + + // Backbone Views are almost more convention than they are actual code. A View + // is simply a JavaScript object that represents a logical chunk of UI in the + // DOM. This might be a single item, an entire list, a sidebar or panel, or + // even the surrounding frame which wraps your whole app. Defining a chunk of + // UI as a **View** allows you to define your DOM events declaratively, without + // having to worry about render order ... and makes it easy for the view to + // react to specific changes in the state of your models. + + // Creating a Backbone.View creates its initial element outside of the DOM, + // if an existing element is not provided... + var View = Backbone.View = function(options) { + this.cid = _.uniqueId('view'); + options || (options = {}); + _.extend(this, _.pick(options, viewOptions)); + this._ensureElement(); + this.initialize.apply(this, arguments); + }; + + // Cached regex to split keys for `delegate`. + var delegateEventSplitter = /^(\S+)\s*(.*)$/; + + // List of view options to be merged as properties. + var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; + + // Set up all inheritable **Backbone.View** properties and methods. + _.extend(View.prototype, Events, { + + // The default `tagName` of a View's element is `"div"`. + tagName: 'div', + + // jQuery delegate for element lookup, scoped to DOM elements within the + // current view. This should be preferred to global lookups where possible. + $: function(selector) { + return this.$el.find(selector); + }, + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // **render** is the core function that your view should override, in order + // to populate its element (`this.el`), with the appropriate HTML. The + // convention is for **render** to always return `this`. + render: function() { + return this; + }, + + // Remove this view by taking the element out of the DOM, and removing any + // applicable Backbone.Events listeners. + remove: function() { + this._removeElement(); + this.stopListening(); + return this; + }, + + // Remove this view's element from the document and all event listeners + // attached to it. Exposed for subclasses using an alternative DOM + // manipulation API. + _removeElement: function() { + this.$el.remove(); + }, + + // Change the view's element (`this.el` property) and re-delegate the + // view's events on the new element. + setElement: function(element) { + this.undelegateEvents(); + this._setElement(element); + this.delegateEvents(); + return this; + }, + + // Creates the `this.el` and `this.$el` references for this view using the + // given `el`. `el` can be a CSS selector or an HTML string, a jQuery + // context or an element. Subclasses can override this to utilize an + // alternative DOM manipulation API and are only required to set the + // `this.el` property. + _setElement: function(el) { + this.$el = el instanceof Backbone.$ ? el : Backbone.$(el); + this.el = this.$el[0]; + }, + + // Set callbacks, where `this.events` is a hash of + // + // *{"event selector": "callback"}* + // + // { + // 'mousedown .title': 'edit', + // 'click .button': 'save', + // 'click .open': function(e) { ... } + // } + // + // pairs. Callbacks will be bound to the view, with `this` set properly. + // Uses event delegation for efficiency. + // Omitting the selector binds the event to `this.el`. + delegateEvents: function(events) { + if (!(events || (events = _.result(this, 'events')))) return this; + this.undelegateEvents(); + for (var key in events) { + var method = events[key]; + if (!_.isFunction(method)) method = this[events[key]]; + if (!method) continue; + var match = key.match(delegateEventSplitter); + this.delegate(match[1], match[2], _.bind(method, this)); + } + return this; + }, + + // Add a single event listener to the view's element (or a child element + // using `selector`). This only works for delegate-able events: not `focus`, + // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer. + delegate: function(eventName, selector, listener) { + this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener); + }, + + // Clears all callbacks previously bound to the view by `delegateEvents`. + // You usually don't need to use this, but may wish to if you have multiple + // Backbone views attached to the same DOM element. + undelegateEvents: function() { + if (this.$el) this.$el.off('.delegateEvents' + this.cid); + return this; + }, + + // A finer-grained `undelegateEvents` for removing a single delegated event. + // `selector` and `listener` are both optional. + undelegate: function(eventName, selector, listener) { + this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener); + }, + + // Produces a DOM element to be assigned to your view. Exposed for + // subclasses using an alternative DOM manipulation API. + _createElement: function(tagName) { + return document.createElement(tagName); + }, + + // Ensure that the View has a DOM element to render into. + // If `this.el` is a string, pass it through `$()`, take the first + // matching element, and re-assign it to `el`. Otherwise, create + // an element from the `id`, `className` and `tagName` properties. + _ensureElement: function() { + if (!this.el) { + var attrs = _.extend({}, _.result(this, 'attributes')); + if (this.id) attrs.id = _.result(this, 'id'); + if (this.className) attrs['class'] = _.result(this, 'className'); + this.setElement(this._createElement(_.result(this, 'tagName'))); + this._setAttributes(attrs); + } else { + this.setElement(_.result(this, 'el')); + } + }, + + // Set attributes from a hash on this view's element. Exposed for + // subclasses using an alternative DOM manipulation API. + _setAttributes: function(attributes) { + this.$el.attr(attributes); + } + + }); + + // Backbone.sync + // ------------- + + // Override this function to change the manner in which Backbone persists + // models to the server. You will be passed the type of request, and the + // model in question. By default, makes a RESTful Ajax request + // to the model's `url()`. Some possible customizations could be: + // + // * Use `setTimeout` to batch rapid-fire updates into a single request. + // * Send up the models as XML instead of JSON. + // * Persist models via WebSockets instead of Ajax. + // + // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests + // as `POST`, with a `_method` parameter containing the true HTTP method, + // as well as all requests with the body as `application/x-www-form-urlencoded` + // instead of `application/json` with the model in a param named `model`. + // Useful when interfacing with server-side languages like **PHP** that make + // it difficult to read the body of `PUT` requests. + Backbone.sync = function(method, model, options) { + var type = methodMap[method]; + + // Default options, unless specified. + _.defaults(options || (options = {}), { + emulateHTTP: Backbone.emulateHTTP, + emulateJSON: Backbone.emulateJSON + }); + + // Default JSON-request options. + var params = {type: type, dataType: 'json'}; + + // Ensure that we have a URL. + if (!options.url) { + params.url = _.result(model, 'url') || urlError(); + } + + // Ensure that we have the appropriate request data. + if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { + params.contentType = 'application/json'; + params.data = JSON.stringify(options.attrs || model.toJSON(options)); + } + + // For older servers, emulate JSON by encoding the request into an HTML-form. + if (options.emulateJSON) { + params.contentType = 'application/x-www-form-urlencoded'; + params.data = params.data ? {model: params.data} : {}; + } + + // For older servers, emulate HTTP by mimicking the HTTP method with `_method` + // And an `X-HTTP-Method-Override` header. + if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { + params.type = 'POST'; + if (options.emulateJSON) params.data._method = type; + var beforeSend = options.beforeSend; + options.beforeSend = function(xhr) { + xhr.setRequestHeader('X-HTTP-Method-Override', type); + if (beforeSend) return beforeSend.apply(this, arguments); + }; + } + + // Don't process data on a non-GET request. + if (params.type !== 'GET' && !options.emulateJSON) { + params.processData = false; + } + + // Pass along `textStatus` and `errorThrown` from jQuery. + var error = options.error; + options.error = function(xhr, textStatus, errorThrown) { + options.textStatus = textStatus; + options.errorThrown = errorThrown; + if (error) error.apply(this, arguments); + }; + + // Make the request, allowing the user to override any Ajax options. + var xhr = options.xhr = Backbone.ajax(_.extend(params, options)); + model.trigger('request', model, xhr, options); + return xhr; + }; + + // Map from CRUD to HTTP for our default `Backbone.sync` implementation. + var methodMap = { + 'create': 'POST', + 'update': 'PUT', + 'patch': 'PATCH', + 'delete': 'DELETE', + 'read': 'GET' + }; + + // Set the default implementation of `Backbone.ajax` to proxy through to `$`. + // Override this if you'd like to use a different library. + Backbone.ajax = function() { + return Backbone.$.ajax.apply(Backbone.$, arguments); + }; + + // Backbone.Router + // --------------- + + // Routers map faux-URLs to actions, and fire events when routes are + // matched. Creating a new one sets its `routes` hash, if not set statically. + var Router = Backbone.Router = function(options) { + options || (options = {}); + if (options.routes) this.routes = options.routes; + this._bindRoutes(); + this.initialize.apply(this, arguments); + }; + + // Cached regular expressions for matching named param parts and splatted + // parts of route strings. + var optionalParam = /\((.*?)\)/g; + var namedParam = /(\(\?)?:\w+/g; + var splatParam = /\*\w+/g; + var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; + + // Set up all inheritable **Backbone.Router** properties and methods. + _.extend(Router.prototype, Events, { + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Manually bind a single named route to a callback. For example: + // + // this.route('search/:query/p:num', 'search', function(query, num) { + // ... + // }); + // + route: function(route, name, callback) { + if (!_.isRegExp(route)) route = this._routeToRegExp(route); + if (_.isFunction(name)) { + callback = name; + name = ''; + } + if (!callback) callback = this[name]; + var router = this; + Backbone.history.route(route, function(fragment) { + var args = router._extractParameters(route, fragment); + if (router.execute(callback, args, name) !== false) { + router.trigger.apply(router, ['route:' + name].concat(args)); + router.trigger('route', name, args); + Backbone.history.trigger('route', router, name, args); + } + }); + return this; + }, + + // Execute a route handler with the provided parameters. This is an + // excellent place to do pre-route setup or post-route cleanup. + execute: function(callback, args, name) { + if (callback) callback.apply(this, args); + }, + + // Simple proxy to `Backbone.history` to save a fragment into the history. + navigate: function(fragment, options) { + Backbone.history.navigate(fragment, options); + return this; + }, + + // Bind all defined routes to `Backbone.history`. We have to reverse the + // order of the routes here to support behavior where the most general + // routes can be defined at the bottom of the route map. + _bindRoutes: function() { + if (!this.routes) return; + this.routes = _.result(this, 'routes'); + var route, routes = _.keys(this.routes); + while ((route = routes.pop()) != null) { + this.route(route, this.routes[route]); + } + }, + + // Convert a route string into a regular expression, suitable for matching + // against the current location hash. + _routeToRegExp: function(route) { + route = route.replace(escapeRegExp, '\\$&') + .replace(optionalParam, '(?:$1)?') + .replace(namedParam, function(match, optional) { + return optional ? match : '([^/?]+)'; + }) + .replace(splatParam, '([^?]*?)'); + return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$'); + }, + + // Given a route, and a URL fragment that it matches, return the array of + // extracted decoded parameters. Empty or unmatched parameters will be + // treated as `null` to normalize cross-browser behavior. + _extractParameters: function(route, fragment) { + var params = route.exec(fragment).slice(1); + return _.map(params, function(param, i) { + // Don't decode the search params. + if (i === params.length - 1) return param || null; + return param ? decodeURIComponent(param) : null; + }); + } + + }); + + // Backbone.History + // ---------------- + + // Handles cross-browser history management, based on either + // [pushState](http://diveintohtml5.info/history.html) and real URLs, or + // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) + // and URL fragments. If the browser supports neither (old IE, natch), + // falls back to polling. + var History = Backbone.History = function() { + this.handlers = []; + _.bindAll(this, 'checkUrl'); + + // Ensure that `History` can be used outside of the browser. + if (typeof window !== 'undefined') { + this.location = window.location; + this.history = window.history; + } + }; + + // Cached regex for stripping a leading hash/slash and trailing space. + var routeStripper = /^[#\/]|\s+$/g; + + // Cached regex for stripping leading and trailing slashes. + var rootStripper = /^\/+|\/+$/g; + + // Cached regex for stripping urls of hash. + var pathStripper = /#.*$/; + + // Has the history handling already been started? + History.started = false; + + // Set up all inheritable **Backbone.History** properties and methods. + _.extend(History.prototype, Events, { + + // The default interval to poll for hash changes, if necessary, is + // twenty times a second. + interval: 50, + + // Are we at the app root? + atRoot: function() { + var path = this.location.pathname.replace(/[^\/]$/, '$&/'); + return path === this.root && !this.getSearch(); + }, + + // In IE6, the hash fragment and search params are incorrect if the + // fragment contains `?`. + getSearch: function() { + var match = this.location.href.replace(/#.*/, '').match(/\?.+/); + return match ? match[0] : ''; + }, + + // Gets the true hash value. Cannot use location.hash directly due to bug + // in Firefox where location.hash will always be decoded. + getHash: function(window) { + var match = (window || this).location.href.match(/#(.*)$/); + return match ? match[1] : ''; + }, + + // Get the pathname and search params, without the root. + getPath: function() { + var path = decodeURI(this.location.pathname + this.getSearch()); + var root = this.root.slice(0, -1); + if (!path.indexOf(root)) path = path.slice(root.length); + return path.charAt(0) === '/' ? path.slice(1) : path; + }, + + // Get the cross-browser normalized URL fragment from the path or hash. + getFragment: function(fragment) { + if (fragment == null) { + if (this._hasPushState || !this._wantsHashChange) { + fragment = this.getPath(); + } else { + fragment = this.getHash(); + } + } + return fragment.replace(routeStripper, ''); + }, + + // Start the hash change handling, returning `true` if the current URL matches + // an existing route, and `false` otherwise. + start: function(options) { + if (History.started) throw new Error('Backbone.history has already been started'); + History.started = true; + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? + this.options = _.extend({root: '/'}, this.options, options); + this.root = this.options.root; + this._wantsHashChange = this.options.hashChange !== false; + this._hasHashChange = 'onhashchange' in window; + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); + this.fragment = this.getFragment(); + + // Normalize root to always include a leading and trailing slash. + this.root = ('/' + this.root + '/').replace(rootStripper, '/'); + + // Transition from hashChange to pushState or vice versa if both are + // requested. + if (this._wantsHashChange && this._wantsPushState) { + + // If we've started off with a route from a `pushState`-enabled + // browser, but we're currently in a browser that doesn't support it... + if (!this._hasPushState && !this.atRoot()) { + var root = this.root.slice(0, -1) || '/'; + this.location.replace(root + '#' + this.getPath()); + // Return immediately as browser will do redirect to new url + return true; + + // Or if we've started out with a hash-based route, but we're currently + // in a browser where it could be `pushState`-based instead... + } else if (this._hasPushState && this.atRoot()) { + this.navigate(this.getHash(), {replace: true}); + } + + } + + // Proxy an iframe to handle location events if the browser doesn't + // support the `hashchange` event, HTML5 history, or the user wants + // `hashChange` but not `pushState`. + if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) { + var iframe = document.createElement('iframe'); + iframe.src = 'javascript:0'; + iframe.style.display = 'none'; + iframe.tabIndex = -1; + var body = document.body; + // Using `appendChild` will throw on IE < 9 if the document is not ready. + this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; + this.iframe.document.open().close(); + this.iframe.location.hash = '#' + this.fragment; + } + + // Add a cross-platform `addEventListener` shim for older browsers. + var addEventListener = window.addEventListener || function (eventName, listener) { + return attachEvent('on' + eventName, listener); + }; + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + addEventListener('popstate', this.checkUrl, false); + } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { + addEventListener('hashchange', this.checkUrl, false); + } else if (this._wantsHashChange) { + this._checkUrlInterval = setInterval(this.checkUrl, this.interval); + } + + if (!this.options.silent) return this.loadUrl(); + }, + + // Disable Backbone.history, perhaps temporarily. Not useful in a real app, + // but possibly useful for unit testing Routers. + stop: function() { + // Add a cross-platform `removeEventListener` shim for older browsers. + var removeEventListener = window.removeEventListener || function (eventName, listener) { + return detachEvent('on' + eventName, listener); + }; + + // Remove window listeners. + if (this._hasPushState) { + removeEventListener('popstate', this.checkUrl, false); + } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { + removeEventListener('hashchange', this.checkUrl, false); + } + + // Clean up the iframe if necessary. + if (this.iframe) { + document.body.removeChild(this.iframe.frameElement); + this.iframe = null; + } + + // Some environments will throw when clearing an undefined interval. + if (this._checkUrlInterval) clearInterval(this._checkUrlInterval); + History.started = false; + }, + + // Add a route to be tested when the fragment changes. Routes added later + // may override previous routes. + route: function(route, callback) { + this.handlers.unshift({route: route, callback: callback}); + }, + + // Checks the current URL to see if it has changed, and if it has, + // calls `loadUrl`, normalizing across the hidden iframe. + checkUrl: function(e) { + var current = this.getFragment(); + + // If the user pressed the back button, the iframe's hash will have + // changed and we should use that for comparison. + if (current === this.fragment && this.iframe) { + current = this.getHash(this.iframe); + } + + if (current === this.fragment) return false; + if (this.iframe) this.navigate(current); + this.loadUrl(); + }, + + // Attempt to load the current URL fragment. If a route succeeds with a + // match, returns `true`. If no defined routes matches the fragment, + // returns `false`. + loadUrl: function(fragment) { + fragment = this.fragment = this.getFragment(fragment); + return _.any(this.handlers, function(handler) { + if (handler.route.test(fragment)) { + handler.callback(fragment); + return true; + } + }); + }, + + // Save a fragment into the hash history, or replace the URL state if the + // 'replace' option is passed. You are responsible for properly URL-encoding + // the fragment in advance. + // + // The options object can contain `trigger: true` if you wish to have the + // route callback be fired (not usually desirable), or `replace: true`, if + // you wish to modify the current URL without adding an entry to the history. + navigate: function(fragment, options) { + if (!History.started) return false; + if (!options || options === true) options = {trigger: !!options}; + + // Normalize the fragment. + fragment = this.getFragment(fragment || ''); + + // Don't include a trailing slash on the root. + var root = this.root; + if (fragment === '' || fragment.charAt(0) === '?') { + root = root.slice(0, -1) || '/'; + } + var url = root + fragment; + + // Strip the hash and decode for matching. + fragment = decodeURI(fragment.replace(pathStripper, '')); + + if (this.fragment === fragment) return; + this.fragment = fragment; + + // If pushState is available, we use it to set the fragment as a real URL. + if (this._hasPushState) { + this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url); + + // If hash changes haven't been explicitly disabled, update the hash + // fragment to store history. + } else if (this._wantsHashChange) { + this._updateHash(this.location, fragment, options.replace); + if (this.iframe && (fragment !== this.getHash(this.iframe))) { + // Opening and closing the iframe tricks IE7 and earlier to push a + // history entry on hash-tag change. When replace is true, we don't + // want this. + if (!options.replace) this.iframe.document.open().close(); + this._updateHash(this.iframe.location, fragment, options.replace); + } + + // If you've told us that you explicitly don't want fallback hashchange- + // based history, then `navigate` becomes a page refresh. + } else { + return this.location.assign(url); + } + if (options.trigger) return this.loadUrl(fragment); + }, + + // Update the hash location, either replacing the current entry, or adding + // a new one to the browser history. + _updateHash: function(location, fragment, replace) { + if (replace) { + var href = location.href.replace(/(javascript:|#).*$/, ''); + location.replace(href + '#' + fragment); + } else { + // Some browsers require that `hash` contains a leading #. + location.hash = '#' + fragment; + } + } + + }); + + // Create the default Backbone.history. + Backbone.history = new History; + + // Helpers + // ------- + + // Helper function to correctly set up the prototype chain, for subclasses. + // Similar to `goog.inherits`, but uses a hash of prototype properties and + // class properties to be extended. + var extend = function(protoProps, staticProps) { + var parent = this; + var child; + + // The constructor function for the new subclass is either defined by you + // (the "constructor" property in your `extend` definition), or defaulted + // by us to simply call the parent's constructor. + if (protoProps && _.has(protoProps, 'constructor')) { + child = protoProps.constructor; + } else { + child = function(){ return parent.apply(this, arguments); }; + } + + // Add static properties to the constructor function, if supplied. + _.extend(child, parent, staticProps); + + // Set the prototype chain to inherit from `parent`, without calling + // `parent`'s constructor function. + var Surrogate = function(){ this.constructor = child; }; + Surrogate.prototype = parent.prototype; + child.prototype = new Surrogate; + + // Add prototype properties (instance properties) to the subclass, + // if supplied. + if (protoProps) _.extend(child.prototype, protoProps); + + // Set a convenience property in case the parent's prototype is needed + // later. + child.__super__ = parent.prototype; + + return child; + }; + + // Set up inheritance for the model, collection, router, view and history. + Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend; + + // Throw an error when a URL is needed, and none is supplied. + var urlError = function() { + throw new Error('A "url" property or function must be specified'); + }; + + // Wrap an optional error callback with a fallback error event. + var wrapError = function(model, options) { + var error = options.error; + options.error = function(resp) { + if (error) error(model, resp, options); + model.trigger('error', model, resp, options); + }; + }; + + return Backbone; + +})); diff --git a/upload/project/2014年17月份时事政治全集.docx b/upload/project/2014年17月份时事政治全集.docx new file mode 100644 index 0000000000000000000000000000000000000000..3bf266e750fc5591cc37ad37dc0f7232fbac685c GIT binary patch literal 132666 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
PDRS`Zy5Ui{We2=2Rnw8iX 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 literal 0 HcmV?d00001 diff --git a/upload/project/综合知识与能力素质.docx b/upload/project/综合知识与能力素质.docx new file mode 100644 index 0000000000000000000000000000000000000000..5aa5bc4180fbf81f359b80f8a93f8c46b55d2415 GIT binary patch literal 12467 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", + self.app_name,self.model_name,self.inst.object_id,self.code) + code_link.allow_tags = True + code_link.short_description = _("code") + + def href(self): + import sys + reload(sys) + sys.setdefaultencoding("utf-8") + ct = ContentType.objects.get(app_label=self.app_name,model=self.model_name) + obj = ct.get_object_for_this_type(id=self.inst.object_id) + title = u"%s" % (obj) + return format_html("{}", + self.app_name,self.model_name,self.inst.object_id,title) + def modal_dsc(self): + return u'%s'%(self.inst.modal.name) + modal_dsc.short_description = u'业务流程' + + def start_time(self): + return self.inst.start_time.strftime('%Y-%m-%d %H:%M') + + href.allow_tags = True + href.short_description = _("description") + node_dsc.short_description = _('current node') + + def submitter(self): + if self.inst.starter.last_name or self.inst.starter.first_name: + return u"%s%s"%(self.inst.starter.last_name,self.inst.starter.first_name) + return u"%s"%(self.inst.starter.username) + submitter.short_description = _("submitter") + + class Meta: + verbose_name = _("workflow todo") + verbose_name_plural = _("workflow todo") + ordering = ['user','-arrived_time'] + + +def get_modal(app_label,model_name): + """ + + :param app_label: + :param model_name: + :return: + """ + try: + return Modal.objects.get(app_name=app_label,model_name=model_name) + except Exception,e: + return None + + +def get_instance(obj): + """ + + :param obj: + :return: + """ + if obj and obj._meta: + modal = get_modal(obj._meta.app_label,obj._meta.model_name) + if modal: + try: + return Instance.objects.get(modal=modal,object_id=obj.id) + except Exception,e: + return None + else: + return None diff --git a/workflow/tests.py b/workflow/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/workflow/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/workflow/views.py b/workflow/views.py new file mode 100644 index 0000000..df40cb9 --- /dev/null +++ b/workflow/views.py @@ -0,0 +1,314 @@ +# 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 django.utils.translation import ugettext_lazy as _ +from workflow.models import Modal,Instance,TodoList,History,Node +from plugin.wfnodes import NextNodeManager,NextNodeHandler +from plugin.wfusers import NextUserManager,NextUserHandler +from plugin.wfactions import WorkflowActionManager,WorkflowAction + + +SELECTED_CHECKBOX_NAME = 'NEXT_NODE_USER' + + +def compile_node_handler(request,obj,next_node): + """ + :param request: + :param obj: + :param handler: + :return: + """ + + handler = next_node.handler + next_user_handler = next_node.next_user_handler + # next_user_handler 具有最高优先级 + if next_user_handler: + # print 'it is here' + klass = NextUserManager().handlers.get(next_user_handler) + if klass and isinstance(klass,NextUserHandler): + return klass.handle(request,obj,next_node) + + if handler and handler != '': + handler = handler.replace("submitter()", request.user.username) + handler = handler.replace("suber()", request.user.username) + fields = obj._meta.fields + for field in fields: + name = field.name + temp = "{{%s}}" % name + val = getattr(obj,name,None) + if val: + if type(val)!=str: + val = str(val) + handler = handler.replace(temp,val) + cursor = connection.cursor() + cursor.execute(handler) + rows = [row for row in cursor.fetchall()] + return rows + else: + tp = next_node.handler_type + if tp == 1 and next_node.users: + # user + users = [user for user in next_node.users.all()] + return users + elif tp == 2 and next_node.positions: + # position + users = [] + for position in next_node.positions.all(): + for employee in position.employee_set.all(): + users.append(employee.user) + return users + elif tp == 3 and next_node.roles: + # role + users = [] + for role in next_node.roles.all(): + for user in role.users.all(): + users.append(user) + return users + elif tp == 4: + # submitter + return request.user + else: + return None + + +def start(request,app,model,object_id): + """ + + :param request: + :return: + """ + import datetime + content_type = ContentType.objects.get(app_label=app,model=model) + obj = content_type.get_object_for_this_type(id=int(object_id)) + title = _("Are you sure?") + opts = obj._meta + objects_name = force_text(opts.verbose_name) + has_workflow = False + queryset = Modal.objects.filter(content_type=content_type,end__gt=datetime.date.today()).order_by('-end') + cnt = queryset.count() + workflow_modal = None + next_node = None + next_users = [] + has_next_user = False + if cnt > 0: + has_workflow = True + workflow_modal = queryset[0] + query_start_node = workflow_modal.node_set.filter(start=1) + query_first_node = workflow_modal.node_set.order_by('id') + if query_start_node.count() > 0: + next_node = query_start_node[0] + elif query_first_node.count()>0: + next_node = query_first_node[0] + if next_node: + next_users = compile_node_handler(request,obj,next_node) + if len(next_users) > 0: + has_next_user = True + else: + title = _("No workflow model was found") + + try: + tmp = Instance.objects.get(modal = workflow_modal,object_id=object_id) + messages.warning(request,_("the object is already in workflow")) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + except Exception: + pass + + if request.POST.get("post"): + val = request.POST.getlist(SELECTED_CHECKBOX_NAME) + workflow_inst = Instance.objects.create(modal=workflow_modal,object_id=object_id,starter=request.user) + workflow_inst.current_nodes.add(next_node) + workflow_inst.save() + workflow_history = History.objects.create(inst=workflow_inst,user=request.user) + for user in User.objects.filter(id__in=val): + todo = TodoList.objects.create(inst=workflow_inst,node=next_node,user=user,app_name=app,model_name=model) + TodoList.objects.create(inst=workflow_inst,user=request.user,app_name=app,model_name=model,is_read=True, + read_time=datetime.datetime.now(),status=True) + if next_node.status_field and next_node.status_value: + try: + setattr(obj,next_node.status_field,next_node.status_value) + obj.save() + except Exception,e: + pass + messages.success(request,_('workflow started successfully')) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + + context = dict( + site.each_context(request), + title=title, + opts=opts, + objects_name=objects_name, + object=obj, + has_workflow = has_workflow, + workflow_modal = workflow_modal, + next_node = next_node, + has_next_user = has_next_user, + next_users = next_users, + checkbox_name = SELECTED_CHECKBOX_NAME, + ) + request.current_app = site.name + + return TemplateResponse(request,'default/workflow/workflow_start_confirmation.html', context) + + +def approve(request,app,model,object_id,operation): + """ + + :param request: + :param operation: + :return: + """ + if operation not in ('1','3','4'): + messages.warning(request,_("unkown workflow operation")) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + + import datetime + import copy + content_type = ContentType.objects.get(app_label=app,model=model) + obj = content_type.get_object_for_this_type(id=int(object_id)) + title = _("Are you sure?") + opts = obj._meta + objects_name = force_text(opts.verbose_name) + + has_workflow = False + queryset = Modal.objects.filter(content_type=content_type,end__gt=datetime.date.today()).order_by('-end') + cnt = queryset.count() + workflow_modal = None + if cnt > 0: + workflow_modal = queryset[0] + else: + messages.warning(request,_("No workflow model was found")) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + workflow_instance = None + try: + workflow_instance = Instance.objects.get(modal = workflow_modal,object_id=object_id) + except Exception: + messages.warning(request,_("please start the workflow first")) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + + next_nodes = [] + node_users = [] + is_stop_node = False + node_has_users = False + delete_instance = False + deny_to_first = False + next_node_description = None + all_nodes =[x for x in Node.objects.filter(modal=workflow_modal).order_by('-id')] + current = workflow_instance.current_nodes.all() + current_tmp = copy.deepcopy(current[0]) + if operation == '4' or operation == '3': + next_nodes = ['stop'] + is_stop_node = True + else: + if current.count() > 1: + pass + else: + tmp_node = current[0] + if tmp_node.stop or tmp_node == all_nodes[0]: + next_nodes = ['stop'] + is_stop_node = True + else: + if tmp_node.next_node_handler and len(tmp_node.next_node_handler) > 0: + hd = tmp_node.next_node_handler + klass = NextNodeManager().handlers.get(hd) + if klass and isinstance(klass,NextNodeHandler): + next_nodes = klass.handle(request,obj,tmp_node) + next_node_description = klass.description + if next_nodes and len(next_nodes) > 0: + pass + elif tmp_node.next and tmp_node.next.count()>0: + next_nodes = [nd for nd in tmp_node.next.all()] + else: + position = all_nodes.index(tmp_node) + next_nodes = [all_nodes[position-1]] + + if request.POST.get("post"): + from django.db import transaction + val = request.POST.getlist(SELECTED_CHECKBOX_NAME) + memo = request.POST['memo'] + with transaction.atomic(): + try: + if delete_instance: + workflow_instance.delete() + else: + if is_stop_node: + workflow_instance.status = 99 + if operation in ('3', '4'): + workflow_instance.status = int(operation) + if not workflow_instance.approved_time and operation == '1': + workflow_instance.approved_time = datetime.datetime.now() + workflow_instance.current_nodes.clear() + workflow_instance.save() + else: + workflow_instance.current_nodes.clear() + workflow_instance.current_nodes.add(next_nodes[0]) + for user in User.objects.filter(id__in=val): + todo = TodoList.objects.create(inst=workflow_instance,node=next_nodes[0],user=user,app_name=app,model_name=model) + if current_tmp.status_field and current_tmp.status_value: + try: + setattr(obj,current_tmp.status_field,current_tmp.status_value) + obj.save() + except Exception,e: + pass + History.objects.create(inst=workflow_instance,user=request.user,pro_type=int(operation),memo=memo,node=current_tmp) + TodoList.objects.filter(inst=workflow_instance,node=current_tmp,status=0).update(status=1) + messages.success(request,_('workflow approved successfully')) + except Exception,e: + messages.error(request,e) + pass + if current_tmp.action and len(current_tmp.action) > 0: + action = WorkflowActionManager().actions.get(current_tmp.action) + if action and isinstance(action,WorkflowAction): + action.action(request,obj,current_tmp,operation) + + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) + + if len(next_nodes) > 0 and not is_stop_node and operation == '1': + for node in next_nodes: + users = compile_node_handler(request,obj,node) + if len(users) > 0: + node_has_users = True + node_users.append({'node':node,'users':users}) + + context = dict( + site.each_context(request), + title=title, + opts=opts, + objects_name=objects_name, + object=obj, + operation = operation, + is_stop_node = is_stop_node, + delete_instance = delete_instance, + node_users = node_users, + node_has_users = node_has_users, + checkbox_name = SELECTED_CHECKBOX_NAME, + ) + if next_node_description: + context.update(dict(next_node_description=next_node_description)) + return TemplateResponse(request,"default/workflow/workflow_approve_confirmation.html",context) + + +def restart(request,app,model,object_id,instance): + """ + + :param request: + :param app: + :param model: + :param object_id: + :return: + """ + try: + inst = Instance.objects.get(id=int(instance)) + if request.user == inst.starter: + inst.delete() + messages.success(request,_("workflow restarted success")) + else: + messages.warning(request,_("you do not have the permission to restart,only the starter can restart")) + except Exception,e: + messages.error(request,e) + return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id)) \ No newline at end of file