Noor2623 commited on
Commit
85d34b9
·
1 Parent(s): 64c8542

I change the PDF form

Browse files
frontend/Sajid Invoice.pdf ADDED
Binary file (57.3 kB). View file
 
frontend/_pdf_ref/sajid_invoice_p1.png ADDED
frontend/css/style.css CHANGED
@@ -237,14 +237,88 @@ table.svc-table { width: 100%; border-collapse: collapse; font-size: 0.84rem;
237
  #toast.info { border-left: 4px solid var(--teal); }
238
 
239
  /* ─── PRINT ─── */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  @media print {
241
  body { background: #fff !important; }
242
- .topbar, .action-bar, .btn-del, .add-row-btn, #toast, #page-history { display: none !important; }
243
- #page-invoice { display: block !important; }
244
  .app-body { padding: 0 !important; max-width: none !important; }
245
- .inv-card { box-shadow: none !important; border: 1px solid #ddd; }
246
- .inv-header-band, .svc-table thead tr, .summary-row.net { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
247
- .tbl-input, .tbl-select, .form-control, .received-input { border: none !important; background: transparent !important; }
 
 
248
  }
249
 
250
  /* ─── RESPONSIVE ─── */
@@ -354,4 +428,4 @@ table.svc-table { width: 100%; border-collapse: collapse; font-size: 0.84rem;
354
  max-width: none;
355
  border-radius: 0;
356
  }
357
- }
 
237
  #toast.info { border-left: 4px solid var(--teal); }
238
 
239
  /* ─── PRINT ─── */
240
+ .print-sheet { display: none; max-width: 820px; margin: 0 auto; font-family: 'Nunito', sans-serif; color: #222; }
241
+ .print-sheet, .print-sheet * { box-sizing: border-box; }
242
+ .print-header {
243
+ background: #1e5c78;
244
+ color: #fff;
245
+ padding: 22px 26px;
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: space-between;
249
+ }
250
+ .print-title {
251
+ font-size: 2.1rem;
252
+ font-weight: 800;
253
+ letter-spacing: 0.08em;
254
+ }
255
+ .print-brand { text-align: right; font-size: 0.75rem; line-height: 1.45; }
256
+ .print-brand-name { font-weight: 700; font-size: 0.8rem; margin-bottom: 2px; }
257
+ .print-info {
258
+ padding: 18px 26px 8px;
259
+ display: grid;
260
+ grid-template-columns: 1fr 1fr;
261
+ gap: 24px;
262
+ font-size: 0.76rem;
263
+ }
264
+ .print-info-title { font-weight: 700; margin-bottom: 6px; }
265
+ .print-info-row { display: flex; gap: 8px; margin: 2px 0; }
266
+ .print-info-row .k { width: 120px; font-weight: 600; color: #333; }
267
+ .print-info-row .v { color: #333; }
268
+
269
+ .print-table {
270
+ width: 100%;
271
+ border-collapse: collapse;
272
+ font-size: 0.75rem;
273
+ margin: 6px 0 0;
274
+ }
275
+ .print-table thead th {
276
+ background: #1e5c78;
277
+ color: #fff;
278
+ padding: 6px 8px;
279
+ text-align: left;
280
+ font-weight: 700;
281
+ }
282
+ .print-table thead th.c { text-align: center; }
283
+ .print-table thead th.r { text-align: right; }
284
+ .print-table tbody td {
285
+ padding: 6px 8px;
286
+ border-bottom: 1px solid #d7e1e8;
287
+ }
288
+ .print-table tbody td.c { text-align: center; }
289
+ .print-table tbody td.r { text-align: right; }
290
+
291
+ .print-summary {
292
+ padding: 10px 26px 0;
293
+ display: grid;
294
+ grid-template-columns: 1fr 280px;
295
+ gap: 24px;
296
+ font-size: 0.75rem;
297
+ }
298
+ .print-terms { color: #333; }
299
+ .print-totals { display: grid; gap: 6px; }
300
+ .tot-row { display: flex; justify-content: space-between; }
301
+ .tot-row.total { border-top: 2px solid #7a2a2a; padding-top: 6px; font-weight: 700; }
302
+
303
+ .print-footer {
304
+ margin: 22px 26px 0;
305
+ background: #1e5c78;
306
+ color: #fff;
307
+ text-align: center;
308
+ padding: 10px 12px;
309
+ font-size: 0.75rem;
310
+ font-weight: 600;
311
+ }
312
+
313
  @media print {
314
  body { background: #fff !important; }
315
+ .topbar, .action-bar, .btn-del, .add-row-btn, #toast, #page-history, #page-invoice { display: none !important; }
 
316
  .app-body { padding: 0 !important; max-width: none !important; }
317
+ .print-sheet { display: block; }
318
+ .print-header, .print-table thead th, .print-footer {
319
+ -webkit-print-color-adjust: exact;
320
+ print-color-adjust: exact;
321
+ }
322
  }
323
 
324
  /* ─── RESPONSIVE ─── */
 
428
  max-width: none;
429
  border-radius: 0;
430
  }
431
+ }
frontend/index.html CHANGED
@@ -137,6 +137,63 @@
137
 
138
  <div id="toast"></div>
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  <script src="/js/data.js"></script>
141
  <script src="/js/db.js"></script>
142
  <script src="/js/ui.js"></script>
@@ -144,4 +201,4 @@
144
  <script src="/js/history.js"></script>
145
  <script src="/js/app.js"></script>
146
  </body>
147
- </html>
 
137
 
138
  <div id="toast"></div>
139
 
140
+ <!-- Print-only invoice layout (matches example PDF style) -->
141
+ <div id="print-sheet" class="print-sheet">
142
+ <div class="print-header">
143
+ <div class="print-title">INVOICE</div>
144
+ <div class="print-brand">
145
+ <div class="print-brand-name">SmiloCAD Dental Lab</div>
146
+ <div class="print-brand-line">Al Anayat Plaza, G11 Markaz Islamabad</div>
147
+ <div class="print-brand-line">Phone: </div>
148
+ <div class="print-brand-line">Email: </div>
149
+ </div>
150
+ </div>
151
+
152
+ <div class="print-info">
153
+ <div class="print-info-left">
154
+ <div class="print-info-row"><span class="k">Invoice No.</span> <span class="v" id="print-inv-no">INV-0000</span></div>
155
+ <div class="print-info-row"><span class="k">Date of Issue</span> <span class="v" id="print-inv-date">Enter Date Here</span></div>
156
+ <div class="print-info-row"><span class="k">Due Date</span> <span class="v" id="print-due-date">Enter Due Date Here</span></div>
157
+ </div>
158
+ <div class="print-info-right">
159
+ <div class="print-info-title">Bill To</div>
160
+ <div class="print-info-row"><span class="k">Client Name</span> <span class="v" id="print-client-name">Client Name</span></div>
161
+ <div class="print-info-row"><span class="k">Company Name</span> <span class="v" id="print-company-name">Company Name</span></div>
162
+ <div class="print-info-row"><span class="k">Address</span> <span class="v" id="print-address">Address</span></div>
163
+ <div class="print-info-row"><span class="k">Phone</span> <span class="v" id="print-phone">Phone</span></div>
164
+ <div class="print-info-row"><span class="k">Email</span> <span class="v" id="print-email">Email</span></div>
165
+ </div>
166
+ </div>
167
+
168
+ <table class="print-table">
169
+ <thead>
170
+ <tr>
171
+ <th class="c">Item</th>
172
+ <th>Patient Name</th>
173
+ <th>Shield</th>
174
+ <th>Description</th>
175
+ <th class="c">Unit</th>
176
+ <th class="r">Rate</th>
177
+ <th class="r">Amount</th>
178
+ </tr>
179
+ </thead>
180
+ <tbody id="print-rows"></tbody>
181
+ </table>
182
+
183
+ <div class="print-summary">
184
+ <div class="print-terms">Terms</div>
185
+ <div class="print-totals">
186
+ <div class="tot-row"><span>Subtotal</span><span id="print-subtotal">$0.00</span></div>
187
+ <div class="tot-row"><span>Discount</span><span>$0.00</span></div>
188
+ <div class="tot-row"><span>Tax Rate</span><span>0%</span></div>
189
+ <div class="tot-row"><span>Tax</span><span>$0.00</span></div>
190
+ <div class="tot-row total"><span>Total</span><span id="print-total">$0.00</span></div>
191
+ </div>
192
+ </div>
193
+
194
+ <div class="print-footer">Thank you for your business!</div>
195
+ </div>
196
+
197
  <script src="/js/data.js"></script>
198
  <script src="/js/db.js"></script>
199
  <script src="/js/ui.js"></script>
 
201
  <script src="/js/history.js"></script>
202
  <script src="/js/app.js"></script>
203
  </body>
204
+ </html>
frontend/js/app.js CHANGED
@@ -84,9 +84,65 @@ var App = (function() {
84
  if (confirm("Clear form?")) _resetForm();
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  // Empty stubs to prevent "undefined" errors if UI calls them
88
- function print() { window.print(); }
89
- function downloadPDF() { window.print(); }
90
  function exportExcel() { console.log("Exporting..."); }
91
  function loadEdit(id) { console.log("Loading ID:", id); }
92
 
@@ -116,4 +172,4 @@ var App = (function() {
116
  exportExcel: exportExcel,
117
  loadEdit: loadEdit
118
  };
119
- })();
 
84
  if (confirm("Clear form?")) _resetForm();
85
  }
86
 
87
+ function _fmtMoney(n) {
88
+ return "PKR " + (Number(n) || 0).toLocaleString("en-PK", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
89
+ }
90
+
91
+ function _preparePrint() {
92
+ var invNo = document.getElementById("inv-number")?.value || "INV-0000";
93
+ var invDate = document.getElementById("inv-date")?.value || "";
94
+ var doctor = document.getElementById("doctor-name")?.value || "";
95
+ var clinic = document.getElementById("clinic")?.value || "";
96
+ var patient = document.getElementById("patient")?.value || "";
97
+ var shade = document.getElementById("shade")?.value || "";
98
+
99
+ var invNoEl = document.getElementById("print-inv-no");
100
+ var invDateEl = document.getElementById("print-inv-date");
101
+ if (invNoEl) invNoEl.textContent = invNo === "Auto-Generated" ? "INV-0000" : invNo;
102
+ if (invDateEl) invDateEl.textContent = invDate || "Enter Date Here";
103
+
104
+ var clientEl = document.getElementById("print-client-name");
105
+ var companyEl = document.getElementById("print-company-name");
106
+ if (clientEl) clientEl.textContent = doctor || "Client Name";
107
+ if (companyEl) companyEl.textContent = clinic || "Company Name";
108
+
109
+ var rowsEl = document.getElementById("print-rows");
110
+ if (rowsEl) rowsEl.innerHTML = "";
111
+
112
+ var items = (typeof Rows !== 'undefined') ? Rows.collect() : [];
113
+ var minRows = 8;
114
+ var rowCount = Math.max(items.length, minRows);
115
+
116
+ for (var i = 0; i < rowCount; i++) {
117
+ var item = items[i];
118
+ var desc = item ? item.description : "";
119
+ var qty = item ? item.quantity : "";
120
+ var price = item ? item.price_per_unit : "";
121
+ var total = item ? (item.quantity * item.price_per_unit) : "";
122
+ var rowHtml = [
123
+ '<tr>',
124
+ '<td class="c">', (i + 1), '</td>',
125
+ '<td>', patient || '', '</td>',
126
+ '<td>', shade || '', '</td>',
127
+ '<td>', desc || '', '</td>',
128
+ '<td class="c">', (qty !== "" ? qty : ''), '</td>',
129
+ '<td class="r">', (price !== "" ? _fmtMoney(price) : ''), '</td>',
130
+ '<td class="r">', (total !== "" ? _fmtMoney(total) : ''), '</td>',
131
+ '</tr>'
132
+ ].join("");
133
+ if (rowsEl) rowsEl.insertAdjacentHTML("beforeend", rowHtml);
134
+ }
135
+
136
+ var subtotal = (typeof Rows !== 'undefined') ? Rows.subtotal() : 0;
137
+ var subEl = document.getElementById("print-subtotal");
138
+ var totalEl = document.getElementById("print-total");
139
+ if (subEl) subEl.textContent = _fmtMoney(subtotal);
140
+ if (totalEl) totalEl.textContent = _fmtMoney(subtotal);
141
+ }
142
+
143
  // Empty stubs to prevent "undefined" errors if UI calls them
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
 
 
172
  exportExcel: exportExcel,
173
  loadEdit: loadEdit
174
  };
175
+ })();