Improved error handling, added FontInfo class.

This commit is contained in:
Skylar Grant 2026-01-05 15:11:25 -05:00
parent 7da3b16077
commit 81c8a211f9

View File

@ -1,15 +1,13 @@
/* ITS Thermal Receipt Printer /* ITS Thermal Receipt Printer
* Developed by Skylar Grant for MCCS ITS * Developed by Skylar Grant for MCCS ITS
*/ */
const version = "1.2.3"; const version = "1.2.4";
// ############################################################# // #############################################################
// Variables // Variables
// ############################################################# // #############################################################
const docWidthPts = 204.09; // Documment width in points const docWidthPts = 204.09; // Documment width in points
const docHeightPts = 1000; // Document height in points const docHeightPts = 1000; // Document height in points
const verticalSpacing = 5; // Number of units to move down after each element const verticalSpacing = 5; // Number of units to move down after each element
const standard = 'Helvetica'; // Font name to use for standard text
const monospace = 'Courier'; // Font name to use for monospace text
const logoHeightMm = 32; // Logo height in millimeters const logoHeightMm = 32; // Logo height in millimeters
const logoWidthMm = 70; // Logo width in millimeters const logoWidthMm = 70; // Logo width in millimeters
@ -48,9 +46,9 @@ const strings = {
// Classes // Classes
// ############################################################# // #############################################################
class LineItem { class LineItem {
constructor(text, font, moveDownAfter) { constructor(text, fontInfo, moveDownAfter) {
this.text = text; this.text = text;
this.font = font || standard; this.fontInfo = fontInfo;
this.moveDownAfter = moveDownAfter || false; this.moveDownAfter = moveDownAfter || false;
return this; return this;
@ -64,11 +62,11 @@ class LineItem {
return this; return this;
} }
setFont(font) { setFontInfo(fontInfo) {
if (typeof font !== 'string') { if (!(fontInfo instanceof FontInfo)) {
throw new Error('Font must be a string'); throw new Error('fontInfo must be an instance of FontInfo');
} }
this.font = font; this.fontInfo = fontInfo;
return this; return this;
} }
@ -81,6 +79,45 @@ class LineItem {
} }
} }
class FontInfo {
constructor(name, size, style) {
this.name = name || 'Helvetica';
this.style = style || '';
this.size = size || 12;
return this;
}
setName(name) {
if (typeof name !== 'string') {
throw new Error('Font name must be a string');
}
this.name = name;
return this;
}
setSize(size) {
if (typeof size !== 'number' || size <= 0) {
throw new Error('Font size must be a positive number');
}
this.size = size;
return this;
}
setStyle(style) {
if (typeof style !== 'string') {
throw new Error('Font style must be a string');
}
this.style = style;
return this;
}
}
// #############################################################
// Fonts
// #############################################################
const standard = new FontInfo('Helvetica', 12);
const standardBold = new FontInfo('Helvetica', 12, 'Bold');
const monospace = new FontInfo('Courier', 16, 'Bold');
// ############################################################# // #############################################################
// Functions // Functions
@ -94,6 +131,11 @@ function tempPasswordHandler() {
const username = document.getElementById('tempPwUsername').value; const username = document.getElementById('tempPwUsername').value;
const password = document.getElementById('tempPwPassword').value; const password = document.getElementById('tempPwPassword').value;
if (password.trim() === '') {
alert('Please enter a temporary password.');
return;
}
// Generate the line array and PDF // Generate the line array and PDF
const lineArray = prepTempPassword(password, username); const lineArray = prepTempPassword(password, username);
const bUrl = generateFile(lineArray, true, true); const bUrl = generateFile(lineArray, true, true);
@ -104,6 +146,10 @@ function tempPasswordHandler() {
function customNoteHandler() { function customNoteHandler() {
// Grab the form values // Grab the form values
const customNoteDetails = document.getElementById('customNoteTextArea').value; const customNoteDetails = document.getElementById('customNoteTextArea').value;
if (customNoteDetails.trim() === '') {
alert('Please enter some details for the note.');
return;
}
// Generate the line array and PDF // Generate the line array and PDF
const lineArray = prepCustomDetails(customNoteDetails); const lineArray = prepCustomDetails(customNoteDetails);
@ -116,9 +162,19 @@ function deviceTrackerHandler() {
// Grab the form values // Grab the form values
const dtticket = document.getElementById('dtticket').value; const dtticket = document.getElementById('dtticket').value;
const dtuser = document.getElementById('dtuser').value; const dtuser = document.getElementById('dtuser').value;
const dtservice = document.querySelector('input[name="dtservice"]:checked').value; const dtserviceinput = document.querySelector('input[name="dtservice"]:checked');
if (!dtserviceinput) {
alert('Please select a service type.');
return;
}
const dtservice = dtserviceinput.value;
const dtnotes = document.getElementById('dtnotes').value; const dtnotes = document.getElementById('dtnotes').value;
if (dtticket.trim() === '' || dtuser.trim() === '' || dtservice.trim() === '') {
alert('Please fill out all required fields (Ticket Number, User, Service Type).');
return;
}
// Generate the line array and PDF // Generate the line array and PDF
const lineArray = prepDeviceTracker(dtticket, dtuser, dtservice, dtnotes); const lineArray = prepDeviceTracker(dtticket, dtuser, dtservice, dtnotes);
const bUrl = generateFile(lineArray, true, false); const bUrl = generateFile(lineArray, true, false);
@ -152,7 +208,7 @@ function prepTempPassword(password, username) {
lineArray.push(new LineItem(strings.tempPassword.pwLabel, standard, false)); lineArray.push(new LineItem(strings.tempPassword.pwLabel, standard, false));
lineArray.push(new LineItem(password, monospace, true)); lineArray.push(new LineItem(password, monospace, true));
lineArray.push(new LineItem(strings.tempPassword.pwRequirements, standard, true)); lineArray.push(new LineItem(strings.tempPassword.pwRequirements, standardBold, true));
return lineArray; return lineArray;
}; };
@ -218,15 +274,8 @@ function generateFile(lineArray, header, footer) {
currentPos += logoHeightMm + ( verticalSpacing * 2); currentPos += logoHeightMm + ( verticalSpacing * 2);
for (row of lineArray) { for (row of lineArray) {
// Set the fonts, TODO: this should be cleaned up with new data options in lineArray doc.setFont(row.fontInfo.name, row.fontInfo.style);
if (row.font === monospace) { doc.setFontSize(row.fontInfo.size);
doc.setFont(monospace, 'bold');
doc.setFontSize(16);
}
if (row.font === standard) {
doc.setFontSize(12);
doc.setFont(standard, '');
}
// Split the text only after changing the font info: // Split the text only after changing the font info:
const stringArray = doc.splitTextToSize(row.text, 68); const stringArray = doc.splitTextToSize(row.text, 68);
@ -244,7 +293,7 @@ function generateFile(lineArray, header, footer) {
// Print the footer if needed // Print the footer if needed
if (footer) { if (footer) {
doc.setFontSize(12); doc.setFontSize(12);
doc.setFont(standard, ''); doc.setFont(standard.name, '');
doc.text(strings.global.receiptFooter, 0, currentPos); doc.text(strings.global.receiptFooter, 0, currentPos);
} }
@ -276,11 +325,33 @@ function printPdf() {
// Event Listeners // Event Listeners
// ############################################################# // #############################################################
document.getElementById('tempPasswordBtn').addEventListener('click', tempPasswordHandler); document.getElementById('tempPasswordBtn').addEventListener('click', () => {
document.getElementById('customNoteBtn').addEventListener('click', customNoteHandler); try {
document.getElementById('deviceTrackerBtn').addEventListener('click', deviceTrackerHandler); tempPasswordHandler();
} catch (error) {
alert(`An error occurred while generating the PDF: ${error.message}`);
}
});
document.getElementById('customNoteBtn').addEventListener('click', () => {
try {
customNoteHandler();
} catch (error) {
alert(`An error occurred while generating the PDF: ${error.message}`);
}
});
document.getElementById('deviceTrackerBtn').addEventListener('click', () => {
try {
deviceTrackerHandler();
} catch (error) {
alert(`An error occurred while generating the PDF: ${error.message}`);
}
});
// ############################################################# // #############################################################
// Function Calls // Function Calls
// ############################################################# // #############################################################
try {
setVersionNumber(); setVersionNumber();
} catch (error) {
console.error(`An error occurred during initialization: ${error.message}`);
}