KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > pos > device > impl > Receipt


1 /*
2  * $Id: Receipt.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2004 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */

25 package org.ofbiz.pos.device.impl;
26
27 import java.io.BufferedReader JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.InputStreamReader JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.text.SimpleDateFormat JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Map JavaDoc;
36
37 import jpos.JposException;
38 import jpos.POSPrinter;
39 import jpos.POSPrinterConst;
40
41 import org.ofbiz.base.util.Debug;
42 import org.ofbiz.base.util.UtilFormatOut;
43 import org.ofbiz.base.util.UtilURL;
44 import org.ofbiz.base.util.UtilValidate;
45 import org.ofbiz.base.util.string.FlexibleStringExpander;
46 import org.ofbiz.pos.PosTransaction;
47 import org.ofbiz.pos.device.GenericDevice;
48 import org.ofbiz.pos.screen.DialogCallback;
49 import org.ofbiz.pos.screen.PosDialog;
50 import org.ofbiz.pos.screen.PosScreen;
51
52 import org.apache.commons.collections.map.LinkedMap;
53
54 /**
55  *
56  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
57  * @version $Rev: 5462 $
58  * @since 3.2
59  */

60 public class Receipt extends GenericDevice implements DialogCallback {
61
62     public static final String JavaDoc module = Receipt.class.getName();
63
64     protected static final String JavaDoc ESC = ((char) 0x1b) + "";
65     protected static final String JavaDoc LF = ((char) 0x0a) + "";
66
67     protected static final String JavaDoc ALIGN_CENTER = ESC + "|cA";
68     protected static final String JavaDoc ALIGN_RIGHT = ESC + "|rA";
69
70     protected static final String JavaDoc TEXT_DOUBLE_HEIGHT = ESC + "|4C";
71     protected static final String JavaDoc TEXT_UNDERLINE = ESC + "|uC";
72     protected static final String JavaDoc TEXT_BOLD = ESC + "|bC";
73
74     protected static final String JavaDoc PAPER_CUT = ESC + "|100fP";
75
76     protected SimpleDateFormat JavaDoc[] dateFormat = null;
77     protected String JavaDoc[] storeReceiptTmpl = null;
78     protected String JavaDoc[] custReceiptTmpl = null;
79     protected LinkedMap reportTmpl = new LinkedMap();
80
81     protected String JavaDoc[] dateFmtStr = { "EEE, d MMM yyyy HH:mm:ss z", "EEE, d MMM yyyy HH:mm:ss z", "EEE, d MMM yyyy HH:mm:ss z" };
82     protected int[] priceLength = { 7, 7, 7 };
83     protected int[] qtyLength = { 5, 5, 5 };
84     protected int[] descLength = { 25, 25, 0 };
85     protected int[] pridLength = { 25, 25, 0 };
86     protected int[] infoLength = { 34, 34, 0 };
87
88     protected PosTransaction lastTransaction = null;
89
90     public Receipt(String JavaDoc deviceName, int timeout) {
91         super(deviceName, timeout);
92         this.control = new jpos.POSPrinter();
93     }
94
95     protected void initialize() throws JposException {
96         Debug.logInfo("Receipt [" + control.getPhysicalDeviceName() + "] Claimed : " + control.getClaimed(), module);
97         // set map mode to metric - all dimensions specified in 1/100mm units
98
// unit = 1/100 mm - i.e. 1 cm = 10 mm = 10 * 100 units
99
((jpos.POSPrinter) control).setMapMode(POSPrinterConst.PTR_MM_METRIC);
100     }
101
102     public void println() {
103         this.println("");
104     }
105
106     public void println(String JavaDoc p) {
107         try {
108             ((POSPrinter) control).printNormal(POSPrinterConst.PTR_S_RECEIPT, p + LF);
109         } catch (jpos.JposException e) {
110             Debug.logError(e, module);
111         }
112     }
113
114     public void printBarcode(String JavaDoc barcode) {
115         // print the orderId bar code (Code 3 of 9) centered (1cm tall, 6cm wide)
116
try {
117             ((POSPrinter) control).printBarCode(POSPrinterConst.PTR_S_RECEIPT, barcode, POSPrinterConst.PTR_BCS_Code39,
118                     10 * 100, 60 * 100, POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_NONE);
119         } catch (JposException e) {
120             Debug.logError(e, module);
121         }
122     }
123
124     public void printReport(PosTransaction trans, String JavaDoc resource, Map JavaDoc context) {
125         Debug.log("Print Report Requested", module);
126         String JavaDoc[] report = this.readReportTemplate(resource);
127
128         if (report != null) {
129             for (int i = 0; i < report.length; i++) {
130                 if (report[i] != null) {
131                     this.printInfo(report[i], context, trans, 2);
132                 }
133             }
134
135             this.println();
136             this.println();
137             this.println(PAPER_CUT);
138         }
139     }
140
141     public void reprintReceipt() {
142         this.reprintReceipt(false);
143     }
144
145     public void reprintReceipt(boolean reprintStoreCopy) {
146         if (lastTransaction != null) {
147             this.printReceipt(lastTransaction, reprintStoreCopy);
148         }
149     }
150
151     public void printReceipt(PosTransaction trans, boolean printStoreCopy) {
152         Debug.log("Print Receipt Requested : " + trans.getTransactionId(), module);
153         POSPrinter printer = (POSPrinter) control;
154         this.lastTransaction = trans;
155
156         try {
157             if (!checkState(printer)) {
158                 return;
159             }
160         } catch (JposException e) {
161             Debug.logError(e, module);
162         }
163
164         if (printStoreCopy) {
165             String JavaDoc[] storeReceipt = this.readStoreTemplate();
166             int payments = trans.getNumberOfPayments();
167             for (int i = 0; i < payments; i++) {
168                 Map JavaDoc info = trans.getPaymentInfo(i);
169                 if (info.containsKey("cardNumber")) {
170                     this.printReceipt(trans, storeReceipt, 1, info);
171                 }
172                 try {
173                     Thread.sleep(3000);
174                 } catch (Exception JavaDoc e) {
175                 }
176             }
177         }
178
179         // print the customer receipt
180
String JavaDoc[] custReceipt = this.readCustomerTemplate();
181         this.printReceipt(trans, custReceipt, 0, null);
182     }
183
184     private void printReceipt(PosTransaction trans, String JavaDoc[] template, int type, Map JavaDoc payInfo) {
185         if (template != null) {
186             for (int i = 0; i < template.length; i++) {
187                 if (template[i] != null) {
188                     if ("[ORDER_BARCODE]".equals(template[i])) {
189                         this.printBarcode(trans.getOrderId());
190                     } else if (template[i].startsWith("[DLOOP]")) {
191                         this.printDetail(template[i], trans, type);
192                     } else if (template[i].startsWith("[PLOOP]")) {
193                         this.printPayInfo(template[i], trans, type);
194                     } else if (payInfo != null) {
195                         this.printPayInfo(template[i], trans, type, payInfo);
196                     } else {
197                         this.printInfo(template[i], trans, type);
198                     }
199                 }
200             }
201
202             this.println();
203             this.println();
204             this.println(PAPER_CUT);
205         }
206     }
207
208     private synchronized String JavaDoc[] readStoreTemplate() {
209         if (this.storeReceiptTmpl == null) {
210             this.storeReceiptTmpl = new String JavaDoc[7];
211             this.readTemplate(storeReceiptTmpl, "storereceipt.txt", 1);
212         }
213
214         return this.storeReceiptTmpl;
215     }
216
217     private synchronized String JavaDoc[] readCustomerTemplate() {
218         if (this.custReceiptTmpl == null) {
219             this.custReceiptTmpl = new String JavaDoc[7];
220             this.readTemplate(custReceiptTmpl, "custreceipt.txt", 0);
221         }
222
223         return this.custReceiptTmpl;
224     }
225
226     private synchronized String JavaDoc[] readReportTemplate(String JavaDoc resource) {
227         String JavaDoc[] template = (String JavaDoc[]) reportTmpl.get(resource);
228         if (template == null) {
229             template = new String JavaDoc[7];
230             this.readTemplate(template, resource, 2);
231             reportTmpl.put(resource, template);
232         }
233
234         return template;
235     }
236
237     private String JavaDoc[] readTemplate(String JavaDoc[] template, String JavaDoc resource, int type) {
238         int currentPart = 0;
239
240         URL JavaDoc fileUrl = UtilURL.fromResource(resource);
241         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
242
243         try {
244             InputStream JavaDoc in = fileUrl.openStream();
245             BufferedReader JavaDoc dis = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
246
247             String JavaDoc line;
248             while ((line = dis.readLine()) != null) {
249                 if (line.trim().startsWith("#")) {
250                     String JavaDoc[] code = line.trim().split("\\=");
251                     if ("#description.length".equals(code[0])) {
252                         try {
253                             this.descLength[type] = Integer.parseInt(code[1]);
254                         } catch (NumberFormatException JavaDoc e) {
255                             Debug.logWarning(e, module);
256                         }
257                     } else if ("#productId.length".equals(code[0])) {
258                         try {
259                             this.pridLength[type] = Integer.parseInt(code[1]);
260                         } catch (NumberFormatException JavaDoc e) {
261                             Debug.logWarning(e, module);
262                         }
263                     } else if ("#price.length".equals(code[0])) {
264                         try {
265                             this.priceLength[type] = Integer.parseInt(code[1]);
266                         } catch (NumberFormatException JavaDoc e) {
267                             Debug.logWarning(e, module);
268                         }
269                     } else if ("#quantity.length".equals(code[0])) {
270                         try {
271                             this.qtyLength[type] = Integer.parseInt(code[1]);
272                         } catch (NumberFormatException JavaDoc e) {
273                             Debug.logWarning(e, module);
274                         }
275                     } else if ("#infoString.length".equals(code[0])) {
276                         try {
277                             this.infoLength[type] = Integer.parseInt(code[1]);
278                         } catch (NumberFormatException JavaDoc e) {
279                             Debug.logWarning(e, module);
280                         }
281                     } else if ("#dateFormat".equals(code[0])) {
282                         this.dateFmtStr[type] = code[1];
283                     }
284                 } else if (line.trim().startsWith("[BEGIN ITEM LOOP]")) {
285                     template[currentPart++] = buf.toString();
286                     buf = new StringBuffer JavaDoc();
287                     buf.append("[DLOOP]");
288                 } else if (line.trim().startsWith("[END ITEM LOOP]")) {
289                     template[currentPart++] = buf.toString();
290                     buf = new StringBuffer JavaDoc();
291                 } else if (line.trim().startsWith("[BEGIN PAY LOOP]")) {
292                     template[currentPart++] = buf.toString();
293                     buf = new StringBuffer JavaDoc();
294                     buf.append("[PLOOP]");
295                 } else if (line.trim().startsWith("[END PAY LOOP]")) {
296                     template[currentPart++] = buf.toString();
297                     buf = new StringBuffer JavaDoc();
298                 } else if (line.trim().startsWith("[ORDER BARCODE]")) {
299                     template[currentPart++] = buf.toString();
300                     template[currentPart++] = "[ORDER_BARCODE]";
301                     buf = new StringBuffer JavaDoc();
302                 } else {
303                     if (UtilValidate.isEmpty(line)) {
304                         line = " ";
305                     }
306                     buf.append(line + "\n");
307                 }
308             }
309             in.close();
310         } catch (IOException JavaDoc e) {
311             Debug.logError(e, "Unable to open receipt template", module);
312         }
313
314         template[currentPart] = buf.toString();
315         return template;
316     }
317
318     private synchronized SimpleDateFormat JavaDoc getDateFormat(int type) {
319         if (dateFormat == null) {
320             dateFormat = new SimpleDateFormat JavaDoc[3];
321         }
322         if (dateFormat[type] == null) {
323             dateFormat[type] = new SimpleDateFormat JavaDoc(this.dateFmtStr[type]);
324         }
325         return dateFormat[type];
326     }
327
328     private void printInfo(String JavaDoc template, Map JavaDoc context, PosTransaction trans, int type) {
329         Map JavaDoc expandMap = this.makeCodeExpandMap(trans, type);
330         if (context != null) {
331             expandMap.putAll(context); // context overrides
332
}
333         this.printInfo(template, expandMap);
334     }
335
336     private void printInfo(String JavaDoc template, PosTransaction trans, int type) {
337         this.printInfo(template, null, trans, type);
338     }
339
340     private void printInfo(String JavaDoc template, Map JavaDoc context) {
341         String JavaDoc toPrint = FlexibleStringExpander.expandString(template, context);
342         if (toPrint.indexOf("\n") > -1) {
343             String JavaDoc[] lines = toPrint.split("\\n");
344             for (int i = 0; i < lines.length; i++) {
345                 this.println(lines[i]);
346             }
347         } else {
348             this.println(toPrint);
349         }
350     }
351
352     private void printDetail(String JavaDoc loop, PosTransaction trans, int type) {
353         String JavaDoc loopStr = loop.substring(7);
354         int size = trans.size();
355         for (int i = 0; i < size; i++) {
356             Map JavaDoc expandMap = this.makeCodeExpandMap(trans, type);
357             expandMap.putAll(trans.getItemInfo(i));
358             // adjust the padding
359
expandMap.put("description", UtilFormatOut.padString((String JavaDoc) expandMap.get("description"), descLength[type], true, ' '));
360             expandMap.put("productId", UtilFormatOut.padString((String JavaDoc) expandMap.get("productId"), pridLength[type], true, ' '));
361             expandMap.put("basePrice", UtilFormatOut.padString((String JavaDoc) expandMap.get("basePrice"), priceLength[type], false, ' '));
362             expandMap.put("subtotal", UtilFormatOut.padString((String JavaDoc) expandMap.get("subtotal"), priceLength[type], false, ' '));
363             expandMap.put("quantity", UtilFormatOut.padString((String JavaDoc) expandMap.get("quantity"), qtyLength[type], false, ' '));
364             expandMap.put("adjustments", UtilFormatOut.padString((String JavaDoc) expandMap.get("adjustments"), priceLength[type], false, ' '));
365             String JavaDoc toPrint = FlexibleStringExpander.expandString(loopStr, expandMap);
366             if (toPrint.indexOf("\n") > -1) {
367                 String JavaDoc[] lines = toPrint.split("\\n");
368                 for (int x = 0; x < lines.length; x++) {
369                     this.println(lines[x]);
370                 }
371             } else {
372                 this.println(toPrint);
373             }
374         }
375     }
376
377     private void printPayInfo(String JavaDoc loop, PosTransaction trans, int type) {
378         String JavaDoc loopStr = loop.substring(7);
379         int size = trans.getNumberOfPayments();
380         for (int i = 0; i < size; i++) {
381             Map JavaDoc payInfoMap = trans.getPaymentInfo(i);
382             this.printPayInfo(loopStr, trans, type, payInfoMap);
383         }
384     }
385
386     private void printPayInfo(String JavaDoc template, PosTransaction trans, int type, Map JavaDoc payInfo) {
387         Map JavaDoc expandMap = this.makeCodeExpandMap(trans, type);
388         expandMap.putAll(payInfo);
389         // adjust the padding
390
expandMap.put("authInfoString", UtilFormatOut.padString((String JavaDoc) expandMap.get("authInfoString"), infoLength[type], false, ' '));
391         expandMap.put("nameOnCard", UtilFormatOut.padString((String JavaDoc) expandMap.get("nameOnCard"), infoLength[type], false, ' '));
392         expandMap.put("payInfo", UtilFormatOut.padString((String JavaDoc) expandMap.get("payInfo"), infoLength[type], false, ' '));
393         expandMap.put("amount", UtilFormatOut.padString((String JavaDoc) expandMap.get("amount"), priceLength[type], false, ' '));
394         String JavaDoc toPrint = FlexibleStringExpander.expandString(template, expandMap);
395         if (toPrint.indexOf("\n") > -1) {
396             String JavaDoc[] lines = toPrint.split("\\n");
397             for (int x = 0; x < lines.length; x++) {
398                 this.println(lines[x]);
399             }
400         } else {
401             this.println(toPrint);
402         }
403     }
404
405     private Map JavaDoc makeCodeExpandMap(PosTransaction trans, int type) {
406         Map JavaDoc expandMap = new HashMap JavaDoc();
407         SimpleDateFormat JavaDoc fmt = this.getDateFormat(type);
408         String JavaDoc dateString = fmt.format(new Date JavaDoc());
409
410         expandMap.put("DOUBLE_HEIGHT", TEXT_DOUBLE_HEIGHT);
411         expandMap.put("CENTER", ALIGN_CENTER);
412         expandMap.put("BOLD", TEXT_BOLD);
413         expandMap.put("LF", LF);
414         expandMap.put("transactionId", trans.getTransactionId());
415         expandMap.put("terminalId", trans.getTerminalId());
416         expandMap.put("userId", trans.getUserId());
417         expandMap.put("orderId", trans.getOrderId());
418         expandMap.put("dateStamp", dateString);
419         expandMap.put("drawerNo", new Integer JavaDoc(trans.getDrawerNumber()).toString());
420         expandMap.put("taxTotal", UtilFormatOut.padString(UtilFormatOut.formatPrice(trans.getTaxTotal()), priceLength[type], false, ' '));
421         expandMap.put("grandTotal", UtilFormatOut.padString(UtilFormatOut.formatPrice(trans.getGrandTotal()), priceLength[type], false, ' '));
422         expandMap.put("totalPayments", UtilFormatOut.padString(UtilFormatOut.formatPrice(trans.getPaymentTotal()), priceLength[type], false, ' '));
423         expandMap.put("change", UtilFormatOut.padString((trans.getTotalDue() < 0 ?
424                 UtilFormatOut.formatPrice(trans.getTotalDue() * -1) : "0.00"), priceLength[type], false, ' '));
425
426         return expandMap;
427     }
428
429     private boolean checkState(POSPrinter printer) throws JposException {
430         if (printer.getCoverOpen() == true) {
431             // printer is not ready
432
PosScreen.currentScreen.showDialog("main/dialog/error/printernotready", this);
433             return false;
434         }
435
436         return true;
437     }
438
439     public void receiveDialogCb(PosDialog dialog) {
440         PosScreen.currentScreen.refresh();
441         this.reprintReceipt();
442     }
443 }
444
Popular Tags