import sys
import requests
from PyQt6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton,
QHBoxLayout, QStackedWidget, QCheckBox, QTextEdit
)
from PyQt6.QtGui import QPixmap, QFont
from PyQt6.QtCore import Qt, QDateTime, QDate
# --- Login Screen ---
class LoginScreen(QWidget):
def __init__(self, stacked):
super().__init__()
self.stacked = stacked
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
logo = QLabel()
logo.setPixmap(QPixmap(
r'C:\Users\Administrator\Downloads\sfg printing\backup from airline device\SRIMATHI\cri_logo.png.png'
).scaled(100, 100, Qt.AspectRatioMode.KeepAspectRatio))
logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(logo)
title_label = QLabel("Login Screen")
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
title_label.setStyleSheet("font-size: 18px; font-weight: bold; color: #002244; margin-bottom: 10px;")
layout.addWidget(title_label)
self.username = QLineEdit()
self.username.setPlaceholderText("Username")
layout.addWidget(self.username)
pw_layout = QHBoxLayout()
self.password = QLineEdit()
self.password.setPlaceholderText("Password")
self.password.setEchoMode(QLineEdit.EchoMode.Password)
pw_layout.addWidget(self.password)
self.eye_toggle = QCheckBox("Show")
self.eye_toggle.toggled.connect(lambda checked: self.password.setEchoMode(
QLineEdit.EchoMode.Normal if checked else QLineEdit.EchoMode.Password))
pw_layout.addWidget(self.eye_toggle)
layout.addLayout(pw_layout)
self.username.returnPressed.connect(self.password.setFocus)
self.password.returnPressed.connect(self.do_login)
login_btn = QPushButton("Login")
login_btn.clicked.connect(self.do_login)
layout.addWidget(login_btn)
logo2 = QLabel()
logo2.setPixmap(QPixmap(
r'C:\Users\Administrator\Downloads\sfg printing\backup from airline device\SRIMATHI\cri_farm_banner.jpg'
).scaled(200, 200, Qt.AspectRatioMode.KeepAspectRatio))
logo2.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(logo2)
self.setLayout(layout)
def do_login(self):
if self.username.text() and self.password.text():
self.stacked.setCurrentIndex(1)
# --- Module Selector ---
class SelectorScreen(QWidget):
def __init__(self, stacked, bot_screen):
super().__init__()
self.stacked = stacked
self.bot_screen = bot_screen
self.init_ui()
self.load_module_list()
def init_ui(self):
self.layout = QVBoxLayout()
title_label = QLabel("Selector Screen")
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
title_label.setStyleSheet("font-size: 18px; font-weight: bold; color: #002244;")
self.layout.addWidget(title_label)
date_label = QLabel(QDate.currentDate().toString("dddd, MMMM d, yyyy"))
date_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
date_label.setFont(QFont("Arial", 14, QFont.Weight.Bold))
self.layout.addWidget(date_label)
self.button_container = QVBoxLayout()
self.layout.addLayout(self.button_container)
self.setLayout(self.layout)
def load_module_list(self):
url = 'https://pds.iotsignin.com/api/get/module-name/data'
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"module-name": "Module List"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
data = response.json()
for module in data.get("status_description", []):
self.add_module_button(module)
else:
self.show_error(f"Failed to load modules: {response.status_code}")
except Exception as e:
self.show_error(str(e))
def add_module_button(self, module_name):
btn = QPushButton(module_name)
btn.setStyleSheet(
"padding: 10px; background-color: #c2185b; color: white; font-size: 14px; border-radius: 8px;")
btn.clicked.connect(lambda _, name=module_name: self.goto_bot_screen(name))
self.button_container.addWidget(btn)
def show_error(self, msg):
error = QLabel(f"❌ {msg}")
error.setStyleSheet("color: red;")
self.layout.addWidget(error)
def goto_bot_screen(self, module_name):
self.bot_screen.set_module_name(module_name)
self.stacked.setCurrentIndex(2)
# --- BotScreen: full chat-driven selection ---
class BotScreen(QWidget):
def __init__(self, stacked):
super().__init__()
self.stacked = stacked
self.module_name = ""
self.charts = []
self.plants = []
self.lines = []
self.filters = []
self.invoice_types = []
self.awaiting_chart_choice = False
self.awaiting_plant_choice = False
self.awaiting_line_choice = False
self.awaiting_order_input = False
self.awaiting_filter_choice = False
self.awaiting_invoice_choice = False
self.selected_chart = None
self.selected_plant = None
self.selected_line = None
self.selected_order = None
self.selected_filter = None
self.selected_invoice_type = None
self.init_ui()
def set_module_name(self, name):
self.module_name = name
self.clear_chat()
self.load_chart_data()
def init_ui(self):
main_layout = QVBoxLayout()
top_bar = QHBoxLayout()
logo = QLabel()
logo.setPixmap(QPixmap(
r'C:\Users\Administrator\Downloads\sfg printing\backup from airline device\SRIMATHI\cri_logo.png.png'
).scaled(40, 40, Qt.AspectRatioMode.KeepAspectRatio))
top_bar.addWidget(logo)
title = QLabel("CRI DIGITAL MANUFACTURING SOLUTIONS \n CRI BOT ASSISTANT")
title.setStyleSheet("font-size: 16px; font-weight: bold; color: black; padding: 10px; border-radius: 8px;")
top_bar.addWidget(title)
top_bar.addStretch()
back_btn = QPushButton("Back")
back_btn.clicked.connect(self.go_back)
top_bar.addWidget(back_btn)
refresh_btn = QPushButton("Refresh")
refresh_btn.clicked.connect(self.load_chart_data)
top_bar.addWidget(refresh_btn)
main_layout.addLayout(top_bar)
self.chart_info = QLabel("Waiting for chart data...")
self.chart_info.setWordWrap(True)
self.chart_info.setStyleSheet(
"background: white; color: black; font-size: 15px; padding: 14px; border-radius: 10px")
main_layout.addWidget(self.chart_info)
self.chat_area = QTextEdit()
self.chat_area.setReadOnly(True)
self.chat_area.setStyleSheet("background-color: white; color: black; padding: 10px; font-size: 14px;")
main_layout.addWidget(self.chat_area)
input_layout = QHBoxLayout()
self.user_input = QLineEdit()
self.user_input.setPlaceholderText("Type a number to select...")
input_layout.addWidget(self.user_input)
send_btn = QPushButton("Send")
send_btn.setStyleSheet(
"padding: 8px; background: #2e7d32; color: white; border-radius: 8px;")
send_btn.clicked.connect(self.send_message)
input_layout.addWidget(send_btn)
main_layout.addLayout(input_layout)
self.setLayout(main_layout)
def load_chart_data(self):
self.chart_info.setText("Loading chart data...")
url = 'https://pds.iotsignin.com/api/get/modulechart-name/data'
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"module-name": self.module_name
}
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
status = data.get("status_code", "UNKNOWN")
desc = data.get("status_description", [])
self.chart_info.setText(f"API Status: {status}")
self.chat_area.append(f"HTTP: {response.status_code}")
self.chat_area.append(f"Bot Module: {self.module_name}")
if isinstance(desc, list) and desc:
self.charts = desc
else:
self.charts = [
"Production Line Count",
"Production Hourly Count",
"Production Line Stop Count",
"Production Order Count"
]
self.awaiting_chart_choice = True
self.show_choice_menu("chart", self.charts)
except Exception as e:
self.chart_info.setText("Failed to load chart data.")
self.chat_area.append(f"Bot: Error: {e}")
def show_choice_menu(self, item, items_list):
label_map = {
"chart": "chart",
"plant": "plant",
"line": "line",
"order": "production order",
"filter": "date filter",
"invoice": "invoice type",
}
# Ensure name extraction works for both simple str and dict/list cases.
lines = [
f"{i + 1}. {item_name['name'] if isinstance(item_name, dict) and 'name' in item_name else str(item_name)}"
for i, item_name in enumerate(items_list)
]
menu_txt = f"Bot: Please select a {label_map[item]}:
" + "
".join(lines)
self.chat_area.append(menu_txt)
def send_message(self):
msg = self.user_input.text().strip()
self.user_input.clear()
# --- Chart selection ---
if self.awaiting_chart_choice:
if msg.isdigit():
idx = int(msg) - 1
if 0 <= idx < len(self.charts):
self.selected_chart = self.charts[idx]
self.awaiting_chart_choice = False
self.chat_area.append(f"Bot: ✅ You selected: {self.selected_chart}")
self.fetch_and_display_plants()
else:
self.chat_area.append(f"Bot: ❌ Please select a number from 1 to {len(self.charts)}.")
else:
self.chat_area.append(f"Bot: ❌ Please enter a number (1-{len(self.charts)}).")
return
# --- Plant selection ---
if self.awaiting_plant_choice:
if msg.isdigit():
idx = int(msg) - 1
if 0 <= idx < len(self.plants):
self.selected_plant = self.plants[idx]
self.awaiting_plant_choice = False
self.chat_area.append(f"Bot: ✅ You selected: {self.selected_plant}")
# Normalize chart name and check for invoice / invoice quantity charts explicitly
selected_chart_name = (self.selected_chart or "").strip().lower()
if selected_chart_name == "invoice":
# Fetch invoice types for regular invoice dashboard
self.fetch_and_display_invoice_types()
elif selected_chart_name == "invoice quantity":
# For invoice quantity, also fetch invoice types first (if needed)
self.fetch_and_display_invoice_types()
# Alternatively: if invoice type is fixed or selection is not needed, you can
# proceed to date filter directly by calling
# self.fetch_and_display_invoice_filters() here if your flow allows
else:
# For other charts, fetch lines normally
self.fetch_and_display_lines()
else:
self.chat_area.append(f"Bot: ❌ Please select a number from 1 to {len(self.plants)}.")
else:
self.chat_area.append(f"Bot: ❌ Please enter a number (1–{len(self.plants)}).")
return
# --- Line selection ---
if self.awaiting_line_choice:
if msg.isdigit():
idx = int(msg) - 1
if 0 <= idx < len(self.lines):
self.selected_line = self.lines[idx]
self.awaiting_line_choice = False
self.chat_area.append(f"Bot: ✅ You selected: {self.selected_line}")
chart_raw = self.selected_chart
chart_normalized = chart_raw.strip().lower() if chart_raw else ""
# 🚩 Only for Chart 4 (Production Order Count)
if chart_normalized == "production order count":
print(f"[DEBUG] self.selected_chart (raw): '{self.selected_chart}'")
self.awaiting_order_input = True # Set state for next prompt
self.chat_area.append("Bot: Please enter the production order number:")
else:
self.fetch_and_display_filters()
else:
self.chat_area.append(f"Bot: ❌ Please select a number from 1 to {len(self.lines)}.")
else:
self.chat_area.append(f"Bot: ❌ Please enter a number (1-{len(self.lines)}).")
return
# --- Production order entry (Chart 4 only) ---
if hasattr(self, 'awaiting_order_input') and self.awaiting_order_input:
order = msg.strip()
if not order.isdigit():
self.chat_area.append("Bot: ❌ Please enter a valid production order number (numbers only).")
else:
self.selected_order = order
self.awaiting_order_input = False
self.chat_area.append(f"Bot: ✅ Production order set: {self.selected_order}")
self.fetch_and_display_filters()
return
#-------if MODULE 2, chart 2 then this part will execute here---------
if self.awaiting_invoice_choice:
if msg.isdigit():
idx = int(msg) - 1
if 0 <= idx < len(self.invoice_types):
self.selected_invoice_type = self.invoice_types[idx]
self.awaiting_invoice_choice = False
self.chat_area.append(
f"Bot: ✅ You selected invoice type: {self.selected_invoice_type}"
)
# Normalize selected chart to distinguish between Invoice and Invoice Quantity dashboards
selected_chart_name = (self.selected_chart or "").strip().lower()
if selected_chart_name == "invoice":
# For "Invoice" chart, fetch invoice filters (date filters)
self.fetch_and_display_invoice_filters()
elif selected_chart_name == "invoice quantity":
# For "Invoice Quantity" chart, fetch invoice filters as well
self.fetch_and_display_invoice_filters()
else:
# If future charts, handle accordingly or fallback
self.chat_area.append(
"Bot: ❌ Unrecognized invoice chart selected."
)
else:
self.chat_area.append(
f"Bot: ❌ Please select a number from 1 to {len(self.invoice_types)}."
)
else:
self.chat_area.append(
f"Bot: ❌ Please enter a valid number (1–{len(self.invoice_types)})."
)
return
# --- Date filter selection ---
if self.awaiting_filter_choice:
if msg.isdigit():
idx = int(msg) - 1
if 0 <= idx < len(self.filters):
self.selected_filter = self.filters[idx]
self.awaiting_filter_choice = False
self.chat_area.append(f"Bot: ✅ You selected filter: {self.selected_filter}")
# Show current date/time
now = QDateTime.currentDateTime()
fmt_date = now.toString("dddd, MMMM d, yyyy, hh:mm AP")
self.chat_area.append(f"Current date: {fmt_date}")
selected = (self.selected_chart or "").strip().lower()
if "invoice" in selected:
# NEW: Handle invoice dashboard: no line name needed
self.fetch_and_display_invoice_production_count()
elif selected == "production hourly count":
self.fetch_and_display_hourly_count()
elif selected == "production line stop count":
self.fetch_and_display_production_line_stop_count()
elif selected == "production order count":
self.fetch_and_display_production_order_count()
elif selected == "invoice":
self.fetch_and_display_invoice_production_count()
else:
self.fetch_and_display_production_count()
else:
self.chat_area.append(f"Bot: ❌ Please select a number from 1 to {len(self.filters)}.")
else:
self.chat_area.append(f"Bot: ❌ Please enter a valid number (1–{len(self.filters)}).")
return
# handle user input
def fetch_and_display_plants(self):
url = 'https://pds.iotsignin.com/api/get/moduleplant-name/data'
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"plant-name": "Plant List"
}
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
if data.get("status_code") == "SUCCESS":
plants = data.get("status_description", [])
if plants:
self.plants = plants
self.awaiting_plant_choice = True
self.show_choice_menu("plant", plants)
else:
self.chat_area.append("Bot: ❌ No plants found.")
else:
self.chat_area.append(f"Bot: ❌ Error: {data.get('status_description')}")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Failed to load plants: {e}")
def fetch_and_display_lines(self):
url = 'https://pds.iotsignin.com/api/get/module-plantline-name/data'
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"plant-name": self.selected_plant,
"chart-name": self.selected_chart
}
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
if data.get("status_code") == "SUCCESS":
lines = data.get("status_description", [])
if lines:
self.lines = lines
self.awaiting_line_choice = True
self.show_choice_menu("line", lines)
else:
self.chat_area.append("Bot: ❌ No lines found for the selected plant.")
else:
self.chat_area.append(f"Bot: ❌ Error: {data.get('status_description')}")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Failed to load lines: {e}")
def fetch_and_display_filters(self):
selected_chart_lower = (self.selected_chart or "").strip().lower()
# URL remains the same unless invoice filters come from a different path
url = 'https://pds.iotsignin.com/api/get/module-line-filter-name/data'
# Base headers
headers = {
"Authorization": self.API_TOKEN
}
# Check if it’s an invoice chart by partial match
if "invoice" in selected_chart_lower:
# INVOICE FLOW: Skip line name, use invoice-type
url = 'https://pds.iotsignin.com/api/get/module-invoice-filter-name/data'
headers.update({
"module-name": self.module_name,
"chart-name": self.selected_chart,
"plant-name": self.selected_plant,
"invoice-type": self.selected_invoice_type
})
else:
# PRODUCTION FLOW: Use line name as before
headers.update({
"line-name": self.selected_line
})
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
if data.get("status_code") == "SUCCESS":
filters = data.get("status_description", [])
if filters:
self.filters = filters
self.awaiting_filter_choice = True
self.show_choice_menu("filter", filters)
self.fetch_and_display_invoice_production_count()
else:
self.chat_area.append("Bot: ❌ No date filters found for your selection.")
else:
self.chat_area.append(f"Bot: ❌ API Error: {data.get('status_description', 'Unknown error')}")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Failed to load date filters: {e}")
def fetch_and_display_production_count(self):
url = 'https://pds.iotsignin.com/api/get/module-filter-value/data'
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"module-name": self.module_name,
"chart-name": self.selected_chart,
"plant-name": self.selected_plant,
"line-name": self.selected_line,
"filter-name": self.selected_filter
}
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
if data.get("status_code") == "SUCCESS":
result = data.get("status_description")
if isinstance(result, dict):
self.chat_area.append(f"Bot: 📊 Production Counts (All Lines):")
for ln, count in result.items():
self.chat_area.append(f"{ln}: {count}")
else:
self.chat_area.append(f"Bot: 📈 Production Count: {result}")
else:
self.chat_area.append(f"Bot: ❌ Error getting production count: {data.get('status_description', 'Unknown')}")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Failed to load production count: {e}")
API_TOKEN = "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE="
#CHART -2 PRODUCTION HOURLY COUNT
def fetch_and_display_hourly_count(self):
url = "https://pds.iotsignin.com/api/get/module-filter-value/data"
# 👇 Pass everything only via HEADERS, not params
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"Accept": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"module-name": "Production Dashboard",
"chart-name": "Production Hourly Count", # ✅ Chart name as header
"plant-name": self.selected_plant, # ✅ From previous input
"line-name": self.selected_line, # ✅ From previous input
"filter-name": self.selected_filter # ✅ e.g., "Today", "Yesterday"
}
try:
response = requests.get(url, headers=headers, timeout=10)
# ✅ Print raw HTTP response to console
print("📡 [DEBUG] HTTP Status:", response.status_code)
print("📡 [DEBUG] Raw API Response:\n", response.text)
print("-" * 50) # Divider in logs
# ✅ Display raw response in chat area
self.chat_area.append(f"Raw API response:
{response.text}")
# 🔒 Handle empty API response
if not response.text.strip():
print("[DEBUG] ❌ Empty response received.")
self.chat_area.append("Bot: ❌ API returned no data.")
return
# 🔒 Try parsing JSON
try:
data = response.json()
except Exception as json_err:
print(f"[DEBUG] ❌ JSON Parse Error: {json_err}")
self.chat_area.append(f"Bot: ❌ Failed to parse data: {json_err}")
return
if data.get("status_code") == "SUCCESS":
now = QDateTime.currentDateTime().toString("dddd, MMMM d, yyyy, h:mm AP t")
self.chat_area.append(
f"📊 Production Hourly Count ({self.selected_filter}){req_status}")
# 🔒 Specific error handling
except requests.exceptions.HTTPError as errh:
print("[DEBUG] ❌ HTTP Error:", errh)
self.chat_area.append(f"Bot: ❌ HTTP Error: {errh}")
except requests.exceptions.ConnectionError:
print("[DEBUG] ❌ Connection Error.")
self.chat_area.append("Bot: ❌ Connection error.")
except requests.exceptions.Timeout:
print("[DEBUG] ❌ Timeout Error.")
self.chat_area.append("Bot: ❌ Request timed out.")
except Exception as e:
print(f"[DEBUG] ❌ General Error: {e}")
self.chat_area.append(f"Bot: ❌ Unexpected Error: {e}")
# PRODUCTION LINE STOP DATA
def fetch_and_display_production_line_stop_count(self):
# You must have these set by prior steps:
# self.selected_plant, self.selected_line, self.selected_filter
url = "https://pds.iotsignin.com/api/get/module-production-linestop/data"
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"module-name": "Production Dashboard",
"chart-name": "Production Line Stop",
"plant-name": self.selected_plant,
"line-name": self.selected_line,
"filter-name": self.selected_filter # Example: "Today"
}
try:
response = requests.get(url, headers=headers, timeout=10)
self.chat_area.append(f"Raw API response:{response.text}")
if response.status_code != 200:
self.chat_area.append(f"Bot: ❌ HTTP error {response.status_code}")
return
if not response.text.strip():
self.chat_area.append(f"Bot: ❌ No response from API.")
return
try:
data = response.json()
except Exception as e:
self.chat_area.append(f"Bot: ❌ Failed to parse API response: {e}")
return
current_date = QDateTime.currentDateTime().toString("dddd, MMMM d, yyyy, h:mm AP t")
if data.get("status_code") == "SUCCESS":
labels = data.get("labels", [])
values = data.get("data", [])
message = f"Production Line Stop Counts{response.text}")
if not response.text.strip():
print("[DEBUG] ❌ Empty API response received.")
self.chat_area.append("Bot: ❌ API returned no data.")
return
try:
data = response.json()
except Exception as json_err:
print(f"[DEBUG] ❌ JSON Parse Error: {json_err}")
self.chat_area.append(f"Bot: ❌ Failed to parse data: {json_err}")
return
status = data.get("status_code")
if status == "SUCCESS":
now = QDateTime.currentDateTime().toString("dddd, MMMM d, yyyy, h:mm AP t")
self.chat_area.append(
f"Production Order Count ({self.selected_filter}){status}")
except requests.exceptions.HTTPError as errh:
print("[DEBUG] ❌ HTTP Error:", errh)
self.chat_area.append(f"Bot: ❌ HTTP Error: {errh}")
except requests.exceptions.ConnectionError:
print("[DEBUG] ❌ Connection Error.")
self.chat_area.append("Bot: ❌ Connection error.")
except requests.exceptions.Timeout:
print("[DEBUG] ❌ Timeout Error.")
self.chat_area.append("Bot: ❌ Request timed out.")
except Exception as e:
print(f"[DEBUG] ❌ General Error: {e}")
self.chat_area.append(f"Bot: ❌ Unexpected Error: {e}")
def clear_chat(self):
self.chat_area.clear()
def go_back(self):
self.stacked.setCurrentIndex(1)
# MODULE -2 INVOICE DASHBOARD
#CHART-1 INVOICE
#to fetch the invoice types
def fetch_and_display_invoice_types(self):
url = "https://pds.iotsignin.com/api/get/module-invoice-type/data"
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"invoice-type-list": "Invoice Type List"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
data = response.json()
if data.get("status_code") == "SUCCESS":
self.invoice_types = data.get("status_description", [])
if self.invoice_types:
self.awaiting_invoice_choice = True
self.show_choice_menu("invoice", self.invoice_types)
else:
self.chat_area.append("Bot: ❌ No invoice types found.")
else:
error_msg = data.get("status_description", "Unknown error")
self.chat_area.append(f"Bot: ❌ Failed to get invoice types: {error_msg}")
else:
self.chat_area.append(f"Bot: ❌ HTTP Error {response.status_code} while fetching invoice types.")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Error getting invoice types: {str(e)}")
# To fetch date filter
def fetch_and_display_invoice_filters(self):
url = "http://pds.iotsignin.com/api/get/module-invoice-filter/data"
headers = {
"Authorization": "Bearer sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68:616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE=",
"filter-name": "Filter List"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code != 200:
self.chat_area.append(f"Bot: ❌ HTTP Error {response.status_code} when fetching filters.")
return
data = response.json()
if data.get("status_code") == "SUCCESS":
filters = data.get("status_description", [])
if filters:
self.filters = filters
self.awaiting_filter_choice = True
self.show_choice_menu("filter", filters)
else:
self.chat_area.append("Bot: ❌ No invoice filters found.")
else:
self.chat_area.append(f"Bot: ❌ API Error: {data.get('status_description', 'Unknown error')}")
except Exception as e:
self.chat_area.append(f"Bot: ❌ Exception when fetching invoice filters: {str(e)}")
# to fetch production count
def fetch_and_display_invoice_production_count(self):
url = "https://pds.iotsignin.com/api/get/module-invoice-count/data"
headers = {
"Authorization": self.API_TOKEN,
"plant-name": self.selected_plant,
"invoice-name": self.selected_invoice_type,
"filter-name": self.selected_filter
}
try:
response = requests.get(url, headers=headers, timeout=10)
# Show raw API response for debugging
self.chat_area.append(f"📡 Raw API Response:{response.text}")
if response.status_code != 200:
self.chat_area.append(f"Bot: ❌ HTTP Error {response.status_code} fetching invoice count.")
return
data = response.json()
status = data.get("status_code")
if status != "SUCCESS":
error_msg = data.get("status_description", "Unknown error")
self.chat_area.append(f"Bot: ❌ API Error: {error_msg}")
return
labels = data.get("labels", [])
datasets = data.get("datasets", [])
# Show current date/time
now = QDateTime.currentDateTime()
fmt_date = now.toString("dddd, MMMM d, yyyy, h:mm AP")
self.chat_area.append(f"Current date: {fmt_date}{str(e)}")
def fetch_and_display_invoice_quantity(self):
url = "https://pds.iotsignin.com/api/get/module-invoice-quantity/data"
headers = {
"Authorization": self.API_TOKEN,
"plant-name": self.selected_plant,
"invoice-name": self.selected_invoice_type,
"filter-name": self.selected_filter
}
try:
response = requests.get(url, headers=headers, timeout=10)
# Show raw response for debugging
self.chat_area.append(f"📡 Raw API Response:{response.text}")
if response.status_code != 200:
self.chat_area.append(f"Bot: ❌ HTTP Error {response.status_code} fetching invoice quantity.")
return
data = response.json()
if data.get("status_code") != "SUCCESS":
error_msg = data.get("status_description", "Unknown error")
self.chat_area.append(f"Bot: ❌ API Error: {error_msg}")
return
labels = data.get("labels", [])
datasets = data.get("datasets", [])
# Display current date/time in desired format
now = QDateTime.currentDateTime()
fmt_date = now.toString("dddd, MMMM d, yyyy, h:mm AP")
self.chat_area.append(f"Current date: {fmt_date}{str(e)}")
def main():
app = QApplication(sys.argv)
stacked = QStackedWidget()
bot_screen = BotScreen(stacked)
selector_screen = SelectorScreen(stacked, bot_screen)
stacked.addWidget(LoginScreen(stacked))
stacked.addWidget(selector_screen)
stacked.addWidget(bot_screen)
stacked.setFixedSize(420, 640)
stacked.show() ,
sys.exit(app.exec())
if __name__ == '__main__':
main()