Noor2623 commited on
Commit
f9ba6a9
·
1 Parent(s): ecd868b

Updated the load invoice to see the old history of patient

Browse files
api/__pycache__/invoices.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/invoices.cpython-313.pyc and b/api/__pycache__/invoices.cpython-313.pyc differ
 
api/invoices.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import APIRouter, Depends
2
  from sqlalchemy.orm import Session
3
  from datetime import datetime
4
  from typing import Optional, List
@@ -73,18 +73,22 @@ def get_invoice(invoice_id: int, db: Session = Depends(get_db)):
73
  raise HTTPException(status_code=404, detail="Invoice not found")
74
 
75
  return {
 
76
  "invoice_no": invoice.invoice_number,
77
- "doctor": invoice.doctor_name,
78
- "clinic": invoice.clinic_name,
79
- "patient": invoice.patient_name,
80
- "total": invoice.total_amount,
81
  "date": invoice.date,
 
 
 
 
 
 
 
82
  "items": [
83
  {
84
  "description": item.description,
85
  "quantity": item.quantity,
86
- "price": item.price_per_unit,
87
- "subtotal": item.total_price
88
  } for item in invoice.items
89
  ]
90
  }
@@ -97,8 +101,10 @@ def get_all_invoices(db: Session = Depends(get_db)):
97
  "id": inv.id,
98
  "invoice_no": inv.invoice_number,
99
  "doctor_name": inv.doctor_name,
 
100
  "patient_name": inv.patient_name,
101
  "total_amount": inv.total_amount,
 
102
  "date": inv.date
103
  } for inv in invoices]
104
 
@@ -110,4 +116,4 @@ def delete_invoice(invoice_id: int, db: Session = Depends(get_db)):
110
  raise HTTPException(status_code=404, detail="Invoice not found")
111
  db.delete(db_invoice)
112
  db.commit()
113
- return {"message": "Deleted successfully"}
 
1
+ from fastapi import APIRouter, Depends, HTTPException
2
  from sqlalchemy.orm import Session
3
  from datetime import datetime
4
  from typing import Optional, List
 
73
  raise HTTPException(status_code=404, detail="Invoice not found")
74
 
75
  return {
76
+ "id": invoice.id,
77
  "invoice_no": invoice.invoice_number,
 
 
 
 
78
  "date": invoice.date,
79
+ "doctor_name": invoice.doctor_name,
80
+ "clinic_name": invoice.clinic_name,
81
+ "patient_name": invoice.patient_name,
82
+ "shade": invoice.shade,
83
+ "total_amount": invoice.total_amount,
84
+ "received_amount": invoice.received_amount,
85
+ "remaining_balance": invoice.remaining_balance,
86
  "items": [
87
  {
88
  "description": item.description,
89
  "quantity": item.quantity,
90
+ "price_per_unit": item.price_per_unit,
91
+ "total_price": item.total_price
92
  } for item in invoice.items
93
  ]
94
  }
 
101
  "id": inv.id,
102
  "invoice_no": inv.invoice_number,
103
  "doctor_name": inv.doctor_name,
104
+ "clinic_name": inv.clinic_name,
105
  "patient_name": inv.patient_name,
106
  "total_amount": inv.total_amount,
107
+ "received_amount": inv.received_amount,
108
  "date": inv.date
109
  } for inv in invoices]
110
 
 
116
  raise HTTPException(status_code=404, detail="Invoice not found")
117
  db.delete(db_invoice)
118
  db.commit()
119
+ return {"message": "Deleted successfully"}
frontend/js/app.js CHANGED
@@ -144,7 +144,50 @@ var App = (function() {
144
  function print() { _preparePrint(); window.print(); }
145
  function downloadPDF() { _preparePrint(); window.print(); }
146
  function exportExcel() { console.log("Exporting..."); }
147
- function loadEdit(id) { console.log("Loading ID:", id); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
  // ── Boot ──
150
  document.addEventListener("DOMContentLoaded", async function() {
 
144
  function print() { _preparePrint(); window.print(); }
145
  function downloadPDF() { _preparePrint(); window.print(); }
146
  function exportExcel() { console.log("Exporting..."); }
147
+ async function loadEdit(id) {
148
+ try {
149
+ if (!id || isNaN(id)) {
150
+ if (typeof showToast === 'function') showToast("❌ Invalid invoice id", "error");
151
+ return;
152
+ }
153
+ // Give immediate feedback and switch view
154
+ if (typeof showPage === "function") showPage("invoice");
155
+ if (typeof showToast === 'function') showToast("Loading invoice...", "info");
156
+ if (typeof dbGet !== 'function') throw new Error("dbGet function not found. Check db.js");
157
+ const inv = await dbGet(id);
158
+
159
+ _currentId = inv.id || id;
160
+ if (document.getElementById("inv-number")) {
161
+ document.getElementById("inv-number").value = inv.invoice_no || "Auto-Generated";
162
+ }
163
+ if (document.getElementById("inv-date")) {
164
+ const dateStr = inv.date ? String(inv.date).split("T")[0] : "";
165
+ document.getElementById("inv-date").value = dateStr;
166
+ }
167
+
168
+ const doctorEl = document.getElementById("doctor-name");
169
+ const clinicEl = document.getElementById("clinic");
170
+ const patientEl = document.getElementById("patient");
171
+ const shadeEl = document.getElementById("shade");
172
+ const receivedEl = document.getElementById("received-input");
173
+
174
+ if (doctorEl) doctorEl.value = inv.doctor_name || "";
175
+ if (clinicEl) clinicEl.value = inv.clinic_name || "";
176
+ if (patientEl) patientEl.value = inv.patient_name || "";
177
+ if (shadeEl) shadeEl.value = inv.shade || "";
178
+ if (receivedEl) receivedEl.value = (inv.received_amount || 0);
179
+
180
+ if (typeof Rows !== 'undefined' && typeof Rows.load === 'function') {
181
+ Rows.load(inv.items || []);
182
+ }
183
+
184
+ if (typeof updateHeaderBadge === 'function') updateHeaderBadge();
185
+ showPage("invoice");
186
+ } catch (err) {
187
+ console.error("Load Error:", err);
188
+ if (typeof showToast === 'function') showToast("❌ Load failed. Check console.", "error");
189
+ }
190
+ }
191
 
192
  // ── Boot ──
193
  document.addEventListener("DOMContentLoaded", async function() {
frontend/js/db.js CHANGED
@@ -48,6 +48,25 @@ async function dbAll() {
48
  }
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /* Delete one invoice by id from Neon */
52
  async function dbDelete(id) {
53
  try {
@@ -60,4 +79,4 @@ async function dbDelete(id) {
60
  console.error("Delete Error:", error);
61
  throw error;
62
  }
63
- }
 
48
  }
49
  }
50
 
51
+ /* Load one invoice by id from Neon */
52
+ async function dbGet(id) {
53
+ try {
54
+ const response = await fetch(`${API_URL}/${id}`);
55
+ if (!response.ok) {
56
+ let detail = "";
57
+ try {
58
+ const err = await response.json();
59
+ detail = err.detail ? ` (${err.detail})` : "";
60
+ } catch (e) {}
61
+ throw new Error(`Could not fetch invoice${detail}`);
62
+ }
63
+ return await response.json();
64
+ } catch (error) {
65
+ console.error("Fetch One Error:", error);
66
+ throw error;
67
+ }
68
+ }
69
+
70
  /* Delete one invoice by id from Neon */
71
  async function dbDelete(id) {
72
  try {
 
79
  console.error("Delete Error:", error);
80
  throw error;
81
  }
82
+ }
frontend/js/history.js CHANGED
@@ -5,6 +5,7 @@
5
  var History = (function() {
6
 
7
  var _allInvoices = []; // cache of loaded invoices
 
8
 
9
  /* Format PKR */
10
  function _fmt(n) { return fmt(n); }
@@ -29,8 +30,8 @@ var History = (function() {
29
  '<div style="font-size:0.75rem;color:var(--green);text-align:right;margin-top:2px">Rcvd: ' + _fmt(inv.received_amount || 0) + '</div>',
30
  '</div>',
31
  '<div class="hist-actions">',
32
- '<button class="btn-xs btn-xs-blue" onclick="App.loadEdit(' + inv.id + ')">✏️ Load</button>',
33
- '<button class="btn-xs btn-xs-red" onclick="History.deleteInvoice(' + inv.id + ')">🗑️</button>',
34
  '</div>',
35
  '</div>',
36
  ].join("");
@@ -84,6 +85,9 @@ var History = (function() {
84
  function _render(list) {
85
  var container = document.getElementById("hist-list");
86
  var count = document.getElementById("history-count");
 
 
 
87
  count.textContent = list.length + " invoice" + (list.length !== 1 ? "s" : "");
88
 
89
  if (list.length === 0) {
@@ -94,6 +98,27 @@ var History = (function() {
94
  }
95
  }
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  return { load: load, filter: filter, deleteInvoice: deleteInvoice, getById: getById };
98
 
99
- })();
 
5
  var History = (function() {
6
 
7
  var _allInvoices = []; // cache of loaded invoices
8
+ var _boundClicks = false;
9
 
10
  /* Format PKR */
11
  function _fmt(n) { return fmt(n); }
 
30
  '<div style="font-size:0.75rem;color:var(--green);text-align:right;margin-top:2px">Rcvd: ' + _fmt(inv.received_amount || 0) + '</div>',
31
  '</div>',
32
  '<div class="hist-actions">',
33
+ '<button class="btn-xs btn-xs-blue" data-action="load" data-id="' + inv.id + '">✏️ Load</button>',
34
+ '<button class="btn-xs btn-xs-red" data-action="delete" data-id="' + inv.id + '">🗑️</button>',
35
  '</div>',
36
  '</div>',
37
  ].join("");
 
85
  function _render(list) {
86
  var container = document.getElementById("hist-list");
87
  var count = document.getElementById("history-count");
88
+ if (!container || !count) return;
89
+
90
+ _bindClicks();
91
  count.textContent = list.length + " invoice" + (list.length !== 1 ? "s" : "");
92
 
93
  if (list.length === 0) {
 
98
  }
99
  }
100
 
101
+ function _bindClicks() {
102
+ if (_boundClicks) return;
103
+ document.addEventListener("click", function(e) {
104
+ var btn = e.target.closest("button[data-action]");
105
+ if (!btn) return;
106
+ var id = parseInt(btn.getAttribute("data-id"), 10);
107
+ var action = btn.getAttribute("data-action");
108
+ if (action === "load") {
109
+ if (typeof showToast === "function") showToast("Loading invoice...", "info");
110
+ if (typeof App !== "undefined" && typeof App.loadEdit === "function") {
111
+ App.loadEdit(id);
112
+ } else if (typeof showToast === "function") {
113
+ showToast("Load handler missing", "error");
114
+ }
115
+ } else if (action === "delete") {
116
+ deleteInvoice(id);
117
+ }
118
+ });
119
+ _boundClicks = true;
120
+ }
121
+
122
  return { load: load, filter: filter, deleteInvoice: deleteInvoice, getById: getById };
123
 
124
+ })();