Merge branch 'mvp_step2_back' into mvp_step2_dev

This commit is contained in:
2024-02-13 14:25:49 +09:00
5 changed files with 159 additions and 29 deletions

View File

@@ -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

View File

@@ -16,6 +16,8 @@ DEPLOY_JS_URL = "https://ka-addin.azurewebsites.net/alc_runtime.js"
KINTONE_FIELD_TYPE=["GROUP","GROUP_SELECT","CHECK_BOX","SUBTABLE","DROP_DOWN","USER_SELECT","RADIO_BUTTON","RICH_TEXT","LINK","REFERENCE_TABLE","CALC","TIME","NUMBER","ORGANIZATION_SELECT","FILE","DATETIME","DATE","MULTI_SELECT","SINGLE_LINE_TEXT","MULTI_LINE_TEXT"]
KINTONE_FIELD_PROPERTY=['label','code','type','required','unique','maxValue','minValue','maxLength','minLength','defaultValue','defaultNowValue','options','expression','hideExpression','digit','protocol','displayScale','unit','unitPosition']
class KINTONE_ENV:
BASE_URL = ""

View File

@@ -291,3 +291,7 @@ def create_log(db: Session, error:schemas.ErrorCreate):
db.commit()
db.refresh(db_log)
return db_log
def get_kintoneformat(db: Session):
formats = db.query(models.KintoneFormat).order_by(models.KintoneFormat.id).all()
return formats

View File

@@ -95,7 +95,18 @@ class EventAction(Base):
class ErrorLog(Base):
__tablename__ = "errorlog"
id = Column(Integer, primary_key=True, index=True)
title = Column(String(50))
location = Column(String(500))
content = Column(String(5000))
class KintoneFormat(Base):
__tablename__ = "kintoneformat"
name = Column(String(50))
startrow =Column(Integer)
startcolumn =Column(Integer)
typecolumn =Column(Integer)
codecolumn =Column(Integer)
field = Column(String(5000))
trueformat = Column(String(10))

View File

@@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "tsc && vite",
"build": "tsc && vite build && xcopy dist\\*.js ..\\..\\backend\\Temp\\ /E /I /Y",
"build:dev":"tsc && set \"SOURCE_MAP=true\" && vite build && xcopy dist\\*.js ..\\..\\backend\\Temp\\ /E /I /Y",
"preview": "vite preview"