sonuprasad23 commited on
Commit
da2774c
·
1 Parent(s): d8ce988

Almost Done

Browse files
Files changed (2) hide show
  1. server.py +12 -5
  2. worker.py +40 -32
server.py CHANGED
@@ -137,7 +137,8 @@ def run_automation_process(session_id):
137
  if workflow == 'void':
138
  results = bot_instance.process_void_list(patient_data)
139
  elif workflow == 'refund':
140
- results = bot_instance.process_refund_list(patient_data, data.get('start_date'), data.get('end_date'))
 
141
  is_terminated = bot_instance.termination_event.is_set()
142
  except Exception as e:
143
  print(f"[Server Log] Fatal error in automation thread: {e}"); is_crash = True
@@ -151,7 +152,7 @@ def run_automation_process(session_id):
151
  def generate_and_send_reports(session_id, results, is_crash_report=False, is_terminated=False):
152
  data = session_data.get(session_id, {})
153
  if not data: return
154
-
155
  full_df = pd.DataFrame(data.get('patient_data_for_report'))
156
  if results:
157
  result_df = pd.DataFrame(results)
@@ -177,7 +178,7 @@ def generate_and_send_reports(session_id, results, is_crash_report=False, is_ter
177
  bad_report_name: bad_df.to_csv(index=False),
178
  skipped_report_name: skipped_df.to_csv(index=False)
179
  }
180
- status_text = "terminated by user" if is_terminated else "crashed due to an error" if is_crash_report else "completed successfully"
181
  stats = {
182
  'total': len(full_df), 'processed': len(results),
183
  'successful': len(full_df[full_df['Status'] == 'Done']),
@@ -218,7 +219,7 @@ def handle_file_processing():
218
  master_df['PRN'] = master_df['Name'].apply(lambda name: prn_lookup_dict.get(name, ""))
219
  master_df['Status'] = ''
220
 
221
- session_data[session_id]['patient_data_for_report'] = master_df.copy()
222
  session_data[session_id]['patient_data'] = master_df.to_dict('records')
223
 
224
  socketio.emit('data_processed')
@@ -236,7 +237,13 @@ def handle_connect():
236
  @socketio.on('initialize_session')
237
  def handle_init(data):
238
  session_id = 'user_session'
239
- session_data[session_id] = {'emails': data['emails'], 'filename': data['filename'], 'workflow': data['workflow'], 'start_date': data.get('start_date'), 'end_date': data.get('end_date')}
 
 
 
 
 
 
240
 
241
  @socketio.on('start_login')
242
  def handle_login(credentials):
 
137
  if workflow == 'void':
138
  results = bot_instance.process_void_list(patient_data)
139
  elif workflow == 'refund':
140
+ date_range = {'start_date': data.get('start_date'), 'end_date': data.get('end_date')}
141
+ results = bot_instance.process_refund_list(patient_data, date_range)
142
  is_terminated = bot_instance.termination_event.is_set()
143
  except Exception as e:
144
  print(f"[Server Log] Fatal error in automation thread: {e}"); is_crash = True
 
152
  def generate_and_send_reports(session_id, results, is_crash_report=False, is_terminated=False):
153
  data = session_data.get(session_id, {})
154
  if not data: return
155
+
156
  full_df = pd.DataFrame(data.get('patient_data_for_report'))
157
  if results:
158
  result_df = pd.DataFrame(results)
 
178
  bad_report_name: bad_df.to_csv(index=False),
179
  skipped_report_name: skipped_df.to_csv(index=False)
180
  }
181
+ status_text = "terminated by user" if is_terminated else "crashed" if is_crash_report else "completed successfully"
182
  stats = {
183
  'total': len(full_df), 'processed': len(results),
184
  'successful': len(full_df[full_df['Status'] == 'Done']),
 
219
  master_df['PRN'] = master_df['Name'].apply(lambda name: prn_lookup_dict.get(name, ""))
220
  master_df['Status'] = ''
221
 
222
+ session_data[session_id]['patient_data_for_report'] = master_df
223
  session_data[session_id]['patient_data'] = master_df.to_dict('records')
224
 
225
  socketio.emit('data_processed')
 
237
  @socketio.on('initialize_session')
238
  def handle_init(data):
239
  session_id = 'user_session'
240
+ session_data[session_id] = {
241
+ 'emails': data['emails'],
242
+ 'filename': data['filename'],
243
+ 'workflow': data['workflow'],
244
+ 'start_date': data.get('start_date'),
245
+ 'end_date': data.get('end_date')
246
+ }
247
 
248
  @socketio.on('start_login')
249
  def handle_login(credentials):
worker.py CHANGED
@@ -2,6 +2,7 @@ import time
2
  import threading
3
  import subprocess
4
  import pandas as pd
 
5
  from selenium import webdriver
6
  from selenium.webdriver.chrome.service import Service as ChromeService
7
  from selenium.webdriver.chrome.options import Options as ChromeOptions
@@ -35,12 +36,10 @@ class QuantumBot:
35
  options.add_argument(f"--user-agent={user_agent}")
36
  service = ChromeService(executable_path="/usr/bin/chromedriver")
37
  self.driver = webdriver.Chrome(service=service, options=options)
38
- self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
39
- 'source': "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
40
- })
41
  return True, None
42
  except Exception as e:
43
- error_message = f"Message: {str(e)}"; print(f"CRITICAL ERROR in WebDriver Initialization: {error_message}")
44
  return False, error_message
45
 
46
  def micro_status(self, message):
@@ -53,10 +52,8 @@ class QuantumBot:
53
 
54
  def login(self, username, password):
55
  try:
56
- self.micro_status("Navigating to login page...")
57
- self.driver.get("https://gateway.quantumepay.com/")
58
- time.sleep(2)
59
- self.micro_status("Entering credentials...")
60
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "Username"))).send_keys(username)
61
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "Password"))).send_keys(password)
62
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.ID, "login"))).click()
@@ -64,23 +61,21 @@ class QuantumBot:
64
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "code1")))
65
  return True, None
66
  except Exception as e:
67
- error_message = f"Error during login: {str(e)}"; print(f"[Bot Log] ERROR during login: {error_message}")
68
  return False, error_message
69
 
70
  def submit_otp(self, otp):
71
  try:
72
- self.micro_status(f"Submitting OTP...")
73
- otp_digits = list(otp)
74
- for i in range(6):
75
- self.driver.find_element(By.ID, f"code{i+1}").send_keys(otp_digits[i])
76
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.ID, "login"))).click()
77
  self.micro_status("Verifying login success...")
78
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Payments']")))
79
  return True, None
80
  except Exception as e:
81
- error_message = f"Error during OTP submission: {str(e)}"; print(f"[Bot Log] ERROR during OTP submission: {error_message}")
82
  return False, error_message
83
-
84
  def _get_calendar_months(self):
85
  try:
86
  titles = self.driver.find_elements(By.XPATH, "//div[contains(@class, 'vc-title')]")
@@ -114,30 +109,21 @@ class QuantumBot:
114
  self.driver.find_element(By.TAG_NAME, "body").click()
115
  time.sleep(3)
116
 
117
- def process_patient_list(self, patient_data, workflow, date_range=None):
118
  results = []
119
- records_to_process = list(patient_data)
120
- for index, record in enumerate(records_to_process):
121
  if self.termination_event.is_set(): print("[Bot Log] Termination detected."); break
122
  patient_name = record['Name']; patient_prn = record.get('PRN', '')
123
  if not patient_prn or not str(patient_prn).strip():
124
- status = 'Skipped - No PRN'
125
  self.micro_status(f"Skipping '{patient_name}' (No PRN).")
126
- time.sleep(0.2)
127
  else:
128
- self.micro_status(f"Processing '{patient_name}' ({index + 1}/{len(records_to_process)})...")
129
- if workflow == 'void':
130
- status = self._process_single_void(patient_name, patient_prn)
131
- elif workflow == 'refund':
132
- status = self._process_single_refund(patient_name, patient_prn, date_range['start_date'], date_range['end_date'])
133
  results.append({'Name': patient_name, 'PRN': patient_prn, 'Status': status})
134
  with self.app.app_context():
135
  self.socketio.emit('log_update', {'name': patient_name, 'prn': patient_prn, 'status': status})
136
- self.socketio.emit('stats_update', {
137
- 'processed': len(results),
138
- 'remaining': len(records_to_process) - len(results),
139
- 'status': status
140
- })
141
  return results
142
 
143
  def _process_single_void(self, patient_name, patient_prn):
@@ -178,12 +164,34 @@ class QuantumBot:
178
  except Exception as e:
179
  print(f"An error occurred while processing {patient_name}: {e}"); return 'Error'
180
 
181
- def _process_single_refund(self, patient_name, patient_prn, start_date, end_date):
 
182
  try:
183
  self.micro_status(f"Navigating to Refund page...")
184
  self.driver.get("https://gateway.quantumepay.com/credit-card/refund")
185
  self._set_date_range(start_date, end_date)
186
- self.micro_status(f"Searching for '{patient_name}'...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  search_box = WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//input[@placeholder='Search']")))
188
  search_box.click(); time.sleep(0.5); search_box.clear(); time.sleep(0.5)
189
  search_box.send_keys(patient_name)
 
2
  import threading
3
  import subprocess
4
  import pandas as pd
5
+ import os
6
  from selenium import webdriver
7
  from selenium.webdriver.chrome.service import Service as ChromeService
8
  from selenium.webdriver.chrome.options import Options as ChromeOptions
 
36
  options.add_argument(f"--user-agent={user_agent}")
37
  service = ChromeService(executable_path="/usr/bin/chromedriver")
38
  self.driver = webdriver.Chrome(service=service, options=options)
39
+ self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"})
 
 
40
  return True, None
41
  except Exception as e:
42
+ error_message = f"Message: {str(e)}"; print(f"CRITICAL ERROR: {error_message}")
43
  return False, error_message
44
 
45
  def micro_status(self, message):
 
52
 
53
  def login(self, username, password):
54
  try:
55
+ self.micro_status("Navigating to login page..."); self.driver.get("https://gateway.quantumepay.com/")
56
+ time.sleep(2); self.micro_status("Entering credentials...")
 
 
57
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "Username"))).send_keys(username)
58
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "Password"))).send_keys(password)
59
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.ID, "login"))).click()
 
61
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.presence_of_element_located((By.ID, "code1")))
62
  return True, None
63
  except Exception as e:
64
+ error_message = f"Error during login: {str(e)}"; print(f"[Bot Log] ERROR: {error_message}")
65
  return False, error_message
66
 
67
  def submit_otp(self, otp):
68
  try:
69
+ self.micro_status(f"Submitting OTP..."); otp_digits = list(otp)
70
+ for i in range(6): self.driver.find_element(By.ID, f"code{i+1}").send_keys(otp_digits[i])
 
 
71
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.ID, "login"))).click()
72
  self.micro_status("Verifying login success...")
73
  WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Payments']")))
74
  return True, None
75
  except Exception as e:
76
+ error_message = f"Error during OTP submission: {str(e)}"; print(f"[Bot Log] ERROR: {error_message}")
77
  return False, error_message
78
+
79
  def _get_calendar_months(self):
80
  try:
81
  titles = self.driver.find_elements(By.XPATH, "//div[contains(@class, 'vc-title')]")
 
109
  self.driver.find_element(By.TAG_NAME, "body").click()
110
  time.sleep(3)
111
 
112
+ def process_void_list(self, patient_data):
113
  results = []
114
+ for index, record in enumerate(patient_data):
 
115
  if self.termination_event.is_set(): print("[Bot Log] Termination detected."); break
116
  patient_name = record['Name']; patient_prn = record.get('PRN', '')
117
  if not patient_prn or not str(patient_prn).strip():
 
118
  self.micro_status(f"Skipping '{patient_name}' (No PRN).")
119
+ status = 'Skipped - No PRN'; time.sleep(0.2)
120
  else:
121
+ self.micro_status(f"Processing '{patient_name}' ({index + 1}/{len(patient_data)})...")
122
+ status = self._process_single_void(patient_name, patient_prn)
 
 
 
123
  results.append({'Name': patient_name, 'PRN': patient_prn, 'Status': status})
124
  with self.app.app_context():
125
  self.socketio.emit('log_update', {'name': patient_name, 'prn': patient_prn, 'status': status})
126
+ self.socketio.emit('stats_update', {'processed': len(results), 'remaining': len(patient_data) - len(results), 'status': status})
 
 
 
 
127
  return results
128
 
129
  def _process_single_void(self, patient_name, patient_prn):
 
164
  except Exception as e:
165
  print(f"An error occurred while processing {patient_name}: {e}"); return 'Error'
166
 
167
+ def process_refund_list(self, patient_data, start_date, end_date):
168
+ results = []
169
  try:
170
  self.micro_status(f"Navigating to Refund page...")
171
  self.driver.get("https://gateway.quantumepay.com/credit-card/refund")
172
  self._set_date_range(start_date, end_date)
173
+ for index, record in enumerate(patient_data):
174
+ if self.termination_event.is_set(): print("[Bot Log] Termination detected."); break
175
+ patient_name = record['Name']; patient_prn = record.get('PRN', '')
176
+ if not patient_prn or not str(patient_prn).strip():
177
+ status = 'Skipped - No PRN'
178
+ self.micro_status(f"Skipping '{patient_name}' (No PRN).")
179
+ time.sleep(0.2)
180
+ else:
181
+ self.micro_status(f"Processing '{patient_name}' ({index + 1}/{len(patient_data)})...")
182
+ status = self._process_single_refund(patient_name, patient_prn)
183
+ results.append({'Name': patient_name, 'PRN': patient_prn, 'Status': status})
184
+ with self.app.app_context():
185
+ self.socketio.emit('log_update', {'name': patient_name, 'prn': patient_prn, 'status': status})
186
+ self.socketio.emit('stats_update', {'processed': len(results), 'remaining': len(patient_data) - len(results), 'status': status})
187
+ except Exception as e:
188
+ print(f"A fatal error occurred during the Refund workflow: {e}")
189
+ self.micro_status("A fatal error stopped the Refund process.")
190
+ return results
191
+
192
+ def _process_single_refund(self, patient_name, patient_prn):
193
+ try:
194
+ self.micro_status(f"Searching for '{patient_name}' on Refund page...")
195
  search_box = WebDriverWait(self.driver, self.DEFAULT_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//input[@placeholder='Search']")))
196
  search_box.click(); time.sleep(0.5); search_box.clear(); time.sleep(0.5)
197
  search_box.send_keys(patient_name)