diff --git a/apps/Backend/src/routes/claims.ts b/apps/Backend/src/routes/claims.ts index 64f8144..345105b 100644 --- a/apps/Backend/src/routes/claims.ts +++ b/apps/Backend/src/routes/claims.ts @@ -4,7 +4,10 @@ import { storage } from "../storage"; import { z } from "zod"; import { ClaimUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas"; import multer from "multer"; -import { forwardToSeleniumAgent, forwardToSeleniumAgent2 } from "../services/seleniumClient"; +import { + forwardToSeleniumAgent, + forwardToSeleniumAgent2, +} from "../services/seleniumClient"; import path from "path"; import axios from "axios"; import fs from "fs"; @@ -43,11 +46,30 @@ const ExtendedClaimSchema = ( // Routes const multerStorage = multer.memoryStorage(); // NO DISK -const upload = multer({ storage: multerStorage }); +const upload = multer({ + storage: multerStorage, + limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit per file + fileFilter: (req, file, cb) => { + const allowed = [ + "application/pdf", + "image/jpeg", + "image/png", + "image/webp", + ]; + if (allowed.includes(file.mimetype)) { + cb(null, true); + } else { + cb(new Error("Unsupported file type")); + } + }, +}); router.post( "/selenium", - upload.array("pdfs"), + upload.fields([ + { name: "pdfs", maxCount: 10 }, + { name: "images", maxCount: 10 }, + ]), async (req: Request, res: Response): Promise => { if (!req.files || !req.body.data) { return res @@ -61,7 +83,10 @@ router.post( try { const claimData = JSON.parse(req.body.data); - const files = req.files as Express.Multer.File[]; + const pdfs = + (req.files as Record).pdfs ?? []; + const images = + (req.files as Record).images ?? []; const credentials = await storage.getInsuranceCredentialByUserAndSiteKey( req.user.id, @@ -78,7 +103,11 @@ router.post( massdhpUsername: credentials.username, massdhpPassword: credentials.password, }; - const result = await forwardToSeleniumAgent(enrichedData, files); + + const result = await forwardToSeleniumAgent(enrichedData, [ + ...pdfs, + ...images, + ]); res.json({ success: true, data: result }); } catch (err) { @@ -95,10 +124,10 @@ router.post( return res.status(401).json({ error: "Unauthorized: user info missing" }); } - try{ - const { patientId, claimId } = req.body; + try { + const { patientId, claimId } = req.body; - if (!patientId || !claimId) { + if (!patientId || !claimId) { return res.status(400).json({ error: "Missing patientId or claimId" }); } const parsedPatientId = parseInt(patientId); @@ -107,14 +136,18 @@ router.post( const result = await forwardToSeleniumAgent2(); if (result.status !== "success") { - return res.status(400).json({ error: result.message || "Failed to fetch PDF" }); + return res + .status(400) + .json({ error: result.message || "Failed to fetch PDF" }); } const pdfUrl = result.pdf_url; const filename = path.basename(new URL(pdfUrl).pathname); - const pdfResponse = await axios.get(pdfUrl, { responseType: "arraybuffer" }); + const pdfResponse = await axios.get(pdfUrl, { + responseType: "arraybuffer", + }); - // Temp savving the pdf incase, creatClaimPdf failed: + // Temp savving the pdf incase, creatClaimPdf failed: const tempDir = path.join(__dirname, "..", "..", "temp"); if (!fs.existsSync(tempDir)) { fs.mkdirSync(tempDir, { recursive: true }); @@ -127,7 +160,7 @@ router.post( parsedPatientId, parsedClaimId, filename, - pdfResponse.data + pdfResponse.data ); return res.json({ @@ -138,9 +171,11 @@ router.post( }); } catch (err) { console.error("Error in /selenium/fetchpdf:", err); - return res.status(500).json({ error: "Failed to forward to selenium agent 2" }); + return res + .status(500) + .json({ error: "Failed to forward to selenium agent 2" }); + } } -} ); // GET /api/claims?page=1&limit=5 diff --git a/apps/Backend/src/services/seleniumClient.ts b/apps/Backend/src/services/seleniumClient.ts index 4c6ad0c..9472eaf 100644 --- a/apps/Backend/src/services/seleniumClient.ts +++ b/apps/Backend/src/services/seleniumClient.ts @@ -6,27 +6,44 @@ export interface SeleniumPayload { originalname: string; bufferBase64: string; }[]; + images: { + originalname: string; + bufferBase64: string; + }[]; } export async function forwardToSeleniumAgent( claimData: any, files: Express.Multer.File[] ): Promise { - const payload: SeleniumPayload = { - claim: claimData, - pdfs: files.map(file => ({ + const pdfs = files + .filter((file) => file.mimetype === "application/pdf") + .map((file) => ({ originalname: file.originalname, bufferBase64: file.buffer.toString("base64"), - })), + })); + + const images = files + .filter((file) => file.mimetype.startsWith("image/")) + .map((file) => ({ + originalname: file.originalname, + bufferBase64: file.buffer.toString("base64"), + })); + + const payload: SeleniumPayload = { + claim: claimData, + pdfs, + images, }; - const response = await axios.post("http://localhost:5002/start-workflow", payload); + const response = await axios.post( + "http://localhost:5002/start-workflow", + payload + ); return response.data; } -export async function forwardToSeleniumAgent2( -): Promise { - +export async function forwardToSeleniumAgent2(): Promise { const response = await axios.post("http://localhost:5002/fetch-pdf"); return response.data; } diff --git a/apps/Frontend/src/components/claims/claim-form.tsx b/apps/Frontend/src/components/claims/claim-form.tsx index 605ab66..6f672ea 100644 --- a/apps/Frontend/src/components/claims/claim-form.tsx +++ b/apps/Frontend/src/components/claims/claim-form.tsx @@ -172,12 +172,14 @@ export function ClaimForm({ }, }); useEffect(() => { - if (staffMembersRaw.length > 0 && !staff) { - const kaiGao = staffMembersRaw.find((member) => member.name === "Kai Gao"); - const defaultStaff = kaiGao || staffMembersRaw[0]; - if (defaultStaff) setStaff(defaultStaff); - } -}, [staffMembersRaw, staff]); + if (staffMembersRaw.length > 0 && !staff) { + const kaiGao = staffMembersRaw.find( + (member) => member.name === "Kai Gao" + ); + const defaultStaff = kaiGao || staffMembersRaw[0]; + if (defaultStaff) setStaff(defaultStaff); + } + }, [staffMembersRaw, staff]); // Service date state function parseLocalDate(dateInput: Date | string): Date { @@ -333,11 +335,30 @@ export function ClaimForm({ const handleFileUpload = (files: File[]) => { setIsUploading(true); - const validFiles = files.filter((file) => file.type === "application/pdf"); - if (validFiles.length > 5) { + const allowedTypes = [ + "application/pdf", + "image/jpeg", + "image/jpg", + "image/png", + "image/webp", + ]; + + const validFiles = files.filter((file) => allowedTypes.includes(file.type)); + + if (validFiles.length > 10) { toast({ title: "Too Many Files", - description: "You can only upload up to 5 PDFs.", + description: "You can only upload up to 10 files (PDFs or images).", + variant: "destructive", + }); + setIsUploading(false); + return; + } + + if (validFiles.length === 0) { + toast({ + title: "Invalid File Type", + description: "Only PDF and image files are allowed.", variant: "destructive", }); setIsUploading(false); @@ -351,7 +372,7 @@ export function ClaimForm({ toast({ title: "Files Selected", - description: `${validFiles.length} PDF file(s) ready for processing.`, + description: `${validFiles.length} file(s) ready for processing.`, }); setIsUploading(false); @@ -711,34 +732,15 @@ export function ClaimForm({ {/* File Upload Section */}

- Only PDF files allowed. You can upload up to 5 files. File types - with 4+ character extensions like .DOCX, .PPTX, or .XLSX are not - allowed. + You can upload up to 10 files. Allowed types: PDF, JPG, PNG, + WEBP.

-
-
- - -
-
- {form.uploadedFiles.length > 0 && ( diff --git a/apps/Frontend/src/components/file-upload/multiple-file-upload-zone.tsx b/apps/Frontend/src/components/file-upload/multiple-file-upload-zone.tsx index ff5d048..6551437 100644 --- a/apps/Frontend/src/components/file-upload/multiple-file-upload-zone.tsx +++ b/apps/Frontend/src/components/file-upload/multiple-file-upload-zone.tsx @@ -1,8 +1,8 @@ -import React, { useState, useRef, useCallback } from 'react'; -import { Upload, File, X, FilePlus } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { useToast } from '@/hooks/use-toast'; -import { cn } from '@/lib/utils'; +import React, { useState, useRef, useCallback } from "react"; +import { Upload, File, X, FilePlus } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { useToast } from "@/hooks/use-toast"; +import { cn } from "@/lib/utils"; interface FileUploadZoneProps { onFileUpload: (files: File[]) => void; @@ -11,43 +11,25 @@ interface FileUploadZoneProps { maxFiles?: number; } -export function MultipleFileUploadZone({ - onFileUpload, - isUploading, - acceptedFileTypes = "application/pdf", - maxFiles = 5, +export function MultipleFileUploadZone({ + onFileUpload, + isUploading, + acceptedFileTypes = "application/pdf,image/jpeg,image/jpg,image/png,image/webp", + maxFiles = 10, }: FileUploadZoneProps) { const { toast } = useToast(); const [isDragging, setIsDragging] = useState(false); const [uploadedFiles, setUploadedFiles] = useState([]); const fileInputRef = useRef(null); - const handleDragEnter = useCallback((e: React.DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - setIsDragging(true); - }, []); - - const handleDragLeave = useCallback((e: React.DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - setIsDragging(false); - }, []); - - const handleDragOver = useCallback((e: React.DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - if (!isDragging) { - setIsDragging(true); - } - }, [isDragging]); + const allowedTypes = acceptedFileTypes.split(",").map((type) => type.trim()); const validateFile = (file: File) => { - if (!file.type.match(acceptedFileTypes)) { + if (!allowedTypes.includes(file.type)) { toast({ title: "Invalid file type", - description: "Please upload a PDF file.", - variant: "destructive" + description: "Only PDF and image files are allowed.", + variant: "destructive", }); return false; } @@ -55,8 +37,8 @@ export function MultipleFileUploadZone({ if (file.size > 5 * 1024 * 1024) { toast({ title: "File too large", - description: "File size should be less than 5MB.", - variant: "destructive" + description: "File size must be less than 5MB.", + variant: "destructive", }); return false; } @@ -84,16 +66,45 @@ export function MultipleFileUploadZone({ onFileUpload(updatedFiles); }; - const handleDrop = useCallback((e: React.DragEvent) => { + const handleDragEnter = useCallback((e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(true); + }, []); + + const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragging(false); - handleFiles(e.dataTransfer.files); - }, [uploadedFiles]); + }, []); - const handleFileSelect = useCallback((e: React.ChangeEvent) => { - handleFiles(e.target.files); - }, [uploadedFiles]); + const handleDragOver = useCallback( + (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + if (!isDragging) { + setIsDragging(true); + } + }, + [isDragging] + ); + + const handleDrop = useCallback( + (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(false); + handleFiles(e.dataTransfer.files); + }, + [uploadedFiles] + ); + + const handleFileSelect = useCallback( + (e: React.ChangeEvent) => { + handleFiles(e.target.files); + }, + [uploadedFiles] + ); const handleBrowseClick = () => { if (fileInputRef.current) { @@ -118,11 +129,13 @@ export function MultipleFileUploadZone({ accept={acceptedFileTypes} multiple /> - +
) : uploadedFiles.length > 0 ? (
-

{uploadedFiles.length} file(s) uploaded

+

+ {uploadedFiles.length} file(s) uploaded +

    {uploadedFiles.map((file, index) => ( -
  • +
  • {file.name} - -

    Up to {maxFiles} PDF files, 5MB each

    +

    + Allowed types: PDF, JPG, PNG — Max {maxFiles} files, 5MB each +

)}
diff --git a/apps/Frontend/src/pages/claims-page.tsx b/apps/Frontend/src/pages/claims-page.tsx index bb3c99d..3487b92 100644 --- a/apps/Frontend/src/pages/claims-page.tsx +++ b/apps/Frontend/src/pages/claims-page.tsx @@ -219,7 +219,7 @@ export default function ClaimsPage() { const handleSeleniumPopup = async (actionType: string) => { try { if (!claimRes?.id) { - throw new Error("Missing claimId"); + throw new Error("Missing claimId"); } if (!selectedPatient) { throw new Error("Missing patientId"); @@ -518,13 +518,16 @@ export default function ClaimsPage() { // handle selenium const handleSelenium = async (data: any) => { const formData = new FormData(); - formData.append("data", JSON.stringify(data)); const uploadedFiles: File[] = data.uploadedFiles ?? []; uploadedFiles.forEach((file: File) => { - formData.append("pdfs", file); + if (file.type === "application/pdf") { + formData.append("pdfs", file); + } else if (file.type.startsWith("image/")) { + formData.append("images", file); + } }); try { @@ -537,7 +540,8 @@ export default function ClaimsPage() { toast({ title: "Selenium service notified", - description: "Your claim data was successfully sent to Selenium.", + description: + "Your claim data was successfully sent to Selenium, Wait for its response.", variant: "default", }); setIsMhPopupOpen(true); diff --git a/apps/SeleniumService/selenium_raw.py b/apps/SeleniumService/selenium_raw.py deleted file mode 100644 index 1a2b496..0000000 --- a/apps/SeleniumService/selenium_raw.py +++ /dev/null @@ -1,327 +0,0 @@ -from selenium import webdriver -from selenium.common import TimeoutException -from selenium.webdriver.chrome.service import Service -from selenium.webdriver.common.by import By -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from webdriver_manager.chrome import ChromeDriverManager -from selenium.webdriver.support.ui import Select -import time -from datetime import datetime -from dotenv import load_dotenv -import os -load_dotenv() - -# this file is just for testing selenium solely. -procedure_codes = [ - { - "procedure_code": "D0210", - "procedure_date": "06/30/2025", - "oralCavityArea": "", - "toothNumber": "", - "toothSurface": "", - "fees":"19" - }, - { - "procedure_code": "D0250", - "procedure_date": "06/30/2025", - "oralCavityArea": "here", - "toothNumber": "15", - "toothSurface": "B", - "fees":"190" - } -] - -pdfs = ["PDF_To_Test/sample1.pdf", "PDF_To_Test/sample2.pdf"] - -data = { - "massdhp_username": os.getenv("MASSDHP_USERNAME"), - "massdhp_password": os.getenv("MASSDHP_PASSWORD"), - "memberId": os.getenv("memberId"), - "dateOfBirth":os.getenv("dob"), - "procedure_codes": procedure_codes, - "pdfs" : pdfs, - "missingTeethStatus": "Yes_missing", # can be Yes_missing , No_missing, or endentulous - "missingTeeth": { - # Tooth name: selection ("X" for missing, "O" for "To be Pulled") - - # for permanent type : T_n : X or O ( n here is teeth number like 1, 2, 3) - "T_1": "X", - "T_32": "O", - - # for primay type: T_x : X or 0 (x here is alphabet) - "T_A": "X", - "T_B": "O", - }, - "remarks": "Hello remarks" -} - -class AutomationMassDHP: - def __init__(self): - self.headless = False - self.driver = None - - def config_driver(self): - options = webdriver.ChromeOptions() - if self.headless: - options.add_argument("--headless") - s = Service(ChromeDriverManager().install()) - driver = webdriver.Chrome(service=s, options=options) - self.driver = driver - - def login(self): - wait = WebDriverWait(self.driver, 30) - - try: - # Enter email - email_field = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@name='Email' and @type='text']"))) - email_field.clear() - email_field.send_keys(data["massdhp_username"]) - - # Enter password - password_field = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@name='Pass' and @type='password']"))) - password_field.clear() - password_field.send_keys(data["massdhp_password"]) - - # Click login - login_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@type='submit' and @value='Login']"))) - login_button.click() - - print("Login submitted successfully.") - - except Exception as e: - print(f"Error while logging in: {e}") - return "ERROR:LOGIN FAILED" - - def step1(self): - wait = WebDriverWait(self.driver, 30) - - try: - claim_upload_link = wait.until( - EC.element_to_be_clickable((By.XPATH, "//a[text()='Claim Upload']")) - ) - claim_upload_link.click() - - time.sleep(3) - - # Fill Member ID - member_id_input = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Text1"]'))) - member_id_input.clear() - member_id_input.send_keys(data["memberId"]) - - # Fill DOB parts - try: - dob_parts = data["dateOfBirth"].split("/") - month= dob_parts[0].zfill(2) # "12" - day= dob_parts[1].zfill(2) # "13" - year = dob_parts[2] # "1965" - except Exception as e: - print(f"Error parsing DOB: {e}") - return "ERROR: PARSING DOB" - - - wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Text2"]'))).send_keys(month) - wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Text3"]'))).send_keys(day) - wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Text4"]'))).send_keys(year) - - # Rendering Provider NPI dropdown - npi_dropdown = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Select1"]'))) - select_npi = Select(npi_dropdown) - select_npi.select_by_index(1) - - # Office Location dropdown - location_dropdown = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="Select2"]'))) - select_location = Select(location_dropdown) - select_location.select_by_index(1) - - # Click Continue button - continue_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[@type="submit" and @value="Continue"]'))) - continue_btn.click() - - - # Check for error message - try: - error_msg = WebDriverWait(self.driver, 5).until(EC.presence_of_element_located( - (By.XPATH, "//td[@class='text_err_msg' and contains(text(), 'Invalid Member ID or Date of Birth')]") - )) - if error_msg: - print("Error: Invalid Member ID or Date of Birth.") - return "ERROR: INVALID MEMBERID OR DOB" - except TimeoutException: - pass - - except Exception as e: - print(f"Error while step1 i.e Cheking the MemberId and DOB in: {e}") - return "ERROR:STEP1" - - def step2(self): - - wait = WebDriverWait(self.driver, 30) - - # already waiting in step1 last part, so no time sleep. - - # 1 - Procedure Codes part - try: - for proc in data["procedure_codes"]: - # Wait for Procedure Code dropdown and select code - - select_element = wait.until(EC.presence_of_element_located((By.XPATH, "//select[@id='Select3']"))) - Select(select_element).select_by_value(proc['procedure_code']) - - # Fill Procedure Date if present - if proc.get("procedure_date"): - try: - # Try to normalize date to MM/DD/YYYY format - parsed_date = datetime.strptime(proc["procedure_date"], "%m/%d/%Y") - formatted_date = parsed_date.strftime("%m/%d/%Y") - - date_xpath = "//input[@name='ProcedureDate']" - wait.until(EC.presence_of_element_located((By.XPATH, date_xpath))).clear() - self.driver.find_element(By.XPATH, date_xpath).send_keys(formatted_date) - - except ValueError: - # Invalid date format - skip filling ProcedureDate field - pass - - # Fill Oral Cavity Area if present - if proc.get("oralCavityArea"): - oral_xpath = "//input[@name='OralCavityArea']" - wait.until(EC.presence_of_element_located((By.XPATH, oral_xpath))).clear() - self.driver.find_element(By.XPATH, oral_xpath).send_keys(proc["oralCavityArea"]) - - # Fill Tooth Number if present - if proc.get("toothNumber"): - tooth_num_dropdown = wait.until(EC.presence_of_element_located((By.XPATH, "//select[@name='ToothNumber']"))) - select_tooth = Select(tooth_num_dropdown) - select_tooth.select_by_value(proc["toothNumber"]) - - - # Fill Tooth Surface if present - if proc.get("toothSurface"): - surface = proc["toothSurface"] - checkbox_xpath = f"//input[@type='checkbox' and @name='TS_{surface}']" - checkbox = wait.until(EC.element_to_be_clickable((By.XPATH, checkbox_xpath))) - if not checkbox.is_selected(): - checkbox.click() - - - # Fill Fees if present - if proc.get("fees"): - fees_xpath = "//input[@name='ProcedureFee']" - wait.until(EC.presence_of_element_located((By.XPATH, fees_xpath))).clear() - self.driver.find_element(By.XPATH, fees_xpath).send_keys(proc["fees"]) - - # Click "Add Procedure" button - add_proc_xpath = "//input[@type='submit' and @value='Add Procedure']" - wait.until(EC.element_to_be_clickable((By.XPATH, add_proc_xpath))).click() - - time.sleep(1) - - - print("Procedure codes submitted successfully.") - - except Exception as e: - print(f"Error while filling Procedure Codes: {e}") - return "ERROR:PROCEDURE CODES" - - # 2 - Upload PDFs: - try: - pdfs_abs = [os.path.abspath(pdf) for pdf in data["pdfs"]] - - for pdf in pdfs_abs: - # Wait for file input and upload file - file_input = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@name='FileName' and @type='file']"))) - file_input.send_keys(pdf) - - # Wait for upload button and click it - upload_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@type='submit' and @value='Upload File']"))) - upload_button.click() - - time.sleep(3) - except Exception as e: - print(f"Error while uploading PDFs: {e}") - return "ERROR:PDF FAILED" - - # 3 - Indicate Missing Teeth Part - try: - # Handle the missing teeth section based on the status - missing_status = data.get("missingTeethStatus") - - if missing_status == "No_missing": - missing_teeth_no = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@type='checkbox' and @name='PAU_Step3_Checkbox1']"))) - missing_teeth_no.click() - - elif missing_status == "endentulous": - missing_teeth_edentulous = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@type='checkbox' and @name='PAU_Step3_Checkbox2']"))) - missing_teeth_edentulous.click() - - elif missing_status == "Yes_missing": - missing_teeth_dict = data.get("missingTeeth", {}) - - # For each tooth in the missing teeth dict, select the dropdown option - for tooth_name, value in missing_teeth_dict.items(): - if value: # only if there's a value to select - select_element = wait.until(EC.presence_of_element_located((By.XPATH, f"//select[@name='{tooth_name}']"))) - select_obj = Select(select_element) - select_obj.select_by_value(value) - - - # Wait for upload button and click it - update_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@type='submit' and @value='Update Missing Teeth']"))) - update_button.click() - - time.sleep(3) - except Exception as e: - print(f"Error while filling missing teeth: {e}") - return "ERROR:MISSING TEETH FAILED" - - - # 4 - Update Remarks - try: - textarea = wait.until(EC.presence_of_element_located((By.XPATH, "//textarea[@name='Remarks']"))) - textarea.clear() - textarea.send_keys(data["remarks"]) - - # Wait for update button and click it - update_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@type='submit' and @value='Update Remarks']"))) - update_button.click() - - time.sleep(3) - - except Exception as e: - print(f"Error while filling remarks: {e}") - return "ERROR:REMARKS FAILED" - - - def main_workflow(self, url): - self.config_driver() - print("Reaching Site :", url) - self.driver.maximize_window() - self.driver.get(url) - time.sleep(3) - value = self.login() - if value.startswith("ERROR"): - self.driver.close() - return value - - - time.sleep(5) - value2 = self.step1() - if value2.startswith("ERROR"): - self.driver.close() - return value2 - - time.sleep(5) - value3 = self.step2() - if value3.startswith("ERROR"): - self.driver.close() - return value3 - - - input("should Close?") # here it sholud get confirmation from the frontend, - - self.driver.close() - - -obj1 = AutomationMassDHP() -obj1.main_workflow(url= "https://providers.massdhp.com/providers_login.asp") \ No newline at end of file diff --git a/apps/SeleniumService/selenium_worker.py b/apps/SeleniumService/selenium_worker.py index dc62390..73080d7 100644 --- a/apps/SeleniumService/selenium_worker.py +++ b/apps/SeleniumService/selenium_worker.py @@ -24,7 +24,7 @@ class AutomationMassHealth: self.data = data self.claim = data.get("claim", {}) - self.pdfs = data.get("pdfs", []) + self.upload_files = data.get("pdfs", []) + data.get("images", []) # Flatten values for convenience self.memberId = self.claim.get("memberId", "") @@ -211,12 +211,14 @@ class AutomationMassHealth: # 2 - Upload PDFs: try: - pdfs_abs = [proc for proc in self.pdfs] - with tempfile.TemporaryDirectory() as tmp_dir: - for pdf_obj in pdfs_abs: - base64_data = pdf_obj["bufferBase64"] - file_name = pdf_obj.get("originalname", "tempfile.pdf") + for file_obj in self.upload_files: + base64_data = file_obj["bufferBase64"] + file_name = file_obj.get("originalname", "tempfile.bin") + + # Ensure valid extension fallback if missing + if not any(file_name.lower().endswith(ext) for ext in [".pdf", ".jpg", ".jpeg", ".png", ".webp"]): + file_name += ".bin" # Full path with original filename inside temp dir tmp_file_path = os.path.join(tmp_dir, file_name)