from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from fastapi import FastAPI, Request, UploadFile, Body from typing import Union # from icecream import install # import icecream # install() # from icecream import ic # ic.configureOutput(includeContext=True, ) import json from iteminventorydasa import QBStock import datetime from pyQBstockserverV1 import searchStockQB from qbgeneralsummaryreport import GeneralSummaryReportQuery as GSRQ import shutil from qbpurchaseorderquery import PurchaseOrderQuery import pdfexcel4DNwithxlrd from ItemInventoryQuery import ItemInventoryQuery from SO_to_Inv import readSO, CustomerQuery import os from QBClass.QBClasses import SalesOrderAdd, InventoryStockStatusByVendor, PriceLevelQuery, TransactionQuery from QBClass.QBClasses import CustomerQuery as CQ from QBClass.QBClasses import ItemInventoryQuery as IIQ from QBClass.QBClasses import GeneralSummaryReportQuery as GSRQuery import pprint # app = FastAPI() app = FastAPI(docs_url="/itemreceipt", redoc_url=None) templates = Jinja2Templates(directory="templates") @app.get('/', response_class=HTMLResponse) async def hello(request:Request, name:str=None): return templates.TemplateResponse("hello.html", {"request":request, "name":name}) # return "Hello Word" @app.get('/hello/{name}', response_class=HTMLResponse) async def hello(request:Request, name:str=None): return templates.TemplateResponse("hello.html", {"request":request, "name":name}) @app.get('/podistri/', response_class=HTMLResponse) async def hello(request:Request, item_name:str=None, cust_id:str=None, cust_name:str=None, start_date:str=None): print(request.query_params) q_dict = {'item_name':item_name, 'cust_id':cust_id, 'cust_name':cust_name, 'start_date':start_date} if not item_name: return templates.TemplateResponse("po_index.html", {"request":request, "name":item_name}) else: return templates.TemplateResponse("po_index.html", {"request":request, "name":item_name}) @app.get('/renew-iteminventory') async def renew_iteminventory(): filename = "ItemInventory\ItemInventory_FromQB.xlsx" item_inv = ItemInventoryQuery( IncludeRetElement=['FullName', 'DataExtRet'], MaxReturned=None) #MaxReturned=None means get ALL items QBXML = item_inv.create_QBXML() status, msg = item_inv.to_excel(filename) if status: return {'Info': f"Saved to {filename}.", 'Status':'DONE', 'msg':f"{msg}"} else: return {'Info': f"NOT Saved", 'Status':'ERROR', 'msg':msg} @app.get('/get-iteminventory-fullname') async def get_iteminventory_fullname(maxreturned:Union[int, None] = None): item_inv = ItemInventoryQuery( IncludeRetElement=['FullName','UnitOfMeasureSetRef'], MaxReturned=maxreturned) #MaxReturned=None means get ALL items # item_inv = ItemInventoryQuery( IncludeRetElement=['FullName',], MaxReturned=maxreturned) #MaxReturned=None means get ALL items QBXML = item_inv.create_QBXML() itu = item_inv.connect_to_quickbooks(item_inv.create_QBXML()) status, data = item_inv.to_json() if status: return data else: return {'Info': f"NOT Saved", 'Status':'ERROR', 'msg':data} @app.get('/get-iteminventory') # async def get_customer_fullname(MaxReturned:Union[int, None] = None, request:Request): async def get_iteminventory(request:Request): print(f'{request.query_params = }') params = await request.json() print(f'{params = }') # print(type(params), params) # params = request.query_params._dict print(type(params), f'{params = }') # iteminventory = CustomerQuery.CustomerQuery(**params) iteminventory = IIQ(**params, debug=False) # print(iteminventory.all()) # status, data = iteminventory.to_json() # print(f'{MaxReturned = }') # print(f'{request.query_params = }') if len(iteminventory.all())>0: return iteminventory.all() else: return {'Info': f"CANNOT Get", 'Status':'ERROR', 'msg':f'Cannot Get Customer with params: {params}'} @app.get('/get-customer-fullname') # async def get_customer_fullname(MaxReturned:Union[int, None] = None, request:Request): async def get_customer_fullname(request:Request): # print(f'{MaxReturned = }') print(f'{request = }') print(f'{request.query_params = }') MaxReturned = request.query_params.get('MaxReturned') # item_inv = CustomerQuery( IncludeRetElement=['FullName'], MaxReturned=maxreturned) #MaxReturned=None means get ALL items customer = CustomerQuery.CustomerQuery(MaxReturned=MaxReturned) # QBXML = customer.create_QBXML() itu = customer.create_customerquery_QBXML() # print(itu) status, data = customer.to_json() print(f'{MaxReturned = }') print(f'{request.query_params = }') if status: return data else: return {'Info': f"NOT Saved", 'Status':'ERROR', 'msg':data} @app.get('/get-customer') # async def get_customer_fullname(MaxReturned:Union[int, None] = None, request:Request): async def get_customer(request:Request): print(f'{request.query_params = }') params = await request.json() print(f'{params = }') # print(type(params), params) # params = request.query_params._dict print(type(params), f'{params = }') # customer = CustomerQuery.CustomerQuery(**params) customer = CQ(**params) # print(customer.all()) # status, data = customer.to_json() # print(f'{MaxReturned = }') # print(f'{request.query_params = }') if len(customer.all())>0: return customer.all() else: return {'Info': f"CANNOT Get", 'Status':'ERROR', 'msg':f'Cannot Get Customer with params: {params}'} @app.get('/get-pricelevel') async def get_pricelevel(name:Union[str, None] = None): print(f'{name = }') # item_inv = CustomerQuery( IncludeRetElement=['FullName'], MaxReturned=maxreturned) #MaxReturned=None means get ALL items pricelevel = PriceLevelQuery( NameFilter_MatchCriterion='Contains', NameFilter_Name=name, ) # print(pricelevel.all()) print(f'{len(pricelevel.all()) = }') # status, data = customer.to_json() if len(pricelevel.all())>0: return pricelevel.all()#len(pricelevel.all()) #pricelevel.all() else: return {'Info': f"CANNOT Get PriceLevel", 'Status':'ERROR', 'msg':f'Cannot get Pricelevel with {name}'} @app.get('/get-inventorystockstatusbyvendor') async def get_inventorystockstatusbyvendor(): items = InventoryStockStatusByVendor() if items: # data = json.dumps(items) return items else: return {'Info': f"CANNOT Get InventoryStockStatusByVendor TACO", 'Status':'ERROR', 'msg':items} @app.post("/upload-file/") async def create_upload_file(uploaded_file: UploadFile): base_file_location = f"DN_Excel_files" status = "ERROR" if uploaded_file.filename.endswith(".xls") and uploaded_file.filename.startswith("TCO-DN"): folder_yearmonth = uploaded_file.filename.split('-') if len(folder_yearmonth)>3: folder_yearmonth = folder_yearmonth[2].strip() folder_location = f"{base_file_location}/{folder_yearmonth}" file_location = f"{base_file_location}/{folder_yearmonth}/{uploaded_file.filename}" if not os.path.exists(folder_location): print('no folder exist. create one now') os.makedirs(folder_location) print(f'Main->{file_location}') else: status='Error Filename format' {"info": f"file '{uploaded_file.filename}' is not in the correct filename pattern. example:'TCO-DNxx-yymm-xxxxx.xls','TCO-DNKR-2308-08888.xls' please upload the correct file", "status": status} with open(file_location, "wb+") as file_object: shutil.copyfileobj(uploaded_file.file, file_object) status, retdict = pdfexcel4DNwithxlrd.read_DN_excel(file_location) if status == False: msg = f'Error. Cannot Find Item FullName: {retdict}' status = 'Error' return {"info": f"file '{uploaded_file.filename}' saved at '{file_location}'", "status": status, "msg": msg} ini=PurchaseOrderQuery(DN=retdict) bol_prepareItemReceiptOk, notinthelist = ini.prepareItemReceipt() print(f'create_upload_file->added DNQty:{ini.PurchaseOrderList}') ret = ini.create_itemreceiptadd_QBXML() # print(ret) if bol_prepareItemReceiptOk: ret = ini.connect_to_quickbooks(ret) # print(ret) status, status_msg = ini.status_ok(ret) # print(f"create_upload_file->replyfrom qbxml:{ret}") if status: print("OK", status_msg) status = "OK" else: print("ERROR", status_msg) print(f"ret:{ret}", type(ret)) status = "ERROR" msg = f"ERROR. replyfromqbxml:{ret}" msg = f"{status}. replyfrom qbxml:{ret}" else: print("create_upload_file->not all DN are added") # ic(notinthelist) # errmsg = ic(notinthelist) # errmsg = pprint.pprint(notinthelist) # errmsg = str(errmsg) # print(errmsg, type(errmsg)) errmsg = json.dumps(notinthelist, indent=2, sort_keys=True) errmsg = json.loads(errmsg) # print(errmsg, type(errmsg)) print(type(errmsg)) # msg = f"Error. not all DN are added. \n these items not added in the list :\n{notinthelist}" msg = f"Error. not all DN are added. \n these items not added in the list :\n{errmsg}" status = 'Error' msgdict={} msgdict["info"]=f'file {uploaded_file.filename} saved at {file_location}' msgdict["status"]=status msgdict["msg"]=errmsg print(msgdict, type(msg)) # jsonmsg = json.dumps(msgdict) # jsonmsg = json.loads(jsonmsg) return msgdict return [{"info": f"file '{uploaded_file.filename}' saved at '{file_location}'", "status": status, "msg": msg}] return {"info": f"file '{uploaded_file.filename}' is not Excel(.xls) file or Filename is not start with 'TCO-DN'. Please upload the correct file", "status": status} @app.post('/getopenso') async def getopenso(request: Request, CustomerName: str = Body(...)): print("getopenso") # CustomerName = await request.body() CustomerName = json.loads(CustomerName) print(f'CustomerName: {CustomerName}', type(CustomerName)) FullName = CustomerName['CustomerName'] print(FullName) ini=readSO.SalesOrderQuery(FullName= FullName, IncludeRetElement = ['TxnID', 'TimeCreated', 'TimeModified','TxnNumber', 'CustomerRef', 'TxnDate', 'RefNumber', 'IsManuallyClosed', 'IsFullyInvoiced','TotalAmount']) print("selesai salesorder") open_sales_orders = ini.get_open_so() print(f'return opensalesorder:{open_sales_orders}') return open_sales_orders @app.post('/getopensodetail') async def getopensodetail(request: Request, open_sales_orders = Body(...)): # open_sales_orders = await request.body() print(f'opensalesorders: {open_sales_orders}', type(open_sales_orders)) open_sales_orders=json.loads(open_sales_orders) open_sales_orders=open_sales_orders['solist'] print(f'openSOstr:{open_sales_orders}', type(open_sales_orders)) open_sales_orders=json.loads(open_sales_orders) print(f'openSOlist:{open_sales_orders}', type(open_sales_orders)) ini=readSO.SalesOrderQuery(FullName= 'abadi serpong', IncludeRetElement = ['TxnID', 'TimeCreated', 'TimeModified','TxnNumber', 'CustomerRef', 'TxnDate', 'RefNumber', 'IsManuallyClosed', 'IsFullyInvoiced','TotalAmount']) open_sales_orders_detail = ini.get_open_sales_order(open_sales_orders) open_sales_orders_detail = json.dumps(open_sales_orders_detail) print(f'opensalesordersdetail:{open_sales_orders_detail}', type (open_sales_orders_detail)) return open_sales_orders_detail @app.post('/get_stock') async def get_stock(request: Request): getstockdict = await request.body() print("") print(f'{datetime.datetime.now()} get_stock start -> {type(getstockdict)}, {getstockdict}') try: getstockdict = json.loads(getstockdict) except: print('error get_stock()') return {'message':'error getting stock'} print(f'get_stock -> {type(getstockdict)}, {getstockdict}') responseRt = searchStockQB(searchitems=getstockdict) print(f'{datetime.datetime.now()} get_stock finish -> {type(responseRt)}, {responseRt}') print("") return responseRt @app.post('/get-iteminventory_report') async def getiteminventory_report(request:Request): print('masuk getiteminventoryreport') params = await request.body() print('getiteminventoryrepot') try: params = json.loads(params) except: print('error get-iteminventory_report') return {'message':'error get-iteminventory_report'} # print(f'{request.query_params = }') # params = await request.json() print(f'{params = }') # print(type(params), params) # params = request.query_params._dict print(type(params), f'{params = }') # iteminventory = CustomerQuery.CustomerQuery(**params) iteminventory_report = GSRQuery(**params, debug=False) # print(iteminventory.all()) # status, data = iteminventory.to_json() # print(f'{MaxReturned = }') # print(f'{request.query_params = }') # print(iteminventory_report.filter('datarow').getItemInventory_Report()) ret = iteminventory_report.filter('DataRow').getItemInventory_Report() # print(f'{ret = } {type(ret) = } {len(ret) = }') if len(ret)>0: return ret else: return {'Info': f"CANNOT Get", 'Status':'ERROR', 'msg':f'Cannot Get /getiteminventory_report with params: {params}'} @app.post('/dasa2/get_generalsalesreport') async def get_generalsalesreport(request: Request): getdict = await request.body() print("") print(f'{datetime.datetime.now()} get_gsr start -> {type(getdict)}, {getdict}') try: getdict = json.loads(getdict) except: print('error get_gsr()') if not getdict: getdict = {'ReportDateMacro' : 'ThisYear'} else: return {'message':'error getting GeneralSalesReport'} print(f'get_gsr 1-> {type(getdict)}, {getdict}') ReportDateMacro = getdict['ReportDateMacro'] if 'ReportDateMacro' in getdict else None FromReportDate = getdict['FromReportDate'] if 'FromReportDate' in getdict else None ToReportDate = getdict['ToReportDate'] if 'ToReportDate' in getdict else None responseRt = GSRQ(GeneralSummaryReportType='SalesByCustomerSummary', ReportDateMacro=ReportDateMacro, FromReportDate=FromReportDate, ToReportDate=ToReportDate) # print(f'get_gsr 2-> {type(responseRt)}, {responseRt}') datas1=responseRt.get_datarow() print(f'get_gsr 3-> {type(datas1)}, {datas1}') print(f'{datetime.datetime.now()} get_gsr 4 finish -> {type(getdict)}, {getdict}') print("") return datas1[0], responseRt.get_total(), datas1[1] @app.post('/dasa2/salesorderadd') async def salesorderadd(request: Request): salesorderdict = await request.body() print("") try: salesorderdict = json.loads(salesorderdict) except: print('error salesorderadd()') return {'message':'error getting SalesOrder Data. it is not json'} print(f'{type(salesorderdict)}, {salesorderdict = }') so = SalesOrderAdd(**salesorderdict) print(f'{len(so.to_json()) = }') return so.all() @app.post('/dasa2/transactionquery') async def transactionquery(request: Request): transactiondict = await request.body() print("") try: transactiondict = json.loads(transactiondict) except: print('error TransactionQuery()') return {'message':'error getting TransactionQuery Data. it is not json'} print(f'{type(transactiondict)}, {transactiondict = }') print(f'{transactiondict = }') tq = TransactionQuery(**transactiondict) print(tq.all()) print(f'{len(tq.to_json()) = }') return tq.all() @app.post('/dasa2/rawxml') async def rawxml(request: Request): raw = await request.body() from sendItem import send_new_item rawstr = raw.decode(encoding="utf-8") # print(f'{raw = } {type(raw) = } {rawstr = } {type(rawstr) = }') # print(f'{send_new_item(rawstr) = }') result = send_new_item(rawstr) # print(result, type(result)) return {'result': result} # return {'msg':'ok'} # return "ok world" # # try: # # transactiondict = json.loads(transactiondict) # # except: # # print('error TransactionQuery()') # # return {'message':'error getting TransactionQuery Data. it is not json'} # print(f'{type(transactiondict)}, {transactiondict = }') # print(f'{transactiondict = }') # tq = TransactionQuery(**transactiondict) # print(tq.all()) # print(f'{len(tq.to_json()) = }') # return tq.all()