碰到一个客户 ,客户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文件
目录如下:
附加:使用说明:
扩展:文件自动处理 服务器与客户端