物业系统信息转U8凭证

碰到一个客户 ,客户U8的凭证是根据 物业系统提供的数据来录入凭证的, 他们现在想如果物业系统中已经录入了数据,那么他们就没必要录入数据了。

需求:将物业系统的数据通过一个方法转成U8凭证

 解决方法:自建转化工具,使物业系统信息转成U8凭证信息

使用语言: python 

涉及知识点:OOP  邮件发送 

程序成熟度: 二星(满分五星,基本实现功能)

转化流程:

 

 

 

 

物业Excel表头:

 

所需要Excel内容:

小区名 户数  缴纳银行   银行账号 费用类型 额度

一共用到 两种费用类型: 缴存 续交 续缴  归为收入类,支出 和退款 ,其中退款涉及利息,此利息为银行所计,故无法对此编写相应程序

 会计分录:

收入类:

摘要                                                                 会计科目                             借方             贷方
小区(*)转来维修基金共户数(*)            银行存款下级科目               小区额度
小区(*)转来维修基金共户数  (*)     .     ..../代收维修基金(挂客户辅助)      小区额度


支出:

小区(*)申请使用维修资金共资金数(*)  ../待收维修资金(挂客户辅助)        小区额度
小区(*)申请使用维修资金共资金数(*)    银行存款下级科目                          小区额度

 

代码:

涉及自定义类:Accvouch(凭证类)  DataBase(数据库类)  Dialog(弹出对话框类)  FileTool(文件处理类)  Login(主界面类) Register(注册类)

Accvouch:


class Accvouch:
    #data(hash)  ino_id(凭证Id),inid(凭证编号),ccode,cdigest,md(借方),mc(贷方),cCusCode(客户编码)
    def __init__(self,data):
        self.iyear=data["iyear"]
        self.iperiod=data["iperiod"]
        self.dbill_date=self.iyear+"-"+self.iperiod+"-"+data["day"]
        self.ino_id=data["ino_id"]
        self.inid=data["inid"]
        self.ccode=data["ccode"]
        self.cdigest=data["cdigest"]
        self.md=data["md"]
        self.mc=data["mc"]
        self.cCusCode=data["cCusCode"]

DataBase:


"""数据库类 处理关于数据库的各种操作方法"""
import pymssql
class DataBase:
    #server  数据库服务器名称
    #user    用户名
    #password  密码
    #database  数据库名称
    #connectState 连接状态  1表示成功  0表示失败
    def __init__(self,server,password,user="sa",database="master"):
        try:
            #print(server,password)
            self.conn=pymssql.connect(server,user,password,database)
            self.connectState=1
        except:
            self.connectState=0
    #生成游标
    def CreateCursor(self):
        self.cursor=self.conn.cursor()
    #查询语句
    #option=0 为查询会计科目表,option=1为查询客户档案表,2为查询账套,3为查询凭证中最大的凭证号
    def SelectTool(self,option,database="master"):
        sqlStr=""
        if(option==0):
            tableSql="["+database+"]"+".[dbo].[code]"
            sqlStr="%s %s %s"%("select ccode,ccode_name from",tableSql,"where ccode like '10020%' and ccode_name like '%(专户%)'  group by  ccode,ccode_name order by  ccode_name")
        elif (option==1):
            tableSql="["+database+"]"+".[dbo].[customer]"
            sqlStr="%s %s %s"%("select   cCusCode,cCusAbbName from",tableSql,"group by  cCusCode,cCusAbbName")
        elif(option==2):
            tableSql="["+database+"]"+".[dbo].[sysdatabases]"
            #print("数据库:",tableSql)
            sqlStr="%s %s %s"%("select name from",tableSql,"where  name like 'UFDATA_%'")
            #print("查询语句:",sqlStr)
        elif(option==3):
            tableSql="["+database+"]"+".[dbo].[gl_accvouch]"
            sqlStr="%s %s "%("select max(ino_id) from",tableSql)
        self.cursor.execute(sqlStr)
    def CloseConn(self):
        self.conn.close()









Dialog:

from  tkinter import  *
class Dialog:
    #param info 错误消息
    def  Alert(info):
        win=Toplevel()
        Dialog.CenterMainCenter(win,400,50)
        Label(win,text=info).pack()
        Button(win,text="确定",command=win.quit).pack()
        win.protocol("WM_DELETE_WINDOW",win.quit)

        win.focus_set()
        win.grab_set()
        win.mainloop()
        win.destroy()
        #设置主窗口大小
    def CenterMainCenter(root,width,height):
        screenWidth=root.winfo_screenwidth()
        screenHeight=root.winfo_screenheight()
        size=("%dx%d+%d+%d"%(width,height,(screenWidth-width)/2,(screenHeight-height)/2))
        root.geometry(size)

 

FileTool:

__author__ = 'i'
"""文件工具类,主要负责文件的写入和读取"""
import os
from  Accvouch import  *
import datetime
import openpyxl
import  shelve
import shutil
import  numpy
import  pandas
import smtplib
from Dialog import  *
from email.mime.text import MIMEText
class  FileTool:
    #初始化,得到当前的工作路径
    def __init__(self):
        self.pathWork=os.getcwd()
        #类初始化就创建文件对象
        self.Record()
    #操作档案方法:
    #档案方法,得到关于Code和Customer文件的操作对象 对象应该为内部对象
    def Record(self):
        self._pathCodeTxt=self.pathWork+"\\data\\code"    #得到Code文件路径
        self._pathCustomerTxt=self.pathWork+"\\data\\customer" #得到customer文件路径
        self._pathRegisterTxt=self.pathWork+"\\data\\register" #得到register文件路径

        self._shelfFile_code=shelve.open(self._pathCodeTxt)
        self._shelfFile_customer=shelve.open(self._pathCustomerTxt)
        self._shelfFile_register=shelve.open(self._pathRegisterTxt)
    #写入档案 arg为 {},param arg={"key":object} 根据key来写入档案  写入文件的数据类型为{}
    def WriteRecord(self,arg):
        key=(list(arg.keys()))[0]
        if(key=="codes"):
            value=arg["codes"]
            self._shelfFile_code[key]=value
        elif(key=="customer"):
            value=arg["customers"]
            self._shelfFile_customer[key]=value
        elif(key=="register"):
            value=arg["register"]
            currentTime=datetime.datetime.now().strftime("%Y-%m-%d")
            strs=currentTime.split("-")
            year=strs[0]  #获取年
            month=strs[1] #获取月
            day=strs[2]   #获取日
            effectivedTime=""

            month_int=(int)(month)+3      #有效期为当前日期往后推3个月
            if(month_int>12):  #表示要往年进位
                monthReal=month_int-12    #真实的月份
                yearReal=(int)(year)+1   #真实的年份
                effectivedTime="%s-%s-%s"%(str(yearReal),str(monthReal),day)
            else:              #否则不进位
                effectivedTime="%s-%s-%s"%(str(year),str(month_int),day)
            reg={"effectivedTime":effectivedTime}
            self._shelfFile_register[key]=reg
    #读取档案,parm  option=0 则只读code, option=1 则只读 customer  option=2 则读取code和customer  option=3 则读取注册码
    #return :objet code or  object  customer object or hash (customer and code)  register:{}
    def ReadRecord(self,option):
        if(option==0):
            return self._shelfFile_code["codes"]
        elif(option==1):
            return self._shelfFile_customer["customers"]
        elif(option==2):
            codes=self._shelfFile_code["codes"]
            customers=self._shelfFile_customer["customers"]
            codsAndCus={"codes":codes,"customers":customers}
            return codsAndCus
        elif(option==3):
            if( self._shelfFile_register!=None and  "register" in self._shelfFile_register.keys()):
                register=self._shelfFile_register['register']
                return register
            else:
                return None
            #操作Excel方法
            #处理Excel return  style={"salarys":salarys,"consumes":consumes,"refunds":refunds} 目标 筛选出小区,户数,小区总额
    #处理物业Excel表  param filePath:物业系统缴纳表路径 return  style={"salarys":salarys,"consumes":consumes,"refunds":refunds}
    # 目标 筛选出小区,户数,小区总额
    def  ManageEstate(self,filePath):
        #salary:{小区名:{房间数:,收入:,银行:}....}
        #测试用缴纳表路径
       # filePath=r"E:\TransferData\sources\缴纳表.xlsx"
        wb=openpyxl.load_workbook(filePath)  #得到工作簿对象
        sheet=wb["导出工作表"]              #得到工作表对象
        maxRow=sheet.max_row              #得到最大行

        #先筛选出状态,查看是收入 支出 还是退款,然后再插入比较妥当
        salaryRow=[]
        consumeRow=[]
        refundRow=[]

        #收入 、支出、退款 数组
        salarys=[]
        consumes=[]
        refunds=[]
        #循环遍历 N2...
        for row in range(2,maxRow+1):
            currentN="N"+str(row)
            state=(str(sheet[currentN].value)).strip()  #是什么状态(1.收入 2是退款 4使用)  记得去掉首尾前后空格
            if(state==str(1) or state==str(3) or  state==str(5)):
                #print("触发1")
                salaryRow.append(row)
            elif(state==str(2)):
                #print("触发2")
                refundRow.append(row)
            elif(state==str(4)):
                #print("触发4")
                consumeRow.append(row)
        """print("------------收入行--------------")
        print(salaryRow)
        print("------------退款行--------------")
        print(refundRow)
        print("------------支出行--------------")
        print(consumeRow)"""
        #循环遍历A2..  E2..  O2..
        #对收入进行处理  #salarys[{"estateName":estateName,"houseSum":houseSum,"moneySum":moneySum},...]
        if(len(salaryRow)>0):
            for num in  salaryRow:
                currentA="A"+str(num)
                currentE="E"+str(num)
                currentO="O"+str(num)
                currentK="K"+str(num)

                estateName=(sheet[currentA].value) #得到小区名
                houseSum=sheet[currentE].value  #得到户数
                moneySum=sheet[currentO].value  #得到金额总数
                bankName=(sheet[currentK].value)  #银行名称

                estate={"estateName":estateName,"houseSum":houseSum,"moneySum":moneySum,"bankName":bankName}

                salarys.append(estate)
        #对支出进行处理
        if(len(consumeRow)>0):
            for num in  consumeRow:
                currentA="A"+str(num)
                currentE="E"+str(num)
                currentO="O"+str(num)
                currentK="K"+str(num)


                estateName=(sheet[currentA].value)  #得到小区名
                houseSum=sheet[currentE].value  #得到户数
                moneySum=sheet[currentO].value  #得到金额总数
                bankName=(sheet[currentK].value) #银行名称

                estate={"estateName":estateName,"houseSum":houseSum,"moneySum":moneySum,"bankName":bankName}

                consumes.append(estate)
        #退款未处理

        """print("--------------收入-------------------")

        for salary in salarys:
            print("小区名:%s  户数:%s  金额:%s "%(salary["estateName"],salary["houseSum"],salary["moneySum"]))

        print("--------------支出-------------------")

        for consume in consumes:
            print("小区名:%s  户数:%s  金额:%s "%(consume["estateName"],consume["houseSum"],consume["moneySum"]))
        """
        style={"salarys":salarys,"consumes":consumes,"refunds":refunds}
        return style
    # 消除物业系统与U8系统凭证差异 maxAccNum:为最大凭证号 return :accvouch( u8 object) data{} 为 年(iyear) 月(iperiod) 日(day)的集合
    def   EstDescription(self,style,maxAccNum,datas):
        #style=ManageEstate()  #得到物业系统所需数据
        #读取档案
        """pathWork=os.getcwd()  #得到当前的工作路径
        pathCodeTxt=pathWork+"\\data\\code"    #得到Code文件路径
        pathCustomerTxt=pathWork+"\\data\\customer" #得到customer文件路径"""

       # self.shelfFile_code=shelve.open(self._pathCodeTxt)
       #self.shelfFile_customer=shelve.open(self._pathCustomerTxt)

        #得到银行科目对象
        codes=self._shelfFile_code["codes"]
        #得到customer对象
        customers=self._shelfFile_customer["customers"]
        #取得物业系统中收入
        salarys=style["salarys"]
        #取得物业系统中支出
        consumes=style["consumes"]
        #取得物业系统中退款
        refunds=style["refunds"]
        #accvouchs为accvouch集合
        accvouchs=[]
        #插入凭证表
        codeSingle="23050301"  #代收维修基金编码
        #对收入进行处理  #salarys[{"estateName":estateName,"houseSum":houseSum,"moneySum":moneySum,"bankName":bankName},...]
        #收入
        ino_id=maxAccNum  #凭证编号
        #凭证 年 月 日 (下面赋值的测试用的年 月 日 可删除)
        iyear=datas["iyear"]
        iperiod=datas["iperiod"]
        day=datas["day"]
       # iyear="2017"
        #iperiod="10"
        #day="11"
        id=1
        for salary in salarys:
            estateName=(salary["estateName"]).strip()  #小区名
            houseSum=salary["houseSum"]      #户数
            moneySum=salary["moneySum"]      #总金额
            cdigest=estateName+"转来维修基金共"+str(houseSum)+"户" #摘要
            try:
                bankName=(salary["bankName"]).strip()      #银行名称
                cCusCode=customers[estateName]    #客户编码
                ccode=codes[bankName]           #银行编码
            except:
                Dialog.Alert("物业信息与U8信息存在差异,无法转换数据....")
                return
            #创建accvouch对象
            #id 为Excel凭证ID
            #inid为控制2行分录
            for  inid in range(1,3):
                #表示在借方
                if(inid==1):
                    data={"ino_id":ino_id,"inid":id,"ccode":ccode,"cdigest":cdigest,"md":moneySum,"mc":"","cCusCode":""
                    ,"iyear":iyear,"iperiod":iperiod,"day":day}
                elif(inid==2):
                    data={"ino_id":ino_id,"inid":id,"ccode":codeSingle,"cdigest":cdigest,"md":"","mc":moneySum,"cCusCode":cCusCode,
                          "iyear":iyear,"iperiod":iperiod,"day":day}
                accvouch=Accvouch(data)
                accvouchs.append(accvouch)
            ino_id+=1  #凭证编号+1
            id+=1
        #支出
        for consume in  consumes:
            estateName=(consume["estateName"]).strip()  #小区名
            houseSum=consume["houseSum"]      #户数
            moneySum=consume["moneySum"]      #总金额
            cdigest=estateName+"转来维修基金共"+str(houseSum)+"户"#摘要
            try:
                bankName=(consume["bankName"]).strip()      #银行名称
                cCusCode=customers[estateName]    #客户编码
                ccode=codes[bankName]             #银行编码
            except:
                Dialog.Alert("物业信息与U8信息存在差异,无法转换数据....")
                return
            for  inid in range(1,3):
                #表示在借方
                if(inid==1):
                    data={"ino_id":ino_id,"inid":id,"ccode":codeSingle,"cdigest":cdigest,"md":moneySum,"mc":"","cCusCode":cCusCode
                    ,"iyear":iyear,"iperiod":iperiod,"day":day}
                #表示贷方
                elif(inid==2):
                    data={"ino_id":ino_id,"inid":id,"ccode":ccode,"cdigest":cdigest,"md":"","mc":moneySum,"cCusCode":"",
                          "iyear":iyear,"iperiod":iperiod,"day":day}
                accvouch=Accvouch(data)
                accvouchs.append(accvouch)
            ino_id+=1  #凭证编号+1
            id+=1  #凭证编号+1
        return accvouchs
    # 将转化后的数据插入U8模板中    accvouchs: accvouch 集合  dirPath:转化后的U8Excel表存放路径
   #   U8 Excel  为 .xlsx格式
    #return state=0 转换失败  1转换成功
    def InsertIntoU8Excel(self,accvouchs,dirPath):
        #测试转化后的U8Excel表存放路径
        #dirPath=self.pathWork+'\\sources\\'
        i=datetime.datetime.now()
        #模板
        modalPath=self.pathWork+r"\modal\凭证.xlsx"
        #拷贝到指定路径
        transName="%s%s%s%s%s%s%s%s"%(dirPath,i.year,i.month,i.day,i.hour,i.minute,round(10),".xlsx")
        transName_real="%s%s%s%s%s%s%s%s"%(dirPath,i.year,i.month,i.day,i.hour,i.minute,round(10),".xls")
        shutil.copy(modalPath,transName)

        #操作模板
        wb=openpyxl.load_workbook(transName)
        sheet=wb["Sheet1"]
        maxRow=sheet.max_row  #得到最大行
        try:
            for accvouch in accvouchs:
                A=accvouch.inid
                B=accvouch.iyear
                C=accvouch.iperiod
                D=accvouch.dbill_date
                E="记"
                F=accvouch.ino_id
                G="demo"
                K=accvouch.ccode
                L=accvouch.cdigest
                P="人民币"
                W=accvouch.md
                X=accvouch.mc
                AA=accvouch.cCusCode
                sheet["A"+str(maxRow+1)].value=A
                sheet["B"+str(maxRow+1)].value=B
                sheet["C"+str(maxRow+1)].value=C
                sheet["D"+str(maxRow+1)].value=D
                sheet["E"+str(maxRow+1)].value=E
                sheet["F"+str(maxRow+1)].value=F
                sheet["G"+str(maxRow+1)].value=G
                sheet["K"+str(maxRow+1)].value=K
                sheet["L"+str(maxRow+1)].value=L
                sheet["P"+str(maxRow+1)].value=P
                sheet["W"+str(maxRow+1)].value=W
                sheet["X"+str(maxRow+1)].value=X
                sheet["AA"+str(maxRow+1)].value=AA
                maxRow+=1
        except:
            os.unlink(transName)  #失败后删除文件
            return  0
        wb.save(transName)
        primExcel=pandas.read_excel(transName,converters={u'客户编码':str,u'借方金额':str,u'贷方金额':str})
        #将.xlsx文件转为xls文件
        primExcel.to_excel(transName_real,index=False)
        #删除文件
        os.unlink(transName)
        return 1
    #U8 Excel 为 .xls格式  和   tkinter 使用 出现bug ,废弃
    def  InsertIntoU8Excel_v2(self,accvouchs,dirPath):
        #测试转化后的U8Excel表存放路径
        #dirPath=self.pathWork+'\\sources\\'
        i=datetime.datetime.now()
        #模板
        modalPath=self.pathWork+r"\modal\凭证.xls"
        #拷贝到指定路径
        self.transName="%s%s%s%s%s%s%s%s"%(dirPath,i.year,i.month,i.day,i.hour,i.minute,round(10),".xls")
        shutil.copy(modalPath,self.transName)
        #操作模板
        book=xlrd.open_workbook(self.transName)
        sheet=book.sheet_by_index(0)
        maxRow=sheet.nrows  #得到最大行
        for accvouch in accvouchs:
            A=accvouch.inid
            B=accvouch.iyear
            C=accvouch.iperiod
            D=accvouch.dbill_date
            E="记"
            F=accvouch.ino_id
            G="demo"
            K=accvouch.ccode
            L=accvouch.cdigest
            P="人民币"
            W=accvouch.md
            X=accvouch.mc
            AA=accvouch.cCusCode
            sheet.put_cell(maxRow+1,1,1,A,0)
            sheet.put_cell(maxRow+1,2,1,B,0)
            sheet.put_cell(maxRow+1,3,1,C,0)
            sheet.put_cell(maxRow+1,4,1,D,0)
            sheet.put_cell(maxRow+1,5,1,F,0)
            sheet.put_cell(maxRow+1,6,1,G,0)
            sheet.put_cell(maxRow+1,10,1,K,0)
            sheet.put_cell(maxRow+1,11,1,L,0)
            sheet.put_cell(maxRow+1,15,1,P,0)
            sheet.put_cell(maxRow+1,22,1,W,0)
            sheet.put_cell(maxRow+1,23,1,X,0)
            sheet.put_cell(maxRow+1,26,1,AA,0)
            maxRow+=1
        wb=copy(book)
        wb.save(self.transName)
    #params  filePath 物业信息文件 U8ExcelPath U8存放文件  maxAccNum  数据库凭证中最大凭证号  datas:accvouchs
    #return  state  1  表示转化成功  0 表示转换失败
    def  TransEstateToU8(self,filePath,u8ExcelPath,maxAccNum,datas):
        style=self.ManageEstate(filePath)
        accvouchs=self.EstDescription(style,maxAccNum,datas)
        state=self.InsertIntoU8Excel(accvouchs,u8ExcelPath)
        return  state
        #self.InsertIntoU8Excel_v2(accvouchs,u8ExcelPath)
        #print("转换成功.......")
    #保存数据库实例和密码至datainfo.txt文件中
    def  SaveDataInfo(self,instance,password):
        file=open(self.pathWork+"\\data\\datainfo.txt","w")
        file.write("%s,%s"%(instance,password))
        file.close()
    #得到datainfo.txt文件的实例和密码 return  data:{instance;password}
    def GetDataInfo(self):
        file=open(self.pathWork+"\\data\\datainfo.txt")
        data=file.read()
        strs=data.split(",")
        instance=""
        password=""
        if(len(strs)>0):   #说明有数据
            instance=strs[0]
            password=strs[1]
        datas={"instance":instance,"password":password}
        return datas
    #向数据库中写入注册码 param:register(注册码) return state=0 失败 state=1成功
    def WriteRegister(self,register):
        arg={"register":register}
        try:
            self.WriteRecord(arg)
            return 1
        except:
            return 0
    #向邮箱发送注册码 param info{key=0 注册码  key=1 获取密码}  return 0:发送失败  1 :发送成功
    def SendEmail(self,info):
        userEmail="发送邮箱"
        pwd="发送邮箱授权码"
        to="接收邮箱"
        subject=""
        self.information=""
        if(list(info.keys())[0]=="0"):  #获取注册码
            self.imformation=info["0"]
            subject="物业信息转换U8凭证注册码"
        elif(list(info.keys())[0]=="1"):  #获取密码
            self.imformation=info["1"]
            subject="物业信息转换U8凭证密码"
        msg=MIMEText(self.imformation)
        msg["Subject"]=subject
        msg["From"]=userEmail
        msg["To"]=to
        try:
            s=smtplib.SMTP_SSL("smtp.qq.com",465)
            s.login(userEmail,pwd)
            s.sendmail(userEmail,to,msg.as_string())
            s.quit()
            return 1
        except:
            return 0
    #判断注册码是否有效
    #return  state=0  无效  state=1 有效
    def   RegisterState(self):
        register=self.ReadRecord(3)
        if(register==None):
            return  0
        effectivedTime=register['effectivedTime']
        currentTime=datetime.datetime.now().strftime('%Y-%m-%d')
        if(currentTime>effectivedTime):    #若当前时间大于有效时间  则无效
            return  0
        else:
            return 1

































 

Login:

__author__ = 'i'
from  tkinter import *
import tkinter;
from tkinter import  filedialog
from  tkinter import ttk
from DataBase import *
from  FileTool import  *
from Dialog import  *
class Login:
    """生成表单"""
    # ents [] , 0-"数据库实例:",1-"sa密码:",2-"会计年度",3-"会计期间",4-"日" ,5-账套下拉框,
    # 6-物业Excel文件路径 7-存储文件路径,8-转换按钮
    def MakeForm(self,root,fields):
        #添加背景图片
        entries=[]
        for field in fields:
            row=Frame(root)
            lab=Label(row,width=15,text=field)
            ent=Entry(row,width=20)
            row.pack(side=TOP,fill=X,pady=5)
            #row.pack(side=TOP)
            lab.pack(side=LEFT)
            ent.pack(side=RIGHT,expand=YES,fill=X)
            #ent.pack(side=LEFT)
            entries.append(ent)
        #账套下拉框
        row=Frame(self.root)
        lab=Label(row,width=15,text="账套:")
        comvalue=StringVar()
        comboxlist=ttk.Combobox(row,textvariable=comvalue)
        comboxlist.bind("<Button-1>",self.OnLeftClick)
        row.pack(side=TOP,fill=X)
        lab.pack(side=LEFT)
        comboxlist.pack(side=LEFT)
        entries.append(comboxlist)
        #初始化账套下拉框为不可用状态
        comboxlist.config(state="disable")
        #选择Excel文件
        row=Frame(root)
        lab=Label(row,width=15,text="物业系统Excel文件:")
        row.pack(side=TOP,fill=X)
        lab.pack(side=LEFT)
        lab_filePath=Label(row,width=30,text="")  #显示文件路径
        lab_filePath.pack(side=LEFT)
        btn_file=Button(row,text="选择文件")
        btn_file.config(relief=SUNKEN)
        btn_file.pack(side=RIGHT)
        btn_file.bind("<Button-1>",self.GetFilePath)
        entries.append(lab_filePath)

        #存放路径
        row=Frame(root)
        lab=Label(row,width=15,text="存储文件路径:")
        row.pack(side=TOP,fill=X)
        lab.pack(side=LEFT)
        lab_storePath=Label(row,width=30,text="")  #显示文件路径
        lab_storePath.pack(side=LEFT)
        btn_store=Button(row,text="选择存放文件路径")
        btn_store.config(relief=SUNKEN)

        btn_store.pack(side=RIGHT) #绑定事件,取出选择的文件路径
        btn_store.bind("<Button-1>",self.StoreFilePath)

        entries.append(lab_storePath)

        #转换按钮
        row=Frame(root)
        row.pack(side=TOP,fill=X)
        btn_transform=Button(root,text="转换文件")
        btn_transform.bind("<Button-1>",self.Transform)
        btn_transform.pack(side=TOP)
        btn_transform.config(relief=SUNKEN)
        entries.append(btn_transform)        #存储转换按钮
        #entries[8].config(state="disable")

        #初始化禁用转换按钮
        btn_transform.config(state="disable")
        #测试时设置数据库和sa密码,完成后删除
        """entries[0].insert(0,"whs")
        entries[1].insert(0,"88832741")"""
        self.ents=entries
        #加载数据库实例和密码
        datas=self.fileTool.GetDataInfo()
        if(datas !=None):
            self.ents[0].insert(0,datas["instance"])
            self.ents[1].insert(0,datas["password"])
    #Excel转换为U8模板所需数据绑定事件
    def Transform(self,event):
        #会计年度  会计期间 日 是否符合规范
        iyear=self.ents[2].get()
        imonth=self.ents[3].get()
        day=self.ents[3].get()
        try:
            int(iyear)
            int(imonth)
            int(day)
        except:
            Dialog.Alert("会计年度 会计期间 日期必须输入且不可出现非法字符....")
            return
        if((iyear==None or len(iyear)!=4)or (imonth==None or len(imonth)>2) or (day==None or len(day)>2)):
            Dialog.Alert("会计年度为4位 会计期间最多为2位 日期最多为4位....")
            return
        attributes=dir(self)
        if("pathFile"not in  attributes or  "pathFolder" not  in attributes):
            Dialog.Alert("请选择物业源文件和存放U8 Excel路径....")
            return
        self.database.SelectTool(option=0,database=self.ledger)              #查询银行Code
        row=self.database.cursor.fetchone()
        codes={}
        while row:
            ccode=(row[0])
            ccode_name=(row[1])
            #对银行分割字符串  ---这样的话就可以对应物业系统的银行科目了
            #“(”或"("字符串索引
            nameStr=list(ccode_name)
            index=0;
            for  str in nameStr:
                if(str=="("or str=="("):break
                else:index+=1
            ccode_realName=ccode_name[0:index]
            codes[ccode_realName]=ccode
            row=self.database.cursor.fetchone()
        #保存Code对象
        self.fileTool.WriteRecord({"codes":codes})
        codes=None
        #同步U8 Customer至文件中
        self.database.SelectTool(option=1,database=self.ledger)              #查询客户档案
        row=self.database.cursor.fetchone()
        customers={}
        while row:
            cCusCode=(row[0])
            cCusAbbName=(row[1])
            customers[cCusAbbName]=cCusCode
            row=self.database.cursor.fetchone()
        self.fileTool.WriteRecord({"customers":customers})
        customers=None
        #取得最大凭证号
        self.database.SelectTool(option=3,database=self.ledger)
        row=self.database.cursor.fetchone()
        maxIno_id=row[0]
        #转换数据
        datas={"iyear":self.ents[2].get(),"iperiod":self.ents[3].get(),"day":self.ents[4].get()}
        #测试文件路径  可删
        """self.pathFile=""
        self.pathFolder="""""
        state=self.fileTool.TransEstateToU8(self.pathFile,self.pathFolder,maxIno_id,datas)
        attributes=dir(self)
        if("databaseIdentity"in attributes and "password"in attributes):
            self.fileTool.SaveDataInfo(self.databaseIdentity,self.password)
        if(state==1):
            Dialog.Alert("转换成功.....")
        else:
            Dialog.Alert("转换失败")
    def  StoreFilePath(self,event):
        dick_Path=filedialog.askdirectory()
        if dick_Path !="":
            self.ents[7].config(text="文件存放路径:"+dick_Path)
            self.pathFolder=dick_Path
        else:
            self.ents[7].config("选择存放文件路径")
    #文件路径事件
    def  GetFilePath(self,event):
        file_path=filedialog.askopenfilename()
        if file_path !="":
            self.ents[6].config(text="文件路径:"+file_path)
            self.pathFile=file_path    #存储文件路径
        else:
            self.ents[6].config(text="选择文件")
    #单击事件
    def OnLeftClick(self,event):
        self.databaseIdentity=self.ents[0].get()  #得到数据库实例
        self.password=self.ents[1].get()          #得到sa密码
        #print("id:%s,pwd:%s"%(databaseIdentity,password))
        self.database=DataBase(server=self.databaseIdentity,password=self.password)
        #print(database.connectState)
        if(self.database.connectState==0):
            self.ents[5].config(state="disable")  #若错误则下拉列表不可用
            self.ents[8].config(state="disable")
            #self.Dialog()
            Dialog.Alert("数据实例或密码输入错误,请核对...")
        else:
            #保存数据库实例和密码
            self.ents[8].config(state="active")
            self.LoadLedger()
    #登录错误--调用模态窗口
    """def Dialog(self):
        win=Toplevel()
        Label(win,text="数据实例或密码输入错误,请核对....").pack()
        Button(win,text="确定",command=win.quit).pack()
        win.protocol("WM_DELETE_WINDOW",win.quit)

        win.focus_set()
        win.grab_set()
        win.mainloop()
        win.destroy()"""
    #登录成功--列表加载账套
    def  LoadLedger(self):
        self.database.CreateCursor()        #生成游标
        self.database.SelectTool(2)         #执行查询语句
        row=self.database.cursor.fetchone() #遍历数据
        rows=[]
        while row:
            rows.append(row[0])
            row=self.database.cursor.fetchone()
        self.ents[5]["value"]=rows
        self.ents[5].config(state="active")
        self.ents[5].bind("<<ComboboxSelected>>",self.SelectedValue) #为下拉列表绑定方法
    #下拉列表绑定方法
    def  SelectedValue(self,event):
        self.ledger= self.ents[5].get()     #保存账套
        print("选择的账套:%s"%(self.ledger))
    #设置主窗口位置
    def CenterMainCenter(self,width,height):
        screenWidth=self.root.winfo_screenwidth()
        screenHeight=self.root.winfo_screenheight()
        size=("%dx%d+%d+%d"%(width,height,(screenWidth-width)/2,(screenHeight-height)/2))
        self.root.geometry(size)
    def   __init__(self):
        self.fileTool=FileTool()
        #初始化前判断注册码是否有效 若无效则无界面  否则有界面
        state=self.fileTool.RegisterState()
        if(state==0):
            Dialog.Alert("注册码过期或无效,请重新注册.....")
            return
        self.root=Tk()
        self.root.title("Ghost WHS")
        fields=("数据库实例:","sa密码:","会计年度:","会计期间:","日期:")
        self.fields=fields
        self.root.maxsize(500,280)
        self.root.minsize(500,280)
if __name__=="__main__":
    login=Login()
    login.CenterMainCenter(500,280)
    login.MakeForm(login.root,login.fields)
    login.root.mainloop()

 

Register:

__author__ = 'i'
from Dialog import  *
from tkinter import  *
from FileTool import *
import  random
class    Register:
    #向邮箱发送电子邮件  内含 注册码
    def  SendRegister(self,event):
        #发送注册码之前首先判断密码是否正确
        pwd=self.ents[0].get()
        if(pwd !=self.password): #表示密码不正确
            Dialog.Alert("密码不正确,请从新输入....")
            return
        self.register=""
        for i  in range(1,9):
            self.register+=random.choice("qwedfrtgksloospgbc1236890462")  #随机产生9个随机数
        #self.WriteRegister(register)           #获取注册码之前得先写入注册码
        info={"0":self.register}
        state=self.fileTool.SendEmail(info)
        if(state==1):
            Dialog.Alert("发送注册码成功,请到邮箱接收.....")
        else:
            Dialog.Alert("发送注册码失败......")
    #向数据库写入注册码
    def  WriteRegister(self,register):
        user_register=self.ents[1].get()
        if(user_register!=self.register):
            Dialog.Alert("注册码错误,请核对后输入...")
            return
        state=self.fileTool.WriteRegister(register)
        if(state==1):
            Dialog.Alert("注册成功....")
        else:
            Dialog.Alert("注册失败....")
    #绑定事件--获取密码
    def  SendPassword(self,event):
        self.fileTool=FileTool() #点击发送密码时初始化文件对象
        str=""
        for i  in range(1,9):
            str+=random.choice("qwedfrtgksloospgbc1236890462")  #随机产生9个随机数
        info={"1":str}
        state=self.fileTool.SendEmail(info)
        if(state==1):
            Dialog.Alert("发送密码成功,请到邮箱接收.....")
            self.password=str
        else:
            Dialog.Alert("发送密码失败......")
    #创建窗体 root(Tk对象) fields([]) fields[0]=password fields[1]=register
    def MakeForm(self,root,fields):
        ents=[]
        row=Frame(root)
        label=Label(row,width=5,text=fields[0])
        ent=Entry(row,width=25,show='*') #密码框
        btn_getpwd=Button(row,text="获取密码",width=10)
        btn_getpwd.config(relief=SUNKEN)
        btn_getpwd.bind("<Button-1>",self.SendPassword)
        row.pack(side=TOP)
        label.pack(side=LEFT,padx=5)
        ent.pack(side=LEFT,padx=5)
        btn_getpwd.pack(side=LEFT,padx=5)
        ents.append(ent)

        row=Frame(root)
        label=Label(row,text=fields[1])
        ent=Entry(row,width=25) #注册码
        btn_Register=Button(row,text='获取注册码',width=10)
        btn_Register.config(relief=SUNKEN)
        btn_Register.bind('<Button-1>',self.SendRegister)
        row.pack(side=TOP,pady=5)
        label.pack(side=LEFT,padx=5)
        ent.pack(side=LEFT,padx=5)
        btn_Register.pack(side=LEFT,padx=5)
        ents.append(ent)

        row=Frame(root)
        btn_confirm=Button(text='注册',width=10)
        btn_confirm.config(relief=SUNKEN)
        btn_confirm.bind('<Button-1>',self.WriteRegister)
        btn_confirm.pack()
        row.pack()
        self.ents=ents
    #初始化加载窗体
    def __init__(self):
        self.root=Tk()
        self.root.title("注册码生成器")
        fields=["密码:","注册码:"]
        self.MakeForm(self.root,fields)
        #设置界面大小
        self.root.maxsize(350,140)
        self.root.minsize(350,140)
        self.CenterMainCenter(350,140)
        self.root.mainloop()
    #设置窗口位置
    def CenterMainCenter(self,width,height):
        screenWidth=self.root.winfo_screenwidth()
        screenHeight=self.root.winfo_screenheight()
        size=("%dx%d+%d+%d"%(width,height,(screenWidth-width)/2,(screenHeight-height)/2))
        self.root.geometry(size)
if __name__=="__main__":
    register=Register()

 

用pyinstaller打包 Register.py 和Login.py生成两个exe文件

 目录如下:

附加:使用说明:

 

 

 

 

 扩展:文件自动处理  服务器与客户端  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值