seven365-zyprinter 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/docs.json +9 -0
- package/dist/esm/definitions.d.ts +1 -0
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/Plugin/ZywellSDK.swift +124 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,6 +178,7 @@ getPrinterStatus(options: { identifier: string; }) => Promise<{ status: string;
|
|
|
178
178
|
| ---------------- | ------------------------------------------------------------------------------ |
|
|
179
179
|
| **`header`** | <code>string</code> |
|
|
180
180
|
| **`items`** | <code><a href="#array">Array</a><{ name: string; price: string }></code> |
|
|
181
|
+
| **`kitchen`** | <code><a href="#array">Array</a><any></code> |
|
|
181
182
|
| **`total`** | <code>string</code> |
|
|
182
183
|
| **`footer`** | <code>string</code> |
|
|
183
184
|
| **`formatting`** | <code><a href="#receiptformatting">ReceiptFormatting</a></code> |
|
package/dist/docs.json
CHANGED
|
@@ -230,6 +230,15 @@
|
|
|
230
230
|
],
|
|
231
231
|
"type": "Array<{ name: string; price: string }>"
|
|
232
232
|
},
|
|
233
|
+
{
|
|
234
|
+
"name": "kitchen",
|
|
235
|
+
"tags": [],
|
|
236
|
+
"docs": "",
|
|
237
|
+
"complexTypes": [
|
|
238
|
+
"Array"
|
|
239
|
+
],
|
|
240
|
+
"type": "Array<any>"
|
|
241
|
+
},
|
|
233
242
|
{
|
|
234
243
|
"name": "total",
|
|
235
244
|
"tags": [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["// Enhanced printer interface with connection type details\nexport interface ZyPrinter {\n identifier: string;\n model: string;\n status: string;\n connectionType: 'bluetooth' | 'wifi' | 'usb';\n ipAddress?: string;\n port?: number;\n rssi?: number;\n}\n\nexport interface ReceiptFormatting {\n headerSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n itemSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n itemBold?: boolean;\n totalSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n totalBold?: boolean;\n footerSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n}\n\nexport interface ReceiptTemplate {\n header?: string;\n items?: Array<{ name: string; price: string }>;\n total?: string;\n footer?: string;\n formatting?: ReceiptFormatting;\n}\n\nexport interface ZyprintPlugin {\n echo(options: { value: string }): Promise<{ value: string }>;\n \n // Enhanced Printer Discovery Methods\n discoverPrinters(): Promise<{ printers: ZyPrinter[] }>;\n discoverBluetoothPrinters(): Promise<{ printers: ZyPrinter[] }>;\n discoverWiFiPrinters(options?: { networkRange?: string }): Promise<{ printers: ZyPrinter[] }>;\n \n // Connection Management\n connectToPrinter(options: { identifier: string }): Promise<{ connected: boolean }>;\n disconnectFromPrinter(options: { identifier: string }): Promise<{ disconnected: boolean }>;\n \n // Printing Methods\n printText(options: { text: string; identifier: string }): Promise<{ success: boolean }>;\n printReceipt(options: { template: ReceiptTemplate; identifier: string }): Promise<{ success: boolean }>;\n \n // Printer Status\n getPrinterStatus(options: { identifier: string }): Promise<{ status: string; paperStatus: string; connected: boolean }>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["// Enhanced printer interface with connection type details\nexport interface ZyPrinter {\n identifier: string;\n model: string;\n status: string;\n connectionType: 'bluetooth' | 'wifi' | 'usb';\n ipAddress?: string;\n port?: number;\n rssi?: number;\n}\n\nexport interface ReceiptFormatting {\n headerSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n itemSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n itemBold?: boolean;\n totalSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n totalBold?: boolean;\n footerSize?: 'normal' | 'large' | 'xlarge' | 1 | 2 | 3 | 4;\n}\n\nexport interface ReceiptTemplate {\n header?: string;\n items?: Array<{ name: string; price: string }>;\n kitchen?: Array<any>; // Support for kitchen data payload\n total?: string;\n footer?: string;\n formatting?: ReceiptFormatting;\n}\n\nexport interface ZyprintPlugin {\n echo(options: { value: string }): Promise<{ value: string }>;\n \n // Enhanced Printer Discovery Methods\n discoverPrinters(): Promise<{ printers: ZyPrinter[] }>;\n discoverBluetoothPrinters(): Promise<{ printers: ZyPrinter[] }>;\n discoverWiFiPrinters(options?: { networkRange?: string }): Promise<{ printers: ZyPrinter[] }>;\n \n // Connection Management\n connectToPrinter(options: { identifier: string }): Promise<{ connected: boolean }>;\n disconnectFromPrinter(options: { identifier: string }): Promise<{ disconnected: boolean }>;\n \n // Printing Methods\n printText(options: { text: string; identifier: string }): Promise<{ success: boolean }>;\n printReceipt(options: { template: ReceiptTemplate; identifier: string }): Promise<{ success: boolean }>;\n \n // Printer Status\n getPrinterStatus(options: { identifier: string }): Promise<{ status: string; paperStatus: string; connected: boolean }>;\n}\n"]}
|
|
@@ -252,6 +252,7 @@ import Network
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
@objc public func printReceipt(template: [String: Any], identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
255
|
+
print("ZywellSDK: Received template: \(template)")
|
|
255
256
|
guard let data = formatReceiptForPrinter(template: template) else {
|
|
256
257
|
completion(false, "Failed to format receipt")
|
|
257
258
|
return
|
|
@@ -323,7 +324,7 @@ import Network
|
|
|
323
324
|
printData.append(Data([0x1B, 0x61, 0x01]))
|
|
324
325
|
|
|
325
326
|
// Header
|
|
326
|
-
if let header = template["header"]
|
|
327
|
+
if let header = getString(template["header"]),
|
|
327
328
|
let headerData = (header + "\n\n").data(using: .utf8) {
|
|
328
329
|
|
|
329
330
|
// Get header size from formatting options
|
|
@@ -332,6 +333,7 @@ import Network
|
|
|
332
333
|
let headerSize = formatting["headerSize"] {
|
|
333
334
|
sizeCode = mapHeaderSizeToCode(headerSize)
|
|
334
335
|
}
|
|
336
|
+
print("ZywellSDK: Header size code: \(sizeCode)")
|
|
335
337
|
|
|
336
338
|
// Set font size (GS ! n)
|
|
337
339
|
printData.append(Data([0x1D, 0x21, sizeCode]))
|
|
@@ -346,7 +348,7 @@ import Network
|
|
|
346
348
|
printData.append(Data([0x1B, 0x61, 0x00]))
|
|
347
349
|
|
|
348
350
|
// Items
|
|
349
|
-
if let
|
|
351
|
+
if let kitchen = template["kitchen"] as? [[String: Any]] {
|
|
350
352
|
// Get item formatting
|
|
351
353
|
var itemSizeCode: UInt8 = 0x00
|
|
352
354
|
var itemBold = false
|
|
@@ -354,9 +356,89 @@ import Network
|
|
|
354
356
|
if let itemSize = formatting["itemSize"] {
|
|
355
357
|
itemSizeCode = mapHeaderSizeToCode(itemSize)
|
|
356
358
|
}
|
|
357
|
-
itemBold = formatting["itemBold"]
|
|
359
|
+
itemBold = getBool(formatting["itemBold"])
|
|
358
360
|
}
|
|
359
361
|
|
|
362
|
+
// Apply item formatting
|
|
363
|
+
if itemBold {
|
|
364
|
+
printData.append(Data([0x1B, 0x45, 0x01])) // Bold on
|
|
365
|
+
}
|
|
366
|
+
if itemSizeCode != 0x00 {
|
|
367
|
+
printData.append(Data([0x1D, 0x21, itemSizeCode])) // Set size
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
for item in kitchen {
|
|
371
|
+
var itemName = ""
|
|
372
|
+
var itemPrice = ""
|
|
373
|
+
|
|
374
|
+
// Get name from menu object
|
|
375
|
+
if let menu = item["menu"] as? [String: Any],
|
|
376
|
+
let name = getString(menu["name"]) {
|
|
377
|
+
itemName = name
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Add quantity
|
|
381
|
+
if let qty = item["quantity"] {
|
|
382
|
+
itemName += " x\(getString(qty) ?? "1")"
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Format price
|
|
386
|
+
if let price = item["total_price"] {
|
|
387
|
+
if let priceDouble = Double(getString(price) ?? "0") {
|
|
388
|
+
itemPrice = String(format: "$%.2f", priceDouble)
|
|
389
|
+
} else {
|
|
390
|
+
itemPrice = "$" + (getString(price) ?? "0.00")
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Print main item
|
|
395
|
+
let line = String(format: "%@\t%@\n", itemName, itemPrice)
|
|
396
|
+
if let lineData = line.data(using: .utf8) {
|
|
397
|
+
printData.append(lineData)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Print modifiers
|
|
401
|
+
if let modifiers = item["modifiers"] as? [[String: Any]] {
|
|
402
|
+
for mod in modifiers {
|
|
403
|
+
if let modName = getString(mod["name"]) {
|
|
404
|
+
var modLine = " + \(modName)"
|
|
405
|
+
|
|
406
|
+
// Only show price if > 0
|
|
407
|
+
if let modPrice = mod["price"],
|
|
408
|
+
let priceDouble = Double(getString(modPrice) ?? "0"),
|
|
409
|
+
priceDouble > 0 {
|
|
410
|
+
modLine += String(format: "\t$%.2f", priceDouble)
|
|
411
|
+
}
|
|
412
|
+
modLine += "\n"
|
|
413
|
+
|
|
414
|
+
if let modData = modLine.data(using: .utf8) {
|
|
415
|
+
printData.append(modData)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Reset item formatting
|
|
423
|
+
if itemSizeCode != 0x00 {
|
|
424
|
+
printData.append(Data([0x1D, 0x21, 0x00])) // Normal size
|
|
425
|
+
}
|
|
426
|
+
if itemBold {
|
|
427
|
+
printData.append(Data([0x1B, 0x45, 0x00])) // Bold off
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
} else if let items = template["items"] as? [[String: Any]] {
|
|
431
|
+
// Get item formatting
|
|
432
|
+
var itemSizeCode: UInt8 = 0x00
|
|
433
|
+
var itemBold = false
|
|
434
|
+
if let formatting = template["formatting"] as? [String: Any] {
|
|
435
|
+
if let itemSize = formatting["itemSize"] {
|
|
436
|
+
itemSizeCode = mapHeaderSizeToCode(itemSize)
|
|
437
|
+
}
|
|
438
|
+
itemBold = getBool(formatting["itemBold"])
|
|
439
|
+
}
|
|
440
|
+
print("ZywellSDK: Item bold: \(itemBold)")
|
|
441
|
+
|
|
360
442
|
// Apply item formatting
|
|
361
443
|
if itemBold {
|
|
362
444
|
printData.append(Data([0x1B, 0x45, 0x01])) // Bold on (ESC E 1)
|
|
@@ -366,8 +448,8 @@ import Network
|
|
|
366
448
|
}
|
|
367
449
|
|
|
368
450
|
for item in items {
|
|
369
|
-
if let name = item["name"]
|
|
370
|
-
let price = item["price"]
|
|
451
|
+
if let name = getString(item["name"]),
|
|
452
|
+
let price = getString(item["price"]) {
|
|
371
453
|
let line = String(format: "%@\t%@\n", name, price)
|
|
372
454
|
if let lineData = line.data(using: .utf8) {
|
|
373
455
|
printData.append(lineData)
|
|
@@ -385,7 +467,7 @@ import Network
|
|
|
385
467
|
}
|
|
386
468
|
|
|
387
469
|
// Total
|
|
388
|
-
if let total = template["total"]
|
|
470
|
+
if let total = getString(template["total"]),
|
|
389
471
|
let totalData = ("\nTotal: " + total + "\n").data(using: .utf8) {
|
|
390
472
|
// Get total formatting
|
|
391
473
|
var totalSizeCode: UInt8 = 0x00
|
|
@@ -394,8 +476,10 @@ import Network
|
|
|
394
476
|
if let totalSize = formatting["totalSize"] {
|
|
395
477
|
totalSizeCode = mapHeaderSizeToCode(totalSize)
|
|
396
478
|
}
|
|
397
|
-
totalBold = formatting["totalBold"]
|
|
479
|
+
totalBold = getBool(formatting["totalBold"])
|
|
398
480
|
}
|
|
481
|
+
print("ZywellSDK: Total size code: \(totalSizeCode)")
|
|
482
|
+
print("ZywellSDK: Total bold: \(totalBold)")
|
|
399
483
|
|
|
400
484
|
// Apply total formatting
|
|
401
485
|
if totalBold {
|
|
@@ -417,7 +501,7 @@ import Network
|
|
|
417
501
|
}
|
|
418
502
|
|
|
419
503
|
// Footer
|
|
420
|
-
if let footer = template["footer"]
|
|
504
|
+
if let footer = getString(template["footer"]),
|
|
421
505
|
let footerData = (footer + "\n").data(using: .utf8) {
|
|
422
506
|
// Get footer formatting
|
|
423
507
|
var footerSizeCode: UInt8 = 0x00
|
|
@@ -460,16 +544,44 @@ import Network
|
|
|
460
544
|
default: return 0x00
|
|
461
545
|
}
|
|
462
546
|
} else if let sizeStr = size as? String {
|
|
463
|
-
switch sizeStr {
|
|
464
|
-
case "normal": return 0x00
|
|
465
|
-
case "large": return 0x11
|
|
466
|
-
case "xlarge": return 0x22
|
|
547
|
+
switch sizeStr.lowercased() {
|
|
548
|
+
case "normal", "1": return 0x00
|
|
549
|
+
case "large", "2": return 0x11
|
|
550
|
+
case "xlarge", "3": return 0x22
|
|
551
|
+
case "4": return 0x33
|
|
467
552
|
default: return 0x00
|
|
468
553
|
}
|
|
554
|
+
} else if let sizeNum = size as? NSNumber {
|
|
555
|
+
switch sizeNum.intValue {
|
|
556
|
+
case 1: return 0x00
|
|
557
|
+
case 2: return 0x11
|
|
558
|
+
case 3: return 0x22
|
|
559
|
+
case 4: return 0x33
|
|
560
|
+
default: return 0x00
|
|
561
|
+
}
|
|
469
562
|
}
|
|
470
563
|
return 0x00
|
|
471
564
|
}
|
|
472
565
|
|
|
566
|
+
private func getBool(_ value: Any?) -> Bool {
|
|
567
|
+
guard let value = value else { return false }
|
|
568
|
+
if let boolVal = value as? Bool { return boolVal }
|
|
569
|
+
if let strVal = value as? String {
|
|
570
|
+
return ["true", "yes", "1"].contains(strVal.lowercased())
|
|
571
|
+
}
|
|
572
|
+
if let numVal = value as? NSNumber {
|
|
573
|
+
return numVal.boolValue
|
|
574
|
+
}
|
|
575
|
+
return false
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
private func getString(_ value: Any?) -> String? {
|
|
579
|
+
guard let value = value else { return nil }
|
|
580
|
+
if let strVal = value as? String { return strVal }
|
|
581
|
+
if let numVal = value as? NSNumber { return numVal.stringValue }
|
|
582
|
+
return String(describing: value)
|
|
583
|
+
}
|
|
584
|
+
|
|
473
585
|
// MARK: - Callback Storage
|
|
474
586
|
|
|
475
587
|
private var discoveryCompletion: (([[String: Any]], String?) -> Void)?
|
package/package.json
CHANGED