|
|
|
|
@@ -9,7 +9,7 @@ import app.core.config as config
|
|
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from app.db.session import SessionLocal
|
|
|
|
|
from app.db.crud import get_flows_by_app,get_activedomain
|
|
|
|
|
from app.db.crud import get_flows_by_app,get_activedomain,get_kintoneformat
|
|
|
|
|
from app.core.auth import get_current_active_user,get_current_user
|
|
|
|
|
from app.core.apiexception import APIException
|
|
|
|
|
|
|
|
|
|
@@ -23,28 +23,132 @@ def getkintoneenv(user = Depends(get_current_user)):
|
|
|
|
|
return kintoneevn
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getfieldsfromexcel(df):
|
|
|
|
|
def getkintoneformat():
|
|
|
|
|
db = SessionLocal()
|
|
|
|
|
formats = get_kintoneformat(db)
|
|
|
|
|
db.close()
|
|
|
|
|
return formats
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def createkintonefields(property,value,trueformat):
|
|
|
|
|
p = []
|
|
|
|
|
if(property=="options"):
|
|
|
|
|
o=[]
|
|
|
|
|
for v in value.split(','):
|
|
|
|
|
o.append(f"\"{v.split('|')[0]}\":{{\"label\":\"{v.split('|')[0]}\",\"index\":\"{v.split('|')[1]}\"}}")
|
|
|
|
|
p.append(f"\"options\":{{{','.join(o)}}}")
|
|
|
|
|
elif(property =="expression"):
|
|
|
|
|
p.append(f"\"hideExpression\":true")
|
|
|
|
|
p.append(f"\"expression\":\"{value.split(':')[1]}\"")
|
|
|
|
|
elif(property =="required" or property =="unique" or property =="defaultNowValue" or property =="hideExpression" or property =="digit"):
|
|
|
|
|
if str(value) == trueformat:
|
|
|
|
|
p.append(f"\"{property}\":true")
|
|
|
|
|
else:
|
|
|
|
|
p.append(f"\"{property}\":false")
|
|
|
|
|
elif(property =="protocol"):
|
|
|
|
|
if(value == "メールアドレス"):
|
|
|
|
|
p.append("\"protocol\":\"MAIL\"")
|
|
|
|
|
elif(value == "Webサイト"):
|
|
|
|
|
p.append("\"protocol\":\"WEB\"")
|
|
|
|
|
elif(value == "電話番号"):
|
|
|
|
|
p.append("\"protocol\":\"CALL\"")
|
|
|
|
|
else:
|
|
|
|
|
p.append(f"\"{property}\":\"{value}\"")
|
|
|
|
|
return p
|
|
|
|
|
|
|
|
|
|
def getfieldsfromexcel(df,mapping):
|
|
|
|
|
startrow = mapping.startrow
|
|
|
|
|
startcolumn = mapping.startcolumn
|
|
|
|
|
typecolumn = mapping.typecolumn
|
|
|
|
|
codecolumn = mapping.codecolumn
|
|
|
|
|
property = mapping.field.split(",")
|
|
|
|
|
trueformat = mapping.trueformat
|
|
|
|
|
appname = df.iloc[0,2]
|
|
|
|
|
col=[]
|
|
|
|
|
for row in range(5,len(df)):
|
|
|
|
|
if pd.isna(df.iloc[row,1]):
|
|
|
|
|
for row in range(startrow,len(df)):
|
|
|
|
|
if pd.isna(df.iloc[row,startcolumn]):
|
|
|
|
|
break
|
|
|
|
|
if not df.iloc[row,3] in config.KINTONE_FIELD_TYPE:
|
|
|
|
|
if not df.iloc[row,typecolumn] in config.KINTONE_FIELD_TYPE:
|
|
|
|
|
continue
|
|
|
|
|
p=[]
|
|
|
|
|
for column in range(1,7):
|
|
|
|
|
for column in range(startcolumn,startcolumn + len(property)):
|
|
|
|
|
if(not pd.isna(df.iloc[row,column])):
|
|
|
|
|
if(property[column-1]=="options"):
|
|
|
|
|
o=[]
|
|
|
|
|
for v in df.iloc[row,column].split(','):
|
|
|
|
|
o.append(f"\"{v.split('|')[0]}\":{{\"label\":\"{v.split('|')[0]}\",\"index\":\"{v.split('|')[1]}\"}}")
|
|
|
|
|
p.append(f"\"{property[column-1]}\":{{{','.join(o)}}}")
|
|
|
|
|
elif(property[column-1]=="required"):
|
|
|
|
|
p.append(f"\"{property[column-1]}\":{df.iloc[row,column]}")
|
|
|
|
|
propertyname =property[column-1]
|
|
|
|
|
if(propertyname.find("[") == 0):
|
|
|
|
|
continue
|
|
|
|
|
elif (propertyname =="remark"):
|
|
|
|
|
if (df.iloc[row,column].find("|") !=-1):
|
|
|
|
|
propertyname = "options"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
if (df.iloc[row,column] == "メールアドレス" or df.iloc[row,column] == "Webサイト" or df.iloc[row,column] == "電話番号"):
|
|
|
|
|
propertyname = "protocol"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
if (df.iloc[row,column].find("桁区切り") !=-1):
|
|
|
|
|
propertyname = "digit"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
if (df.iloc[row,column].find("前単位") !=-1):
|
|
|
|
|
propertyname = "unitPosition"
|
|
|
|
|
p = p + createkintonefields(propertyname, "BEFORE",trueformat)
|
|
|
|
|
if (df.iloc[row,column].find("後単位") !=-1):
|
|
|
|
|
propertyname = "unitPosition"
|
|
|
|
|
p = p + createkintonefields(propertyname, "AFTER",trueformat)
|
|
|
|
|
if (df.iloc[row,column].find("単位「") !=-1):
|
|
|
|
|
propertyname = "unit"
|
|
|
|
|
ids = df.iloc[row,column].index("単位「")
|
|
|
|
|
ide = df.iloc[row,column].index("」")
|
|
|
|
|
unit = df.iloc[row,column][ids+3:ide]
|
|
|
|
|
p = p + createkintonefields(propertyname, unit,trueformat)
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
elif(propertyname =="mixValue"):
|
|
|
|
|
if(df.iloc[row,column].find("レコード登録時の日") != -1):
|
|
|
|
|
propertyname = "defaultNowValue"
|
|
|
|
|
df.iloc[row,column] = trueformat
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
elif(df.iloc[row,column].find("計:") != -1):
|
|
|
|
|
propertyname = "expression"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
elif(df.iloc[row,column] !=""):
|
|
|
|
|
propertyname = "defaultValue"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
elif(propertyname=="max" or propertyname == "min"):
|
|
|
|
|
if(df.iloc[row,typecolumn] == "NUMBER"):
|
|
|
|
|
propertyname = property[column-1] + "Value"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
else:
|
|
|
|
|
propertyname = property[column-1] + "Length"
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
else:
|
|
|
|
|
p.append(f"\"{property[column-1]}\":\"{df.iloc[row,column]}\"")
|
|
|
|
|
col.append(f"\"{df.iloc[row,2]}\":{{{','.join(p)}}}")
|
|
|
|
|
fields = ",".join(col).replace("False","false").replace("True","true")
|
|
|
|
|
p = p + createkintonefields(propertyname, df.iloc[row,column],trueformat)
|
|
|
|
|
|
|
|
|
|
# if(propertyname=="options"):
|
|
|
|
|
# o=[]
|
|
|
|
|
# for v in df.iloc[row,column].split(','):
|
|
|
|
|
# o.append(f"\"{v.split('|')[0]}\":{{\"label\":\"{v.split('|')[0]}\",\"index\":\"{v.split('|')[1]}\"}}")
|
|
|
|
|
# p.append(f"\"options\":{{{','.join(o)}}}")
|
|
|
|
|
# elif(propertyname=="expression"):
|
|
|
|
|
# p.append(f"\"hideExpression\":true")
|
|
|
|
|
# p.append(f"\"expression\":{df.iloc[row,column].split(':')[1]}")
|
|
|
|
|
# elif(propertyname=="required" or propertyname =="unique" or propertyname=="defaultNowValue" or propertyname=="hideExpression" or propertyname=="digit"):
|
|
|
|
|
# if (df.iloc[row,column] == trueformat):
|
|
|
|
|
# p.append(f"\"{propertyname}\":true")
|
|
|
|
|
# else:
|
|
|
|
|
# p.append(f"\"{propertyname}\":false")
|
|
|
|
|
# elif(propertyname =="protocol"):
|
|
|
|
|
# if(df.iloc[row,column] == "メールアドレス"):
|
|
|
|
|
# p.append("\"protocol\":\"MAIL\"")
|
|
|
|
|
# elif(df.iloc[row,column] == "Webサイト"):
|
|
|
|
|
# p.append("\"protocol\":\"WEB\"")
|
|
|
|
|
# elif(df.iloc[row,column] == "電話番号"):
|
|
|
|
|
# p.append("\"protocol\":\"CALL\"")
|
|
|
|
|
# else:
|
|
|
|
|
# p.append(f"\"{propertyname}\":\"{df.iloc[row,column]}\"")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
col.append(f"\"{df.iloc[row,codecolumn]}\":{{{','.join(p)}}}")
|
|
|
|
|
fields = ",".join(col).replace("\\", "\\\\")
|
|
|
|
|
return json.loads(f"{{{fields}}}")
|
|
|
|
|
|
|
|
|
|
def getsettingfromexcel(df):
|
|
|
|
|
@@ -129,8 +233,8 @@ def analysefields(excel,kintone):
|
|
|
|
|
adds = excel.keys() - kintone.keys()
|
|
|
|
|
dels = kintone.keys() - excel.keys()
|
|
|
|
|
for key in updates:
|
|
|
|
|
for p in property:
|
|
|
|
|
if excel[key].get(p) != None and kintone[key][p] != excel[key][p]:
|
|
|
|
|
for p in config.KINTONE_FIELD_PROPERTY:
|
|
|
|
|
if excel[key].get(p) != None and kintone[key].get(p) != None and kintone[key][p] != excel[key][p]:
|
|
|
|
|
updatefields[key] = excel[key]
|
|
|
|
|
break
|
|
|
|
|
for key in adds:
|
|
|
|
|
@@ -412,10 +516,14 @@ async def createapp(request:Request,name:str,c:config.KINTONE_ENV=Depends(getkin
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise APIException('kintone:createapp',request.url._url, f"Error occurred while create app({c.DOMAIN_NAM}->{name}):",e)
|
|
|
|
|
|
|
|
|
|
property=["label","code","type","required","defaultValue","options"]
|
|
|
|
|
|
|
|
|
|
@r.post("/createappfromexcel",)
|
|
|
|
|
async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...),env = Depends(getkintoneenv)):
|
|
|
|
|
async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...),format:int = 0,env = Depends(getkintoneenv)):
|
|
|
|
|
try:
|
|
|
|
|
mapping = getkintoneformat()[format]
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise APIException('kintone:createappfromexcel',request.url._url, f"Error occurred while get kintone format:",e)
|
|
|
|
|
|
|
|
|
|
for file in files:
|
|
|
|
|
if file.filename.endswith('.xlsx'):
|
|
|
|
|
try:
|
|
|
|
|
@@ -425,7 +533,7 @@ async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...
|
|
|
|
|
appname = df.iloc[0,2]
|
|
|
|
|
desc = df.iloc[2,2]
|
|
|
|
|
result = {"app":0,"revision":0,"msg":""}
|
|
|
|
|
fields = getfieldsfromexcel(df)
|
|
|
|
|
fields = getfieldsfromexcel(df,mapping)
|
|
|
|
|
users = getkintoneusers(env)
|
|
|
|
|
orgs = getkintoneorgs(env)
|
|
|
|
|
processes = getprocessfromexcel(df,users["users"], orgs["organizationTitles"])
|
|
|
|
|
@@ -442,14 +550,19 @@ async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...
|
|
|
|
|
result["revision"] = app["revision"]
|
|
|
|
|
deoployappfromkintone(result["app"],result["revision"],env)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise APIException('kintone:createappfromexcel',request.url._url, f"Error occurred while parsing file ({env.DOMAIN_NAM}->{file.filename}):",e)
|
|
|
|
|
raise APIException('kintone:createappfromexcel',request.url._url, f"Error occurred while parsing file ({env.DOMAIN_NAME}->{file.filename}):",e)
|
|
|
|
|
else:
|
|
|
|
|
raise APIException('kintone:createappfromexcel',request.url._url, f"File {file.filename} is not an Excel file",e)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@r.post("/updateappfromexcel")
|
|
|
|
|
async def updateappfromexcel(request:Request,app:str,files:t.List[UploadFile] = File(...),env = Depends(getkintoneenv)):
|
|
|
|
|
async def updateappfromexcel(request:Request,app:str,files:t.List[UploadFile] = File(...),format:int = 0,env = Depends(getkintoneenv)):
|
|
|
|
|
try:
|
|
|
|
|
mapping = getkintoneformat()[format]
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise APIException('kintone:updateappfromexcel',request.url._url, f"Error occurred while get kintone format:",e)
|
|
|
|
|
|
|
|
|
|
for file in files:
|
|
|
|
|
if file.filename.endswith('.xlsx'):
|
|
|
|
|
try:
|
|
|
|
|
@@ -458,7 +571,7 @@ async def updateappfromexcel(request:Request,app:str,files:t.List[UploadFile] =
|
|
|
|
|
excel = getsettingfromexcel(df)
|
|
|
|
|
kintone= getsettingfromkintone(app,env)
|
|
|
|
|
settings = analysesettings(excel,kintone)
|
|
|
|
|
excel = getfieldsfromexcel(df)
|
|
|
|
|
excel = getfieldsfromexcel(df,mapping)
|
|
|
|
|
kintone = getfieldsfromkintone(app,env)
|
|
|
|
|
users = getkintoneusers(env)
|
|
|
|
|
orgs = getkintoneorgs(env)
|
|
|
|
|
@@ -493,7 +606,7 @@ async def updateappfromexcel(request:Request,app:str,files:t.List[UploadFile] =
|
|
|
|
|
if deploy:
|
|
|
|
|
result = deoployappfromkintone(app,revision,env)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise APIException('kintone:updateappfromexcel',request.url._url, f"Error occurred while parsing file ({env.DOMAIN_NAM}->{file.filename}):",e)
|
|
|
|
|
raise APIException('kintone:updateappfromexcel',request.url._url, f"Error occurred while parsing file ({env.DOMAIN_NAME}->{file.filename}):",e)
|
|
|
|
|
else:
|
|
|
|
|
raise APIException('kintone:updateappfromexcel',request.url._url, f"File {file.filename} is not an Excel file",e)
|
|
|
|
|
return result
|
|
|
|
|
|