diff --git a/app.py b/app.py index 900d13f..53edae0 100644 --- a/app.py +++ b/app.py @@ -27,6 +27,18 @@ file_handler.setFormatter(logging.Formatter( "%(asctime)s - %(levelname)s - %(name)s - %(message)s" )) +import pyodbc + +def get_db_connection(): + return pyodbc.connect( + "DRIVER={ODBC Driver 18 for SQL Server};" + "SERVER=VPS88.DATACENTER.CSTI;" + "DATABASE=Faircot-Test;" + "UID=SINGA_META;" + "PWD=Start.123;" + "TrustServerCertificate=yes;" + ) + class AHKParser: lab = "AHK" @@ -484,48 +496,126 @@ predictor = ocr_predictor(pretrained=True) logger.info("Models loaded successfully.") -# ============================= -# 🧠 Smart OCR -# ============================= -# @app.post("/ocr") -# async def ocr(file: UploadFile): -# logger.info(f"Received OCR request: {file.filename}") -# try: -# file_data = await file.read() -# ext = file.filename.lower() +@app.post("/weight-report") +def create_weight_report(payload: dict = Body(...)): + logger.info("Create weight report called") -# # --------- PDF with native text --------- -# if ext.endswith(".pdf"): -# logger.info("PDF detected → Extracting native text first") -# reader = PdfReader(io.BytesIO(file_data)) -# direct_text = "".join( -# page.extract_text() or "" for page in reader.pages -# ) + # -------- Validation minimale -------- + required_fields = [ + "chunk_key", + "gross_weight", + "net_weight", + "tare_total", + "bags", + "surveyor_code", + "place_key", + "report_date" + ] -# if direct_text.strip(): -# logger.info("Native PDF text found → No OCR needed") -# return {"ocr_text": direct_text} + missing = [f for f in required_fields if f not in payload] + if missing: + raise HTTPException( + status_code=400, + detail=f"Missing fields: {', '.join(missing)}" + ) -# # -------- Fallback: scanned PDF OCR -------- -# logger.info("No native text → PDF treated as scanned → OCR") -# from pdf2image import convert_from_bytes -# images = convert_from_bytes(file_data) -# text = "" -# for i, img in enumerate(images): -# logger.info(f"OCR page {i+1}/{len(images)}") -# text += pytesseract.image_to_string(img) + "\n" + try: + chunk_key = int(payload["chunk_key"]) + gross_weight = float(payload["gross_weight"]) + net_weight = float(payload["net_weight"]) + tare_total = float(payload["tare_total"]) + bags = int(payload["bags"]) + surveyor_code = int(payload["surveyor_code"]) + place_key = int(payload["place_key"]) + report_date = int(payload["report_date"]) + except Exception as e: + raise HTTPException( + status_code=400, + detail=f"Invalid payload types: {e}" + ) -# return {"ocr_text": text} + try: + conn = get_db_connection() + cursor = conn.cursor() -# # --------- Image file OCR --------- -# logger.info("Image detected → Running OCR") -# img = Image.open(io.BytesIO(file_data)) -# text = pytesseract.image_to_string(img) -# return {"ocr_text": text} + cursor.execute(""" + EXEC dbo.sp_Singa_Automation_InsertWeightReport + @CHUNK_KEY = ?, + @BAGS_SOUND_AND_FULL = ?, + @BAGS_SOUND_AND_SLACK = 0, + @BAGS_DAMAGED_AND_FULL = 0, + @BAGS_DAMAGED_AND_SLACK = 0, + @BAGS_SHORT_LANDED = 0, + @GROSS_SOUND_AND_FULL = ?, + @GROSS_SOUND_AND_SLACK = 0, + @GROSS_DAMAGED_AND_FULL = 0, + @GROSS_DAMAGED_AND_SLACK = 0, + @GROSS_SAMPLES = 0, + @WEIGHING_DATE = ?, + @REPORT_DATE = ?, + @DATE_RECEIVED = ?, + @NET_WEIGHT = ?, + @TARE_TOTAL = ?, + @TARE_FOR_TEN_BAGS = 0, + @SURVEYOR_CODE = ?, + @PLACE_KEY = ?, + @SAMPLE_AFTER_WEIGHING = 'N', + @MODIFIED_BY = 'FAIRCOTBOT', + @MODIFY_DATE = ?, + @VERSION_NB = 1, + @FORWARDER_REF = 'API-TRYTON', + @INSURED_VALUE = '0', + @CREATED_BY = 1424, + @UPDATED_BY = 1424, + @BUY_INVOICE_AMOUNT = 0, + @BUY_CURR_KEY = 0, + @SEL_INVOICE_AMOUNT = 0, + @SEL_CURR_KEY = 0, + @CONSISTENCY = 'N', + @FINALIZED = 'N', + @MOISTURE_VALUE = NULL, + @REPORT_TYPE = 0, + @WET_WEIGHT = NULL, + @WSMD_LOCATION = 0 + """, + chunk_key, + bags, + gross_weight, + report_date, + report_date, + report_date, + net_weight, + tare_total, + surveyor_code, + place_key, + report_date + ) + + # 🟢 On récupère le SELECT final de la SP + row = cursor.fetchone() + conn.commit() + + if not row: + raise HTTPException( + status_code=500, + detail="Stored procedure returned no data" + ) + + return { + "success": True, + "weight_report_key": row.WEIGHT_REPORT_KEY + } + + except Exception as e: + logger.exception("Weight report creation failed") + raise HTTPException(status_code=500, detail=str(e)) + + finally: + try: + conn.close() + except: + pass -# except Exception as e: -# logger.error(f"OCR failed: {e}", exc_info=True) -# raise HTTPException(status_code=500, detail=str(e)) @app.post("/ocr") async def ocr(file: UploadFile): """ @@ -849,7 +939,6 @@ def call_extractor(text: str, lab: str = "AHK"): return response.json() - @app.post("/parse") async def parse_endpoint(text: str = Body(..., embed=True)): lab = parse_report(text)