From 33ab53f520f8de9b3e31998fee873e6f4dccd6ee Mon Sep 17 00:00:00 2001 From: hugh-unicenta <59798574+hugh-unicenta@users.noreply.github.com> Date: Mon, 20 May 2024 17:03:58 +0100 Subject: [PATCH] 5.3.1 release (#36) * UOCL-265: Spanish translation improvements * UOCL-246: Reprint receipt fix * UOCL-246: Reprint receipt fix * UOCL-246: reprint receipt * UOCL-283: Porting ZATCA QR-code! * UOCL-283: Porting ZATCA QR-code! * UOCL-246: reprint receipt * UOCL-274: Top 10 sales rpt fix * UOCL-274: Top 10 sales rpt fix * 5.3.1 release --- pom.xml | 10 + .../com/unicenta/pos/forms/AppConfig.java | 8 +- .../java/com/unicenta/pos/forms/AppLocal.java | 2 +- .../unicenta/pos/printer/TicketParser.java | 575 +++++++++--------- .../unicenta/pos/reports/PanelReportBean.java | 10 +- .../com/unicenta/pos/sales/JPanelTicket.java | 15 +- .../com/unicenta/pos/ticket/TicketInfo.java | 12 +- .../java/com/unicenta/pos/util/QRCode.java | 75 +++ .../java/com/unicenta/pos/util/QRObject.java | 40 ++ .../unicenta/pos/templates/Printer.Ticket.xml | 2 +- .../com/unicenta/reports/sales_chart_top10.bs | 79 ++- src/main/resources/pos_messages.properties | 2 +- src/main/resources/pos_messages_es.properties | 195 +++--- .../resources/pos_messages_es_MX.properties | 2 +- src/main/resources/pos_messages_nl.properties | 2 +- .../com/unicenta/pos/util/QRCodeTest.java | 73 +++ 16 files changed, 685 insertions(+), 417 deletions(-) create mode 100644 src/main/java/com/unicenta/pos/util/QRCode.java create mode 100644 src/main/java/com/unicenta/pos/util/QRObject.java create mode 100644 src/test/java/com/unicenta/pos/util/QRCodeTest.java diff --git a/pom.xml b/pom.xml index d2bf8db..1522801 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,16 @@ 10.15.2.0 + + com.google.zxing + core + 3.3.0 + + + com.google.zxing + javase + 3.3.0 + org.xerial diff --git a/src/main/java/com/unicenta/pos/forms/AppConfig.java b/src/main/java/com/unicenta/pos/forms/AppConfig.java index 0e7ce61..a101004 100644 --- a/src/main/java/com/unicenta/pos/forms/AppConfig.java +++ b/src/main/java/com/unicenta/pos/forms/AppConfig.java @@ -228,7 +228,7 @@ public class AppConfig implements AppProperties { } - private void refreshProperties() { + private void pullLatestProperties() { try { InputStream in = new FileInputStream(configfile); if (in != null) { @@ -252,9 +252,11 @@ public class AppConfig implements AppProperties { } } - public void saveWithExistingProperties() throws IOException { + public void setLastTicket(String lastTicketNumber, String lastTicketType) throws IOException { - refreshProperties(); + pullLatestProperties(); + properties.setProperty("lastticket.number", lastTicketNumber); + properties.setProperty("lastticket.type", lastTicketType); OutputStream out = new FileOutputStream(configfile); if (out != null) { diff --git a/src/main/java/com/unicenta/pos/forms/AppLocal.java b/src/main/java/com/unicenta/pos/forms/AppLocal.java index ee34dfe..e4b7557 100644 --- a/src/main/java/com/unicenta/pos/forms/AppLocal.java +++ b/src/main/java/com/unicenta/pos/forms/AppLocal.java @@ -30,7 +30,7 @@ public class AppLocal { public static final String APP_NAME = "uniCenta oPOS"; public static final String APP_ID = "unicentaopos"; - public static final String APP_VERSION = "5.3"; + public static final String APP_VERSION = "5.3.1"; private static final LocaleResources m_resources; diff --git a/src/main/java/com/unicenta/pos/printer/TicketParser.java b/src/main/java/com/unicenta/pos/printer/TicketParser.java index b988be9..18a9cce 100644 --- a/src/main/java/com/unicenta/pos/printer/TicketParser.java +++ b/src/main/java/com/unicenta/pos/printer/TicketParser.java @@ -39,6 +39,8 @@ import javax.imageio.ImageIO; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; + +import com.unicenta.pos.util.QRCode; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -49,52 +51,52 @@ import org.xml.sax.helpers.DefaultHandler; * @author JG uniCenta */ public class TicketParser extends DefaultHandler { - + private static SAXParser m_sp = null; - + private DeviceTicket m_printer; private DataLogicSystem m_system; - + private StringBuilder text; - + private String bctype; private String bcposition; private int m_iTextAlign; private int m_iTextLength; private int m_iTextStyle; private int size; - + private StringBuilder m_sVisorLine; private int m_iVisorAnimation; private String m_sVisorLine1; private String m_sVisorLine2; - + private double m_dValue1; private double m_dValue2; private int attribute3; - + private int m_iOutputType; private static final int OUTPUT_NONE = 0; private static final int OUTPUT_DISPLAY = 1; private static final int OUTPUT_TICKET = 2; private static final int OUTPUT_FISCAL = 3; - private DevicePrinter m_oOutputPrinter; + private DevicePrinter m_oOutputPrinter; private DateFormat df= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); private Date today; private String cUser; private String ticketId; private String pickupId; - - + + /** Creates a new instance of TicketParser * @param printer * @param system */ public TicketParser(DeviceTicket printer, DataLogicSystem system) { m_printer = printer; m_system = system; - today = Calendar.getInstance().getTime(); + today = Calendar.getInstance().getTime(); } - + /** * * @param sIn @@ -103,27 +105,27 @@ public class TicketParser extends DefaultHandler { */ public void printTicket(String sIn, TicketInfo ticket) throws TicketPrinterException { // cUser=ticket.getUser().getName(); - cUser=ticket.getName(); - ticketId=Integer.toString(ticket.getTicketId()); + cUser=ticket.getName(); + ticketId=Integer.toString(ticket.getTicketId()); pickupId=Integer.toString(ticket.getPickupId()); - + if (ticket.getTicketId()==0){ ticketId="No Sale"; } if (ticket.getPickupId()==0){ pickupId="No PickupId"; - } + } printTicket(new StringReader(sIn)); - + } - + /** * * @param sIn * @throws TicketPrinterException */ - public void printTicket(String sIn) throws TicketPrinterException { + public void printTicket(String sIn) throws TicketPrinterException { printTicket(new StringReader(sIn)); } @@ -133,15 +135,15 @@ public class TicketParser extends DefaultHandler { * @throws TicketPrinterException */ public void printTicket(Reader in) throws TicketPrinterException { - + try { - + if (m_sp == null) { SAXParserFactory spf = SAXParserFactory.newInstance(); m_sp = spf.newSAXParser(); } m_sp.parse(new InputSource(in), this); - + } catch (ParserConfigurationException ePC) { throw new TicketPrinterException(LocalRes.getIntString("exception.parserconfig") , ePC); } catch (SAXException eSAX) { @@ -149,8 +151,8 @@ public class TicketParser extends DefaultHandler { } catch (IOException eIO) { throw new TicketPrinterException(LocalRes.getIntString("exception.iofile") , eIO); } - } - + } + @Override public void startDocument() throws SAXException { // inicalizo las variables pertinentes @@ -168,293 +170,300 @@ public class TicketParser extends DefaultHandler { @Override public void endDocument() throws SAXException { } - + @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{ + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{ String openDate = df.format(today); Date dNow = new Date(); - + switch (m_iOutputType) { - case OUTPUT_NONE: - switch (qName) { - case "opendrawer": - m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")).openDrawer(); - // Cashdrawer has been activated record the data in the table - try { - m_system.execDrawerOpened( - //new Object[] {df.format(dNow),cUser,ticketId}); - new Object[] {cUser,ticketId}); - } catch (BasicException ex) {} - break; - case "play": - text = new StringBuilder(); - break; - case "ticket": - m_iOutputType = OUTPUT_TICKET; - m_oOutputPrinter = m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")); - m_oOutputPrinter.beginReceipt(); - break; - case "display": - m_iOutputType = OUTPUT_DISPLAY; - String animation = attributes.getValue("animation"); - if ("scroll".equals(animation)) { - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_SCROLL; - } else if ("flyer".equals(animation)) { - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_FLYER; - } else if ("blink".equals(animation)) { - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_BLINK; - } else if ("curtain".equals(animation)) { - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_CURTAIN; - } else { // "none" - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; - } - m_sVisorLine1 = null; - m_sVisorLine2 = null; - m_oOutputPrinter = null; - break; - case "fiscalreceipt": - m_iOutputType = OUTPUT_FISCAL; - m_printer.getFiscalPrinter().beginReceipt(); - break; - case "fiscalzreport": - m_printer.getFiscalPrinter().printZReport(); - break; - case "fiscalxreport": - m_printer.getFiscalPrinter().printXReport(); - break; - } - break; - case OUTPUT_TICKET: - if (null != qName)switch (qName) { - case "logo": - text = new StringBuilder(); - break; - case "image": - text = new StringBuilder(); - break; - case "barcode": - text = new StringBuilder(); - bctype = attributes.getValue("type"); - bcposition = attributes.getValue("position"); - break; - case "line": - m_oOutputPrinter.beginLine(parseInt(attributes.getValue("size"), DevicePrinter.SIZE_0)); - break; - case "text": - text = new StringBuilder(); - m_iTextStyle = ("true".equals(attributes.getValue("bold")) - ? DevicePrinter.STYLE_BOLD : DevicePrinter.STYLE_PLAIN) - | ("true".equals(attributes.getValue("underline")) - ? DevicePrinter.STYLE_UNDERLINE : DevicePrinter.STYLE_PLAIN); - String sAlign = attributes.getValue("align"); - if (null == sAlign) { - m_iTextAlign = DevicePrinter.ALIGN_LEFT; - } else switch (sAlign) { - case "right": - m_iTextAlign = DevicePrinter.ALIGN_RIGHT; - break; - case "center": - m_iTextAlign = DevicePrinter.ALIGN_CENTER; - break; - default: - m_iTextAlign = DevicePrinter.ALIGN_LEFT; - break; - } - m_iTextLength = parseInt(attributes.getValue("length"), 0); - break; - default: - break; - } - break; - case OUTPUT_DISPLAY: - if (null != qName) switch (qName) { - case "line": - // line 1 or 2 of the display - m_sVisorLine = new StringBuilder(); - break; - case "line1": - // linea 1 del visor - m_sVisorLine = new StringBuilder(); - break; - case "line2": - // linea 2 del visor - m_sVisorLine = new StringBuilder(); - break; - case "text": - text = new StringBuilder(); - String sAlign = attributes.getValue("align"); - if (null == sAlign) { - m_iTextAlign = DevicePrinter.ALIGN_LEFT; - } else switch (sAlign) { - case "right": - m_iTextAlign = DevicePrinter.ALIGN_RIGHT; - break; - case "center": - m_iTextAlign = DevicePrinter.ALIGN_CENTER; - break; - default: - m_iTextAlign = DevicePrinter.ALIGN_LEFT; - break; - } - m_iTextLength = parseInt(attributes.getValue("length")); - break; - default: - break; - } - break; - case OUTPUT_FISCAL: - if (null != qName) + case OUTPUT_NONE: switch (qName) { - case "line": - text = new StringBuilder(); - m_dValue1 = parseDouble(attributes.getValue("price")); - m_dValue2 = parseDouble(attributes.getValue("units"), 1.0); - attribute3 = parseInt(attributes.getValue("tax")); - break; - case "message": + case "opendrawer": + m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")).openDrawer(); + // Cashdrawer has been activated record the data in the table + try { + m_system.execDrawerOpened( + //new Object[] {df.format(dNow),cUser,ticketId}); + new Object[] {cUser,ticketId}); + } catch (BasicException ex) {} + break; + case "play": text = new StringBuilder(); break; - case "total": + case "ticket": + m_iOutputType = OUTPUT_TICKET; + m_oOutputPrinter = m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")); + m_oOutputPrinter.beginReceipt(); + break; + case "display": + m_iOutputType = OUTPUT_DISPLAY; + String animation = attributes.getValue("animation"); + if ("scroll".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_SCROLL; + } else if ("flyer".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_FLYER; + } else if ("blink".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_BLINK; + } else if ("curtain".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_CURTAIN; + } else { // "none" + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; + } + m_sVisorLine1 = null; + m_sVisorLine2 = null; + m_oOutputPrinter = null; + break; + case "fiscalreceipt": + m_iOutputType = OUTPUT_FISCAL; + m_printer.getFiscalPrinter().beginReceipt(); + break; + case "fiscalzreport": + m_printer.getFiscalPrinter().printZReport(); + break; + case "fiscalxreport": + m_printer.getFiscalPrinter().printXReport(); + break; + } + break; + case OUTPUT_TICKET: + if (null != qName)switch (qName) { + case "logo": text = new StringBuilder(); - m_dValue1 = parseDouble(attributes.getValue("paid")); + break; + case "image": + text = new StringBuilder(); + break; + case "barcode": + text = new StringBuilder(); + bctype = attributes.getValue("type"); + bcposition = attributes.getValue("position"); + break; + case "qr-code": + text = new StringBuilder(); + break; + case "line": + m_oOutputPrinter.beginLine(parseInt(attributes.getValue("size"), DevicePrinter.SIZE_0)); + break; + case "text": + text = new StringBuilder(); + m_iTextStyle = ("true".equals(attributes.getValue("bold")) + ? DevicePrinter.STYLE_BOLD : DevicePrinter.STYLE_PLAIN) + | ("true".equals(attributes.getValue("underline")) + ? DevicePrinter.STYLE_UNDERLINE : DevicePrinter.STYLE_PLAIN); + String sAlign = attributes.getValue("align"); + if (null == sAlign) { + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + } else switch (sAlign) { + case "right": + m_iTextAlign = DevicePrinter.ALIGN_RIGHT; + break; + case "center": + m_iTextAlign = DevicePrinter.ALIGN_CENTER; + break; + default: + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + break; + } + m_iTextLength = parseInt(attributes.getValue("length"), 0); break; default: break; } - break; + break; + case OUTPUT_DISPLAY: + if (null != qName) switch (qName) { + case "line": + // line 1 or 2 of the display + m_sVisorLine = new StringBuilder(); + break; + case "line1": + // linea 1 del visor + m_sVisorLine = new StringBuilder(); + break; + case "line2": + // linea 2 del visor + m_sVisorLine = new StringBuilder(); + break; + case "text": + text = new StringBuilder(); + String sAlign = attributes.getValue("align"); + if (null == sAlign) { + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + } else switch (sAlign) { + case "right": + m_iTextAlign = DevicePrinter.ALIGN_RIGHT; + break; + case "center": + m_iTextAlign = DevicePrinter.ALIGN_CENTER; + break; + default: + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + break; + } + m_iTextLength = parseInt(attributes.getValue("length")); + break; + default: + break; + } + break; + case OUTPUT_FISCAL: + if (null != qName) + switch (qName) { + case "line": + text = new StringBuilder(); + m_dValue1 = parseDouble(attributes.getValue("price")); + m_dValue2 = parseDouble(attributes.getValue("units"), 1.0); + attribute3 = parseInt(attributes.getValue("tax")); + break; + case "message": + text = new StringBuilder(); + break; + case "total": + text = new StringBuilder(); + m_dValue1 = parseDouble(attributes.getValue("paid")); + break; + default: + break; + } + break; } - } - + } + @Override public void endElement(String uri, String localName, String qName) throws SAXException { switch (m_iOutputType) { - case OUTPUT_NONE: - if ("play".equals(qName)) { - try { - AudioClip oAudio = Applet.newAudioClip(getClass().getClassLoader().getResource(text.toString())); - oAudio.play(); - } catch (Exception fnfe) { - //throw new ResourceNotFoundException( fnfe.getMessage() ); + case OUTPUT_NONE: + if ("play".equals(qName)) { + try { + AudioClip oAudio = Applet.newAudioClip(getClass().getClassLoader().getResource(text.toString())); + oAudio.play(); + } catch (Exception fnfe) { + //throw new ResourceNotFoundException( fnfe.getMessage() ); + } + text = null; } - text = null; - } - break; - -// Added 23.05.13 used by star TSP700 to print stored logo image JDL - case OUTPUT_TICKET: - if ("logo".equals(qName)){ - m_oOutputPrinter.printLogo(); - // } - }else if ("image".equals(qName)){ - try { -// BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(text.toString())); - BufferedImage image = m_system.getResourceAsImage(text.toString()); + break; - if (image == null) { - image = decodeToImage(text.toString()); - } - if (image != null) { - m_oOutputPrinter.printImage(image); - } - - } catch (Exception fnfe) { - //throw new ResourceNotFoundException( fnfe.getMessage() ); +// Added 23.05.13 used by star TSP700 to print stored logo image JDL + case OUTPUT_TICKET: + if ("logo".equals(qName)){ + m_oOutputPrinter.printLogo(); + // } } - text = null; - } else if ("barcode".equals(qName)) { - m_oOutputPrinter.printBarCode(bctype, bcposition, text.toString()); - text = null; - } else if ("text".equals(qName)) { - if (m_iTextLength > 0) { - switch(m_iTextAlign) { - case DevicePrinter.ALIGN_RIGHT: - m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignRight(text.toString(), m_iTextLength)); - break; - case DevicePrinter.ALIGN_CENTER: - m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignCenter(text.toString(), m_iTextLength)); - break; - default: // DevicePrinter.ALIGN_LEFT - m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignLeft(text.toString(), m_iTextLength)); - break; + if ("image".equals(qName)){ + try { +// BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(text.toString())); + BufferedImage image = m_system.getResourceAsImage(text.toString()); + + if (image == null) { + image = decodeToImage(text.toString()); + } + if (image != null) { + m_oOutputPrinter.printImage(image); + } + + } catch (Exception fnfe) { + //throw new ResourceNotFoundException( fnfe.getMessage() ); } - } else { - m_oOutputPrinter.printText(m_iTextStyle, text.toString()); + text = null; + } else if ("qr-code".equals(qName)) { + m_oOutputPrinter.printImage(QRCode.printQRCode(text.toString())); } - text = null; - } else if ("line".equals(qName)) { - m_oOutputPrinter.endLine(); - } else if ("ticket".equals(qName)) { - m_oOutputPrinter.endReceipt(); - m_iOutputType = OUTPUT_NONE; - m_oOutputPrinter = null; - } - break; - case OUTPUT_DISPLAY: - if ("line".equals(qName)) { // line 1 or 2 of the display - if (m_sVisorLine1 == null) { + else if ("barcode".equals(qName)) { + m_oOutputPrinter.printBarCode(bctype, bcposition, text.toString()); + text = null; + } else if ("text".equals(qName)) { + if (m_iTextLength > 0) { + switch(m_iTextAlign) { + case DevicePrinter.ALIGN_RIGHT: + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignRight(text.toString(), m_iTextLength)); + break; + case DevicePrinter.ALIGN_CENTER: + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignCenter(text.toString(), m_iTextLength)); + break; + default: // DevicePrinter.ALIGN_LEFT + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignLeft(text.toString(), m_iTextLength)); + break; + } + } else { + m_oOutputPrinter.printText(m_iTextStyle, text.toString()); + } + text = null; + } else if ("line".equals(qName)) { + m_oOutputPrinter.endLine(); + } else if ("ticket".equals(qName)) { + m_oOutputPrinter.endReceipt(); + m_iOutputType = OUTPUT_NONE; + m_oOutputPrinter = null; + } + break; + case OUTPUT_DISPLAY: + if ("line".equals(qName)) { // line 1 or 2 of the display + if (m_sVisorLine1 == null) { + m_sVisorLine1 = m_sVisorLine.toString(); + } else { + m_sVisorLine2 = m_sVisorLine.toString(); + } + m_sVisorLine = null; + } else if ("line1".equals(qName)) { // linea 1 del visor m_sVisorLine1 = m_sVisorLine.toString(); - } else { + m_sVisorLine = null; + } else if ("line2".equals(qName)) { // linea 2 del visor m_sVisorLine2 = m_sVisorLine.toString(); - } - m_sVisorLine = null; - } else if ("line1".equals(qName)) { // linea 1 del visor - m_sVisorLine1 = m_sVisorLine.toString(); - m_sVisorLine = null; - } else if ("line2".equals(qName)) { // linea 2 del visor - m_sVisorLine2 = m_sVisorLine.toString(); - m_sVisorLine = null; - } else if ("text".equals(qName)) { - if (m_iTextLength > 0) { - switch(m_iTextAlign) { - case DevicePrinter.ALIGN_RIGHT: - m_sVisorLine.append(DeviceTicket.alignRight(text.toString(), m_iTextLength)); - break; - case DevicePrinter.ALIGN_CENTER: - m_sVisorLine.append(DeviceTicket.alignCenter(text.toString(), m_iTextLength)); - break; - default: // DevicePrinter.ALIGN_LEFT - m_sVisorLine.append(DeviceTicket.alignLeft(text.toString(), m_iTextLength)); - break; + m_sVisorLine = null; + } else if ("text".equals(qName)) { + if (m_iTextLength > 0) { + switch(m_iTextAlign) { + case DevicePrinter.ALIGN_RIGHT: + m_sVisorLine.append(DeviceTicket.alignRight(text.toString(), m_iTextLength)); + break; + case DevicePrinter.ALIGN_CENTER: + m_sVisorLine.append(DeviceTicket.alignCenter(text.toString(), m_iTextLength)); + break; + default: // DevicePrinter.ALIGN_LEFT + m_sVisorLine.append(DeviceTicket.alignLeft(text.toString(), m_iTextLength)); + break; + } + } else { + m_sVisorLine.append(text); } - } else { - m_sVisorLine.append(text); + text = null; + } else if ("display".equals(qName)) { + m_printer.getDeviceDisplay().writeVisor(m_iVisorAnimation, m_sVisorLine1, m_sVisorLine2); + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; + m_sVisorLine1 = null; + m_sVisorLine2 = null; + m_iOutputType = OUTPUT_NONE; + m_oOutputPrinter = null; } - text = null; - } else if ("display".equals(qName)) { - m_printer.getDeviceDisplay().writeVisor(m_iVisorAnimation, m_sVisorLine1, m_sVisorLine2); - m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; - m_sVisorLine1 = null; - m_sVisorLine2 = null; - m_iOutputType = OUTPUT_NONE; - m_oOutputPrinter = null; - } - break; - case OUTPUT_FISCAL: - if ("fiscalreceipt".equals(qName)) { - m_printer.getFiscalPrinter().endReceipt(); - m_iOutputType = OUTPUT_NONE; - } else if ("line".equals(qName)) { - m_printer.getFiscalPrinter().printLine(text.toString(), m_dValue1, m_dValue2, attribute3); - text = null; - } else if ("message".equals(qName)) { - m_printer.getFiscalPrinter().printMessage(text.toString()); - text = null; - } else if ("total".equals(qName)) { - m_printer.getFiscalPrinter().printTotal(text.toString(), m_dValue1); - text = null; - } - break; - } + break; + case OUTPUT_FISCAL: + if ("fiscalreceipt".equals(qName)) { + m_printer.getFiscalPrinter().endReceipt(); + m_iOutputType = OUTPUT_NONE; + } else if ("line".equals(qName)) { + m_printer.getFiscalPrinter().printLine(text.toString(), m_dValue1, m_dValue2, attribute3); + text = null; + } else if ("message".equals(qName)) { + m_printer.getFiscalPrinter().printMessage(text.toString()); + text = null; + } else if ("total".equals(qName)) { + m_printer.getFiscalPrinter().printTotal(text.toString(), m_dValue1); + text = null; + } + break; + } } - + @Override public void characters(char[] ch, int start, int length) throws SAXException { if (text != null) { text.append(ch, start, length); } } - + private int parseInt(String sValue, int iDefault) { try { return Integer.parseInt(sValue); @@ -462,11 +471,11 @@ public class TicketParser extends DefaultHandler { return iDefault; } } - + private int parseInt(String sValue) { return parseInt(sValue, 0); } - + private double parseDouble(String sValue, double ddefault) { try { return Double.parseDouble(sValue); @@ -474,11 +483,11 @@ public class TicketParser extends DefaultHandler { return ddefault; } } - + private double parseDouble(String sValue) { return parseDouble(sValue, 0.0); } - + private String readString(String sValue, String sDefault) { if (sValue == null || sValue.equals("")) { return sDefault; @@ -502,5 +511,5 @@ public class TicketParser extends DefaultHandler { return image; - } + } } \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/reports/PanelReportBean.java b/src/main/java/com/unicenta/pos/reports/PanelReportBean.java index c6f6abc..04360f9 100644 --- a/src/main/java/com/unicenta/pos/reports/PanelReportBean.java +++ b/src/main/java/com/unicenta/pos/reports/PanelReportBean.java @@ -22,6 +22,7 @@ package com.unicenta.pos.reports; import com.unicenta.basic.BasicException; import com.unicenta.data.loader.*; import com.unicenta.data.user.EditorCreator; +import com.unicenta.pos.forms.AppConfig; import com.unicenta.pos.forms.AppLocal; import com.unicenta.pos.forms.AppView; import com.unicenta.pos.forms.BeanFactoryException; @@ -197,5 +198,12 @@ public class PanelReportBean extends JPanelReport { */ public void addQBFFilter(ReportEditorCreator qbff) { qbffilter.addEditor(qbff); - } + } + public String getDBType() { + String url = AppConfig.getInstance().getProperty("db.URL"); + if (url.contains("derby")) { + return "derby"; + } + return "mysql"; + } } diff --git a/src/main/java/com/unicenta/pos/sales/JPanelTicket.java b/src/main/java/com/unicenta/pos/sales/JPanelTicket.java index def840d..2f06e10 100644 --- a/src/main/java/com/unicenta/pos/sales/JPanelTicket.java +++ b/src/main/java/com/unicenta/pos/sales/JPanelTicket.java @@ -42,7 +42,6 @@ import com.unicenta.pos.panels.JProductFinder; import com.unicenta.pos.payment.JPaymentSelect; import com.unicenta.pos.payment.JPaymentSelectReceipt; import com.unicenta.pos.payment.JPaymentSelectRefund; -import com.unicenta.pos.printer.DeviceTicket; import com.unicenta.pos.printer.TicketParser; import com.unicenta.pos.printer.TicketPrinterException; import com.unicenta.pos.sales.restaurant.RestaurantDBUtils; @@ -1839,9 +1838,11 @@ public abstract class JPanelTicket extends JPanel implements JPanelView, BeanFac try { dlSales.saveTicket(ticket, m_App.getInventoryLocation()); - m_config.setProperty("lastticket.number", Integer.toString(ticket.getTicketId())); - m_config.setProperty("lastticket.type", Integer.toString(ticket.getTicketType())); - m_config.saveWithExistingProperties(); + String lastTicketNumber = Integer.toString(ticket.getTicketId()); + String lastTicketType = Integer.toString(ticket.getTicketType()); + m_config.setProperty("lastticket.number", lastTicketNumber); + m_config.setProperty("lastticket.type", lastTicketType); + m_config.setLastTicket(lastTicketNumber, lastTicketType); } catch (BasicException eData) { MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.nosaveticket"), eData); @@ -3269,7 +3270,11 @@ public abstract class JPanelTicket extends JPanel implements JPanelView, BeanFac if (listener != null) { listener.stop(); } - Object[] options = {"Create", "Find", "Cancel"}; + Object[] options = { + AppLocal.getIntString("label.create"), + AppLocal.getIntString("label.find"), + AppLocal.getIntString("label.cancel") + }; int n = JOptionPane.showOptionDialog(null, AppLocal.getIntString("message.customeradd"), diff --git a/src/main/java/com/unicenta/pos/ticket/TicketInfo.java b/src/main/java/com/unicenta/pos/ticket/TicketInfo.java index 7f82c28..1c98c86 100644 --- a/src/main/java/com/unicenta/pos/ticket/TicketInfo.java +++ b/src/main/java/com/unicenta/pos/ticket/TicketInfo.java @@ -648,7 +648,17 @@ public final class TicketInfo implements SerializableRead, Externalizable { String row =(m_config.getProperty("tkt."+data)); return row; - } + } + + public String printQRCode(String nameHeader, String vatHeader, String vatLabel){ + String name = getTicketHeaderFooterData(nameHeader); + String vatNumberHeader = getTicketHeaderFooterData(vatHeader); + String vatNumber = vatNumberHeader.split(vatLabel)[1]; + String date = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(getDate()); + String total = String.valueOf(getTotal()); + String vatValue = String.valueOf(getTax()); + return name+","+vatNumber+","+date+","+total+","+vatValue; + } public String printTicketHeaderLine1() { String lineData = getTicketHeaderFooterData("header1"); diff --git a/src/main/java/com/unicenta/pos/util/QRCode.java b/src/main/java/com/unicenta/pos/util/QRCode.java new file mode 100644 index 0000000..a953ce2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/QRCode.java @@ -0,0 +1,75 @@ +package com.unicenta.pos.util; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class QRCode { + + public static BufferedImage printQRCode(String data) { + + String[] values = data.split(","); + + try { + // Name + QRObject name = new QRObject(1, values[0] ); + byte nameTagByte = (byte) name.getTag(); + byte nameLengthByte = (byte) name.getLength(); + byte[] nameBytes = {nameTagByte, nameLengthByte}; + String nameString = new String(nameBytes, StandardCharsets.UTF_8)+name.getValue(); + + //vat number + QRObject vat = new QRObject(2, values[1]); + byte vatTagByte = (byte) vat.getTag(); + byte vatLengthByte = (byte) vat.getLength(); + byte[] vatBytes = {vatTagByte, vatLengthByte}; + String vatString = new String(vatBytes, StandardCharsets.UTF_8)+vat.getValue(); + + // date + QRObject date = new QRObject(3, values[2]); + byte dateTagByte = (byte) date.getTag(); + byte dateLengthByte = (byte) date.getLength(); + byte[] dateBytes = {dateTagByte, dateLengthByte}; + String dateString = new String(dateBytes, StandardCharsets.UTF_8)+date.getValue(); + + // amount + QRObject amount = new QRObject(4, values[3]); + byte amountTagByte = (byte) amount.getTag(); + byte amountLengthByte = (byte) amount.getLength(); + byte[] amountBytes = {amountTagByte, amountLengthByte}; + String amountString = new String(amountBytes, StandardCharsets.UTF_8)+amount.getValue(); + + + // Vat amount + QRObject vatAmount = new QRObject(5, values[4]); + byte vatAmountTag = (byte) vatAmount.getTag(); + byte vatAmountLengthByte = (byte) vatAmount.getLength(); + byte[] vatAmountBytes = {vatAmountTag, vatAmountLengthByte}; + String vatAmountString = new String(vatAmountBytes, StandardCharsets.UTF_8)+vatAmount.getValue(); + + + //barcode + String barCodeString = nameString+vatString+dateString+amountString+vatAmountString; + String encodedBarcode = Base64.getEncoder().encodeToString(barCodeString.getBytes(StandardCharsets.UTF_8)); + + System.out.println(encodedBarcode); + + QRCodeWriter barcodeWriter = new QRCodeWriter(); + BitMatrix bitMatrix = barcodeWriter.encode(encodedBarcode, BarcodeFormat.QR_CODE, 200, 200); + + BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix); + return MatrixToImageWriter.toBufferedImage(bitMatrix); + } catch (WriterException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/com/unicenta/pos/util/QRObject.java b/src/main/java/com/unicenta/pos/util/QRObject.java new file mode 100644 index 0000000..7ebd305 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/QRObject.java @@ -0,0 +1,40 @@ +package com.unicenta.pos.util; + +import java.nio.charset.StandardCharsets; + +public class QRObject { + + private int tag; + private int length; + private String value; + + public QRObject(int tag, String value) { + this.tag = tag; + this.length = setLength(value); + this.value = value; + } + + public int getTag() { + return tag; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int getLength() { + return length; + } + + private static int setLength(String value) { + return value.getBytes(StandardCharsets.UTF_8).length; + } +} diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml index 2c67886..393ec43 100644 --- a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml @@ -254,7 +254,7 @@ #end #end - + #foreach ($paymentline in $ticket.payments) diff --git a/src/main/resources/com/unicenta/reports/sales_chart_top10.bs b/src/main/resources/com/unicenta/reports/sales_chart_top10.bs index 4f299ea..8083fff 100644 --- a/src/main/resources/com/unicenta/reports/sales_chart_top10.bs +++ b/src/main/resources/com/unicenta/reports/sales_chart_top10.bs @@ -24,26 +24,65 @@ report.setTitleKey("Menu.Top10Sales"); report.setReport("/com/unicenta/reports/sales_chart_top10"); report.setResourceBundle("com/unicenta/reports/sales_messages"); -report.setSentence( - "SELECT " + - "products.NAME,SUM(ticketlines.UNITS) AS UNITS, " + - "products.PRICEBUY,products.PRICESELL, " + - "SUM(ticketlines.PRICE * ticketlines.UNITS))AS SUBTOTAL, " + - "SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS TAXES, " + - "SUM(ticketlines.PRICE * ticketlines.UNITS) + SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS GROSSTOTAL " + - "FROM ticketlines " + - "LEFT OUTER JOIN products ON ticketlines.PRODUCT = products.ID " + - "LEFT OUTER JOIN tickets ON tickets.ID = ticketlines.TICKET " + - "LEFT OUTER JOIN receipts ON receipts.ID = tickets.ID, taxes " + - "WHERE receipts.ID = tickets.ID " + - "AND tickets.ID = ticketlines.TICKET " + - "AND ticketlines.PRODUCT = products.ID " + - "AND ticketlines.TAXID = taxes.ID " + - "AND ?(QBF_FILTER) " + - "GROUP BY products.NAME,products.PRICEBUY,products.PRICESELL " + - "ORDER BY GROSSTOTAL DESC " + - "LIMIT 10"); - +String maria = "SELECT \n" + + " products.NAME,\n" + + " SUM(ticketlines.UNITS) AS UNITS, \n" + + " products.PRICEBUY,\n" + + " products.PRICESELL, \n" + + " SUM(ticketlines.PRICE * ticketlines.UNITS) AS SUBTOTAL, \n" + + " SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS TAXES,\n" + + " SUM(ticketlines.PRICE * ticketlines.UNITS) + SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS GROSSTOTAL\n" + + "FROM \n" + + " ticketlines\n" + + " LEFT JOIN products ON ticketlines.PRODUCT = products.ID \n" + + " LEFT JOIN tickets ON tickets.ID = ticketlines.TICKET\n" + + " LEFT JOIN receipts ON receipts.ID = tickets.ID\n" + + " LEFT JOIN taxes ON ticketlines.TAXID = taxes.ID\n" + + "WHERE \n" + + " tickets.ID = ticketlines.TICKET\n" + + " AND ticketlines.PRODUCT = products.ID \n" + + " AND ticketlines.TAXID = taxes.ID\n" + + " AND ?(QBF_FILTER) " + + "GROUP BY \n" + + " products.NAME,\n" + + " products.PRICEBUY,\n" + + " products.PRICESELL\n" + + "ORDER BY \n" + + " GROSSTOTAL DESC \n" + + "LIMIT 10"; + +String derby = "SELECT \n" + + " products.NAME,\n" + + " SUM(ticketlines.UNITS) AS UNITS, \n" + + " products.PRICEBUY,\n" + + " products.PRICESELL, \n" + + " SUM(ticketlines.PRICE * ticketlines.UNITS) AS SUBTOTAL, \n" + + " SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS TAXES,\n" + + " SUM(ticketlines.PRICE * ticketlines.UNITS) + SUM((ticketlines.PRICE * ticketlines.UNITS) * taxes.RATE) AS GROSSTOTAL\n" + + "FROM \n" + + " ticketlines\n" + + " LEFT JOIN products ON ticketlines.PRODUCT = products.ID \n" + + " LEFT JOIN tickets ON tickets.ID = ticketlines.TICKET\n" + + " LEFT JOIN receipts ON receipts.ID = tickets.ID\n" + + " LEFT JOIN taxes ON ticketlines.TAXID = taxes.ID\n" + + "WHERE \n" + + " tickets.ID = ticketlines.TICKET\n" + + " AND ticketlines.PRODUCT = products.ID \n" + + " AND ticketlines.TAXID = taxes.ID\n" + + " AND ?(QBF_FILTER) " + + "GROUP BY \n" + + " products.NAME,\n" + + " products.PRICEBUY,\n" + + " products.PRICESELL\n" + + "ORDER BY \n" + + " GROSSTOTAL DESC \n" + + "FETCH FIRST 10 ROWS ONLY"; + +if (report.getDBType() == "derby") { +report.setSentence(derby); +} else { +report.setSentence(maria); +} report.addParameter("receipts.DATENEW"); report.addParameter("receipts.DATENEW"); diff --git a/src/main/resources/pos_messages.properties b/src/main/resources/pos_messages.properties index 0f9cfa3..c32bde3 100644 --- a/src/main/resources/pos_messages.properties +++ b/src/main/resources/pos_messages.properties @@ -881,7 +881,7 @@ message.email=Desktop email app' not found message.emptycustomer=Customer cannot be empty message.emptynumber=Number cannot be empty message.enterbuyprice=Enter new Buy Price -message.eolupdate=

Version 5.3 Upgrade!


Your current database version is {0}


For version 5.2 click YES

For any other version click NO and get to 5.2 first

+message.eolupdate=

Version 5.3.1 Upgrade!


Your current database version is {0}


For version 5.3 click YES

For any other version click NO and get to 5.3 first

message.ibuttonassign=
Get the iButton ID
Place iButton onto the reader then click OK message.ibuttonnotassign=
The iButton used is not yet assigned to anyone message.ibuttonnotfound=No iButton adapter found. Key fobs will be disabled. diff --git a/src/main/resources/pos_messages_es.properties b/src/main/resources/pos_messages_es.properties index eb82f2d..0ed5280 100644 --- a/src/main/resources/pos_messages_es.properties +++ b/src/main/resources/pos_messages_es.properties @@ -18,7 +18,8 @@ # along with uniCenta oPOS. If not, see . button.backup=Copia seguridad realizada -Button.Cancel=\ +button.Cancel=Cancelar +Button.Cancel=Cancelar button.cancel=Cancelar button.catalogadd=A\u00f1adir al cat\u00e1logo button.catalogdel=Borrar del cat\u00e1logo @@ -27,7 +28,7 @@ button.close=Cerrar Button.Close=Cerrar button.closecash=Cerrar caja button.closecashpreview=Cerrar Vista previa -button.deleteticket=Borar Tiquet +button.deleteticket=Borar tiquet button.discount=Descuento button.edit=Editar button.email=email @@ -44,8 +45,6 @@ button.listtickets=Lista button.memberdiscount=Desc Miembro button.moorings=Moorings button.movetable=Mover -button.newcustomer=Nuevo -Button.newcustomer=Nuevo button.newcustomer=Nuevo Cliente Button.newcustomer=Nuevo cliente button.newticket=Nuevo @@ -87,7 +86,7 @@ button.totaldiscount=Total Desc' button.transfer=Transferancia Base de Datos caption.split=Dividir recibo -caption.tickets=Recibos +caption.tickets=Tiquets caption.upload=Subir lista de productos cboption.clear=Borrar clave existente @@ -119,7 +118,7 @@ filter.imgfile=Imagen (*.jpg,*.png) form.customertitle=Lista de clientes form.productslist=Lista de productos form.selectprintertitle=Seleccionar impresora -form.tickettitle=Lista de recibos +form.tickettitle=Lista de tiquets label.address=Direcci\u00f3n l\u00ednea 1 label.address2=Direcci\u00f3n l\u00ednea 2 @@ -208,7 +207,6 @@ label.curdebt=Deuda actual label.currency=Moneda label.currencybutton=Ocultar Superposici\u00f3n texto Pagos label.currentstock=Disponible -label.currentstock=Esta, existe label.customer=Cliente label.customerdate=Fecha Memorizada label.customerupdated=Clientes actualizados\t @@ -216,8 +214,6 @@ label.custtaxcategory=Categor\u00eda de impuesto por cliente label.cvsinvalid=Productos Inv\u00e1lidos label.cvsnotchanged=Sin Cambios label.Database=Base de datos -Label.Database=Base de datos -Label.Database=Base de datos label.date=Fecha label.datestitle=Fechas de cierre label.datetime=Fecha y hora @@ -266,7 +262,6 @@ label.inputamount=Campo de entrada por encima del teclado label.InputCash=Entregado label.integer=Entero label.invalidcustomers=Clientes no validos -label.invalidcustomers=Clientes no validos label.invlinetotal=Linea total label.IP1=IP 2 label.item=Art\u00edculo @@ -275,7 +270,7 @@ label.javapos.drawer=Nombre del caj\u00f3n label.javapos.printer=Nombre de la impresora label.lastname=Apellidos label.lindediscount=Desc' % -label.linevoids=Boletos vac\u00edos +label.linevoids=L\u00edneas borradas y tiquets vac\u00edos Label.LoadError=Error de Carga label.LoadError=Se ha producido un error al mostrar esta funcionalidad. label.locale=Localizaci\u00f3n @@ -308,10 +303,10 @@ label.maximum=M\u00e1ximo label.merchantcode=C\u00f3digo de comercio label.minimum=M\u00ednimo label.money=Total -label.mooringcreatebtn=Crear Ticket -label.mooringscreatefor=Crear ticket para +label.mooringcreatebtn=Crear Tiquet +label.mooringscreatefor=Crear tiquet para label.name=Nombre -label.nocashsales=Sin Venta-Abrir Caj\u00f3n +label.nocashsales=Aperturas de caj\u00f3n sin venta label.notes=Notas label.noticketstoclose=No hay tiquets por cerrar label.nullcategory=(Sin categor\u00eda) @@ -343,9 +338,8 @@ label.placename=Sitio label.placeposition=Posici\u00f3n label.postal=C\u00f3digo postal label.prepay=Cantidad de prepago -label.prepay=Cantidad Prepago -label.price=PVP -label.pricetax=PVP+IVA +label.price=Base +label.pricetax=Base+IVA label.priceupdate=Actualizaciones de precios label.csvnewcustomers=Nuevos Clientes label.priceupdate=Permitir actualizaciones de precios @@ -369,8 +363,8 @@ label.prodname=Nombre label.prodnamem= Nombre * label.prodorder=Orden label.prodpricebuy=Precio compra -label.prodpricesell=PVP -label.prodpriceselltax=PVP+IVA +label.prodpricesell=Base +label.prodpriceselltax=Base+IVA label.prodproperties=Propiedades label.prodref=Referencia label.prodscale=Balanza @@ -383,13 +377,13 @@ label.prodsupplier=Proveedores label.prodtaxcode=Impuesto label.product=C\u00f3digo de barras label.producthtmlguide=\n

Puedes personalizar la pantalla de venta de Productos aqu\u00ed. \nSi tienes algunos conocimientos de HTML puedes completar lo que aparece aqu\u00ed



\n
Pasa el cursor sobre el texto de la derecha para ver el c\u00f3digo HTML asociado al efecto que quieres en el Bot\u00f3n

\n -label.productreceipt=Se requiere Ticket para la garant\u00eda +label.productreceipt=Se requiere tiquet para la garant\u00eda label.produnits=Unidades label.prodvaluebuy=Valor de compra label.prodvaluesell=Valor de venta label.prodvolume=Volumen label.properties=Propiedades -label.receiptprint=Desactivar Impresi\u00f3n Ticket +label.receiptprint=Desactivar Impresi\u00f3n de tiquet label.receiptprinter=Impresora de recibos label.recorddeleted=(Registro borrado) label.recordeof=(No hay registros) @@ -436,7 +430,7 @@ label.stocktaker=Entrado por label.storename=Nombre de tienda label.StripeLivePublishableKey=Clave publicable en vivo label.subcategorytitle=Nombre en panel -label.subtotalcash=Subtotal +label.subtotalcash=Total sin IVA label.supplierdocment=Documento label.suppliertaxid=La Cuenta label.SupplierTransactions=Actas @@ -453,12 +447,12 @@ label.tableshowwaiterdetails=Mostrar Camarero label.tabletransbutton=Boton de la mesa transparente label.tabletransbutton=Boton de la mesa transparente label.tabletransbutton=Boton de la mesa transparente -label.tax=Impuesto -label.taxcash=Impuestos +label.tax=IVA +label.taxcash=IVA label.taxcategory=Cat. de impuesto -label.taxes=Impuestos +label.taxes=IVA label.taxid=CIF/NIF -label.taxincluded=Impuestos Incluidos al inicio +label.taxincluded=IVA Incluido al inicio label.taxparent=Impuesto padre label.tblProdHeaderCol1=Almac\u00e9n label.tblProdHeaderCol2=cantidad @@ -471,14 +465,14 @@ label.textclourtablename=Color nombre Mesa label.textcolourcustomer=Color texto Cliente label.textcolourwaiter=Color texto Camarero label.texttip=Mensaje texto -label.ticketid=Ticket # +label.ticketid=Tiquet # label.Tickets=Pagos -label.Ticketsbag=Recibos +label.Ticketsbag=Tiquets Label.Ticketsbag=Tiquets label.ticketsetupexample=Ejemplo -label.ticketsetupnumber=Long. m\u00edn N\u00fam Ticket +label.ticketsetupnumber=Long. m\u00edn N\u00fam Tiquet label.ticketsetupprefix=Prefijo N\u00fam. Recibo -label.tickettype=Tipo de boleto +label.tickettype=Tipo de tiquet label.time=Hora label.tktfooter1=Pie de p\u00e1gina 1 label.tktfooter2=Pie de p\u00e1gina 2 @@ -486,7 +480,7 @@ label.tktfooter3=Pie de p\u00e1gina 3 label.tktfooter4=Pie de p\u00e1gina 4 label.tktfooter5=Pie de p\u00e1gina 5 label.tktfooter6=Pie de p\u00e1gina 6 -label.totalcash=Total +label.totalcash=Total PVP label.totaldiscount=Total Desc' label.Transactions=Transacciones label.type=Tipo @@ -496,8 +490,8 @@ label.uploadingproducts=Subiendo productos... Por favor, espere label.URL=URL label.user=Usuario label.ValidFrom=Validez desde -label.value=Importe -label.value2=Precio +label.value=PVP +label.value2=PVP label.variableprice=Precio Variable label.visible=Visible label.voucherValue=Valor @@ -672,9 +666,9 @@ Menu.Taxes=Impuestos Menu.ThirdParties=Proveedores Menu.ThirdPartiesManagement=Gesti\u00f3n de proveedores -Menu.Ticket=Ventas -Menu.TicketEdit=Editar ventas -Menu.TicketRefund=Devoluciones +Menu.Ticket=Vender +Menu.TicketEdit=Buscar tiquets +Menu.TicketRefund=Reembolsos Menu.TimeSeriesProduct=Series de
tiempo Menu.Tools.Resets=Resetear Aplicaciones @@ -687,7 +681,7 @@ Menu.Update= Actulizaci\u00f3n Manual Base de Datos Menu.Tools.UpdatedPrices=Cambio de Precios Menu.Users=Usuarios -Menu.UserNoSales=Boleto vac\u00edo +Menu.UserNoSales=Tiquet vac\u00edo Menu.UserSells=Caja por
vendedor Menu.UsersReport=Usuarios Menu.UserTip=Consejos por usuario @@ -718,7 +712,7 @@ message.cannotloadlists=No se han podido cargar las listas de datos. message.cannotloadreport=No se ha podido cargar la definici\u00f3n del informe. message.cannotloadreportdata=No se han podido cargar los datos del informe. message.cannotloadresourcedata=No se han podido cargar los recursos del informe. -message.cannotloadticket=No se ha podido cargar el recibo. +message.cannotloadticket=No se ha podido cargar el tiquet. message.CannotMove=No se puede mover a otro registro. message.cannotprint=No se puede imprimir el recibo. message.cannotprintline=No se ha podido imprimir la l\u00ednea. @@ -763,17 +757,17 @@ message.nocustomernodebt=Este recibo no est\u00e1 asignado.\nNo puede ser pagado message.nopaymentgateway=Pasarela de pago sin definir. message.noprinters=No hay impresoras instaladas en el sistema. message.noproduct=No existe un producto con el c\u00f3digo introducido -message.nosaveticket=No se ha podido guardar el recibo. +message.nosaveticket=No se ha podido guardar el tiquet. message.noshift=No tienes un turno anterior message.nosupptranx=No hay transacciones para este proveedor message.notactive=Ha sucedido un error al mostrar el panel. -message.notexiststicket=El recibo no existe. -message.noticket=El recibo ya no existe +message.notexiststicket=El tiquet no existe. +message.noticket=El tiquet ya no existe message.notpermissions=No se le permite ejecutar esta tarea message.noupdatescript=Se ha detectado un versi\u00f3n anterior de la base de datos pero no es posible actualizar la base de datos autom\u00e1ticamente. Openbravo POS se cerrar\u00e1 ahora. message.novprice=

Producto de precio variable!


Introducir precio y luego seleccionar producto message.noweight=No se ha podido realizar la pesada -message.nullticket=No puedes crear un ticket vac\u00edo!
Por favor a\u00f1ade alg\u00fan art\u00edculo a esta venta +message.nullticket=No puedes crear un tiquet vac\u00edo!
Por favor a\u00f1ade alg\u00fan art\u00edculo a esta venta message.numericamount = La cantidad debe ser un numero. message.paymentcashneg=Haga la devoluci\u00f3n y pulse Aceptar. message.paymenterror=Error de transaccion de pago! @@ -799,11 +793,11 @@ message.restartchanges=La configuraci\u00f3n se ha guardado correctamente. Los c message.scannerfail=Se ha producido un error al subir la lista de productos. message.scannerfail2=Se ha producido un error al descargar la lista de productos. message.scannerok=Se ha subido con \u00e9xito la lista de productos. -message.sharedticket=

Hay entradas en la pila


Desafortunadamente no puedes verlos. -message.sharedticketlock=El billete esta bloqueado! En uso en otro terminal -message.sharedticketlockoverriden=

Su Vale fue excedido por alguien con permisos de usuario mas altos.
Cualquier cambio que haya hecho en su Vale actual puede ser reemplazado -message.sharedtickets=

Hay entradas en la pila!

Completar o enviar a la papelera -message.sharedtickettitle=Lista de Vales compartidos +message.sharedticket=

Hay tiquets aparcados


Desafortunadamente no puedes verlos. +message.sharedticketlock=El tiquet esta bloqueado! En uso en otro terminal +message.sharedticketlockoverriden=

Su tiquet fue emitido por alguien con permisos de usuario mas altos.
Cualquier cambio que haya hecho en su tiquet actual puede ser reemplazado +message.sharedtickets=

Hay tiquets aparcados!

Completar o enviar a la papelera +message.sharedtickettitle=Lista de tiquets aparcados message.startupText=Cambiar el contenido del texto de inicio predeterminado y no declarar que se trata de un software libre infringe la GNU General Public License de Free Software Foundation GPL. message.supplierinvalid=Proveedor no valido message.systemclosecas=Producto no valido @@ -811,12 +805,12 @@ message.systemclosecash=Mover botones Cerrar Caja message.tableempty=El Vale de esta tabla esta siendo editado por otro usuario
Vuelva luego. message.tableempty=La mesa est\u00e1 ahora vac\u00eda. message.tablefull=La mesa est\u00e1 ahora vac\u00eda. -message.ticketrefunded=Este Vale ya ha sido Reembolsado
Solo se permite un reembolso por Vale -message.ticketrefundedtitle=Cheque de reembolso de Vales +message.ticketrefunded=Este tiquet ya ha sido Reembolsado
Solo se permite un reembolso por tiquet +message.ticketrefundedtitle=Recibo de reembolso de tiquet message.title.checkstock= Control de inventario message.title.nostocklocation=Localizaciones message.title=Mensaje de caja registradora -message.transfer=La transferencia puede tardar mucho tiempo dependiendo del tama\u00c3\u00b1o de su base de datos
Estas seguro de que quieres seguir adelante? +message.transfer=La transferencia puede tardar mucho tiempo dependiendo del tama\u00f1o de su base de datos
Estas seguro de que quieres seguir adelante? message.transfercomplete=La transferencia de datos esta completa
Los datos se indexaran ahora message.transfernotsupported=Tipo de Migraci\u00f3n de Base de Datos no soportada message.transfertitle=Transferencia de base de datos @@ -831,12 +825,12 @@ message.wannasave=\u00bfDesea guardar los cambios antes de salir? messsage.title.supplierinvalid=Proveedor no valido notify.added='Agregado' -notify.customeradd='Cliente a\u00c3\u00b1adido a este ticket' -notify.customerchange='El cliente ha cambiado por este ticket' -notify.customerremove='El cliente ha borrado por este ticket' +notify.customeradd='Cliente a\u00c3\u00b1adido a este tiquet' +notify.customerchange='El cliente se ha cambiado para este tiquet' +notify.customerremove='El cliente se ha eliminado para este tiquet' notify.deleted='Borrado' -notify.printed='Imprimido' -notify.printing='Imprimendo...' +notify.printed='Impreso' +notify.printing='Imprimiendo...' notify.removed='Borrado' notify.saved='Guardado' @@ -855,24 +849,24 @@ rest.label.chairs=Personas rest.label.customer=Cliente rest.label.date=Fecha rest.label.notes=Notas -rest.label.selectcustomer=Selecionar Persona +rest.label.selectcustomer=Selecionar cliente rest.label.showcalendar=Ver/quitar Calendario scale.invalidvalue=La balanza devolvi\u00f3 un valor err\u00f3neo. scale.notdefined=La balanza no est\u00e1 definida. stock.in.movement=(entrada) Traspaso -stock.in.purchase=(entrada) compra -stock.in.refund=(entrada) devoluci\u00f3n -stock.out.break=(salida) rotura -stock.out.crossing=Traspaso -stock.out.free=Gratis -stock.out.movement=(salida) Traspaso -stock.out.refund=Retornar - Suprimir -stock.out.sale=(salida) venta -stock.out.sample=Ejemplo - Salida -stock.out.subtract=Sustraer -stock.out.used=Usado +stock.in.purchase=(entrada) Compra +stock.in.refund=(entrada) Devuelto +stock.out.break=(salida) Rotura +stock.out.crossing=(entrada) Otros motivos +stock.out.free=(salida) Regalo +stock.out.movement=No se usa +stock.out.refund=(salida) Retornado +stock.out.sale=(salida) Venta +stock.out.sample=(salida) Empleados +stock.out.subtract=(salida) Robado +stock.out.used=(salida) Traspaso tab.bank=Banco tab.cash=Caja @@ -884,9 +878,9 @@ tab.debt=A cuenta tab.debt=D\u00e9bito tab.free=Escaso tab.magcard=Tarjeta -tab.paper=Boleto -tab.paper=Slip -tab.slip=Slip +tab.paper=Tiquet +tab.paper=A cuenta +tab.slip=A cuenta tab.ticket=Tiquet tab.voucher=Vale @@ -911,7 +905,7 @@ tkt.tktheader6=Cabezal 6 tooltip.=Reembolsar todo tooltip.addnew=

Adquirir Nuevo -tooltip.addnewticket=

Nuevo Tiquet +tooltip.addnewticket=

Aparcar tiquet tooltip.attributes=

Atributos tooltip.barcodetype=El valor predeterminado es EAN Barcodes. Comprobar para cambiar a codigos de barras de formato UPC tooltip.btn.closecash=

Cerrar efectivo (tambien conocido como lectura Z)
Cerrar transacciones hasta este momento @@ -946,7 +940,7 @@ tooltip.fontsize=peque\u00f1o tooltip.fontsizelarge=

Grande tooltip.fontsizesmall=peque\u00f1o tooltip.fontsizesmall=

Menor -tooltip.layaway=

Entradas a la espera de finalizacion +tooltip.layaway=

Tiquets aparcados tooltip.menu=Ver/Suprimir Menu y todo el programa tooltip.openfile=

Seleccione el archivo necesario para este control\n tooltip.openfile=

Seleccione el archivo necesario para este control\n @@ -955,7 +949,7 @@ tooltip.prepay=Prepago a cuenta tooltip.priceupdate=Permitir actualizaciones de precios en la pantalla Ventas tooltip.printto=

Seleccione esta impresora predeterminada de productos -tooltip.printtoremote=

Imprimir el ticket a la impresora remota +tooltip.printtoremote=

Imprimir el tiquet a la impresora remota tooltip.proddate=Utilice este campo de fecha para algo como la fecha de caducidad de un producto tooltip.prodhtmldisplayBold=

Establezca el texto del boton en Negrita tooltip.prodhtmldisplayBreak=

Inserta un salto de linea y se borra todo
(una nueva linea) para el texto del boton @@ -970,37 +964,37 @@ tooltip.product.button.tab= La pesta\u00f1a Bot\u00f3n permite mejorar el tooltip.product.general.tab=La pesta\u00f1a General contiene la informaci\u00f3n principal de los productos. Los campos que tienen un * (asterisco) DEBEN completarse y no pueden estar vac\u00edos tooltip.quicklogoff=

Salida rapida tooltip.refunditem=

Reembolsar un solo articulo -tooltip.refundline=

Reembolsar una linea de billetes +tooltip.refundline=

Reembolsar una linea de tiquet tooltip.refundticket=

Reembolsar todo -tooltip.reprint=

TIQUET Reimpreso -tooltip.reprintLastTicket=

Imprimir el ultimo Ticket -tooltip.saleattributes=

Elegir atributos del productobr>Para la linea de transaccion actual +tooltip.reprint=

TIQUET REIMPRESO +tooltip.reprintLastTicket=

Imprimir el \u00faltimo tiquet +tooltip.saleattributes=

Elegir atributos del producto
Para la linea de transaccion actual tooltip.salebarcode=

Haga clic para obtener coincidencia de productos
Codigo de barras introducido manualmente tooltip.salechangetax=

Cambiar impuesto para la linea de transaccion actual -tooltip.salecheckstock=

Comprobar existencias para la linea de transaccion actual
Doble toque para obtener mas informacion -tooltip.saleeditline=

Editar el ultimo Tiquet +tooltip.salecheckstock=

Comprobar existencias para la linea de transaccion actual
Doble toque para obtener m\u00e1s informaci\u00f3n +tooltip.saleeditline=

Editar el ultimo tiquet tooltip.saleproductfind=

Buscar por producto -tooltip.saleremoveline=

Borrar el actual tiquet +tooltip.saleremoveline=

Borrar l\u00ednea seleccionada tooltip.salesattributes=

Atributos -tooltip.salescustomer=

Buscar o crear
Tiquet para este cliente -tooltip.salesplit=

Venta de Split +tooltip.salescustomer=

Seleccionar cliente
para este tiquet +tooltip.salesplit=

Repartir venta tooltip.salestaxswitch=

Impuesto para aplicar a
a la linea de transaccion actual -tooltip.salesubtotal=

Total de lineas de billetes sin IVA -tooltip.saletax=

Impuestos totales de lineas de billetes
El impuesto se calcula linea por linea -tooltip.saletotal=

Vale total incluyendo impuestos +tooltip.salesubtotal=

Total de l\u00edneas de tiquets sin IVA +tooltip.saletax=

Impuestos totales de las l\u00edneas de tiquets
El impuesto se calcula l\u00ednea por l\u00ednea +tooltip.saletotal=

Total impuestos incluidos tooltip.save=

Guardar tooltip.scale=

Abrir en pantalla
como Bascula virtual tooltip.supplierdocument=

Introduzca la entrega de un proveedor
Nota o factura tooltip.switchtax=

Impuesto de cambio de un precio introducido manualmente tooltip.ticketedit=

Editar tiquet tooltip.ticketrefund=

Tiquet de reembolso -tooltip.ticketreprint=

Reimprimir Tiquet -tooltip.ticketsearch=

Buscar Tiquets +tooltip.ticketreprint=

Reimprimir tiquet +tooltip.ticketsearch=

Buscar tiquets tooltip.transferdb=

Iniciar la base de datos Proceso de transferencia tooltip.transferdbversion=

La version uniCenta oPOS de la base de datos de transferencias tooltip.transferfromdb=

Seleccione el tipo de base de datos a transferir desde tooltip.transfertxtout=

Lista actualizada dinamicamente de cada proceso cuando sucede
\nEnumera las tablas de la base de datos de transferencia -tooltip.vouchercustomer=

Buscar o Crear nuevo
el Cliente de este tiquet +tooltip.vouchercustomer=

Buscar o Crear nuevo
Cliente para este tiquet tooltip.xmlheader=Utilicelo para insertar el encabezado XML correcto para su uso en los scripts de extension tootltip.transferclass=

Dejar como predeterminado a menos que
Se selecciona una biblioteca de controladores diferente tootltip.transferdbname=

Esta es la URL completa de la
Servidor que aloja la base de datos
\nEl valor predeterminado es localhost. Cambie aqui si su base de datos esta alojada en un servidor remoto @@ -1024,7 +1018,7 @@ transpayment.debtpaid=A cuenta pagados transpayment.free=Sin cargo transpayment.ccard=Tarjeta de credito transpayment.ccardrefund=Devoluci\u00f3n con tarjeta -transpayment.slip=Vales +transpayment.slip=A cuenta transpayment.ticket=Tiquet transpayment.voucher=Vale transpayment.voucherin=Cupon - Redimido @@ -1037,7 +1031,7 @@ label.DbName1=DB 2 Nombre label.DbPort=Port label.DbPort1=Port 2 label.DbURL1=DB 2 URL -label.discount=Reembolso +label.discount=Descuento label.display=Pantalla label.from=De label.ibutton=iButton @@ -1045,7 +1039,7 @@ label.ibuttonresponsespeed=Sensibilidad label.imagesize=Tama\u00f1o de la imagen 250x250 p\u00edxeles o inferior para un mejor rendimiento label.instance=\u00fanica instancia label.invline=Cambiar Precio Comprar -label.invlinestotal=L\u00edneas Total +label.invlinestotal=Total l\u00edneas label.locationplace=Almac\u00e9n label.customer_list=Lista label.customer_export=Lista de exportaci\u00f3n @@ -1064,7 +1058,7 @@ label.prodbarcodetype=Tipo de c\u00f3digo de barras label.prodcategorym=Categor\u00eda * label.proddefaultcategory=Predeterminado Cat' label.prodpricebuym=Precio de compra * -label.prodpriceselltaxm=Precio de venta inc' * +label.prodpriceselltaxm=PVP * label.prodrefm=Referencia * label.prodtax=Impuesto label.rolem=Role * @@ -1116,8 +1110,8 @@ form.usertitle=Lista de usuarios migration.warning=Advertencia label.warranty=Garant\u00eda message.deletelineno=No tienes permitido hacer esto -message.nosharedtickets=No tienes pedidos compartidas en la pila -tooltip.customerpay.prepay=Seleccione un cliente y luego ingrese el importe de pago aqu\u00ed y luego haga clic en bot\u00f3n Prepago +message.nosharedtickets=No hay tiquets aparcados +tooltip.customerpay.prepay=Seleccione un cliente, ingrese el importe de pago aqu\u00ed y luego haga clic en bot\u00f3n Prepago tootltip.save=Guardar label.configOptionRestaurant=Restaurante button.closecashreprint=Reimprimir @@ -1150,13 +1144,13 @@ label.autoRefreshTableMapTimerOFF= La Actualizaci\u00f3n Autom\u00e1tica e label.autoRefreshTableMapTimerON= La Actualizaci\u00f3n Autom\u00e1tica es: ON Menu.Closing1=Caja cerrado
Exportaci\u00f3n Menu.Closing2=Caja cerrado
Exportaci\u00f3n -message.customernotfound= Cliente no encontrado.
\u00bfDesea crear un nuevo registro de cliente? +message.customernotfound= Cliente no encontrado.
\u00bfDesea crear un nuevo cliente? Menu.InventoryBundles=Inventario
Paquetes tooltip.product.properties.tab= La ficha Propiedades se utiliza junto con los scripts de recursos
Se utiliza para agregar m\u00e1s atributos a un producto tooltip.product.stock.tab= La pesta\u00f1a Almac\u00e9n contiene los atributos opcionales Productos message.customercheck=Se requiere una clave de b\u00fasqueda y un nombre. -message.customeradd=\u00bfA\u00f1adir al cliente a este boleto? -message.customerchangeyn=\u00bfEst\u00e1 seguro de que desea cambiar el cliente por el recibo actual? +message.customeradd=\u00bfA\u00f1adir cliente a este tiquet? +message.customerchangeyn=\u00bfEst\u00e1 seguro de que desea cambiar el cliente para el tiquet actual? message.deletelineyes=\u00bfEstas seguro que quieres borrarlo? message.sharedticketlockoverride=\u00bfEst\u00e1s seguro de que quieres Over-ride? message.customerclear=\u00bfEst\u00e1s seguro? Cancelar borrar\u00e1 al Cliente. @@ -1183,11 +1177,14 @@ database.ScriptWarning=Error de script de base de datos exception.unavailabledataset=El conjunto de datos no est\u00e1 disponible message.email=No se ha encontrado la aplicaci\u00f3n de correo electr\u00f3nico de escritorio message.enterbuyprice=Introduzca el nuevo Precio de Compra -tooltip.edit.findticket=Introduzca Recibo y toque para Buscar por n\u00famero +tooltip.edit.findticket=Introduzca n\u00ba de tiquet y valide para Buscar por n\u00famero exception.unavailablefield=Campo no definido: {0} exception.unavailablefields=Campos no disponibles cboption.find=Buscar button.prodhtmldisplayFont=Tipo de fuente button.prodhtmldisplayImage=Imagen label.csvclear=Diario de importaci\u00f3n -message.eolupdate=

uniCenta oPOS Versi\u00f3n {0} detectada!

\u00a1Las actualizaciones de la versi\u00f3n est\u00e1n cambiando!

Si su versi\u00f3n es 5.2 o posterior, elija S\u00cd para continuar.

Para versiones anteriores, haga clic en NO para abrir Opciones de configuraci\u00f3n ahora.

Lea la Gu\u00eda de transferencia de datos de uniCenta oPOS \ No newline at end of file +message.eolupdate=

uniCenta oPOS Versi\u00f3n {0} detectada!

\u00a1Las actualizaciones de la versi\u00f3n est\u00e1n cambiando!

Si su versi\u00f3n es 4.5 o posterior, elija S\u00cd para continuar.

Para versiones anteriores, haga clic en NO para abrir Opciones de configuraci\u00f3n ahora.

Lea la Gu\u00eda de transferencia de datos de uniCenta oPOS +label.find=Buscar +label.create=Crear +label.cancel=Cancelar \ No newline at end of file diff --git a/src/main/resources/pos_messages_es_MX.properties b/src/main/resources/pos_messages_es_MX.properties index 99e9e58..9ccac1c 100644 --- a/src/main/resources/pos_messages_es_MX.properties +++ b/src/main/resources/pos_messages_es_MX.properties @@ -468,4 +468,4 @@ transpayment.ticket=Ticket transpayment.voucherin=Vales cobrados transpayment.voucherout=Vales emitidos Visor.Title=uniCenta oPOS -message.eolupdate=

uniCenta oPOS Versi\u00f3n {0} detectada!

\u00a1Las actualizaciones de la versi\u00f3n est\u00e1n cambiando!

Si su versi\u00f3n es 5.2 o posterior, elija S\u00cd para continuar.

Para versiones anteriores, haga clic en NO para abrir Opciones de configuraci\u00f3n ahora.

Lea la Gu\u00eda de transferencia de datos de uniCenta oPOS \ No newline at end of file +message.eolupdate=

uniCenta oPOS Versi\u00f3n {0} detectada!

\u00a1Las actualizaciones de la versi\u00f3n est\u00e1n cambiando!

Si su versi\u00f3n es 5.3 o posterior, elija S\u00cd para continuar.

Para versiones anteriores, haga clic en NO para abrir Opciones de configuraci\u00f3n ahora.

Lea la Gu\u00eda de transferencia de datos de uniCenta oPOS \ No newline at end of file diff --git a/src/main/resources/pos_messages_nl.properties b/src/main/resources/pos_messages_nl.properties index b0215a2..835b207 100644 --- a/src/main/resources/pos_messages_nl.properties +++ b/src/main/resources/pos_messages_nl.properties @@ -911,7 +911,7 @@ message.transfermessage=Database overdracht message.transfernotsupported=Database overdrachtstype wordt niet ondersteund message.transfertitle=Database overdracht message.updatedatabase=

uniCenta oPOS Version {0} database gedetecteerd!

De database wordt automatisch geüpgraded.
GEGEVENS KUNNEN VERLOREN GAAN. MAAK EERST EEN BACKUP.

Wilt u doorgaan? -message.eolupdate=

uniCenta oPOS Version {0} gedetecteerd!

Versie-upgrades veranderen!

Als je versie 5.2 of hoger is kiesYESom door te gaan

Voor oudere versies kiesNO Om nu de configuratie opties te openen!
Lees alstublieft de uniCenta oPOS Data Transfer Guide

+message.eolupdate=

uniCenta oPOS Version {0} gedetecteerd!

Versie-upgrades veranderen!

Als je versie 5.3 of hoger is kiesYESom door te gaan

Voor oudere versies kiesNO Om nu de configuratie opties te openen!
Lees alstublieft de uniCenta oPOS Data Transfer Guide

message.URL=Een webpagina laten zien in het hoofdscherm . vereist de volledige URL
Voor een lokaal bestand begin met - file://
Voor een extern bestand gebruik http://
message.uuidcopy=

UUID is gekopieerd naar het klembord message.vipno=Klant is geen VIP diff --git a/src/test/java/com/unicenta/pos/util/QRCodeTest.java b/src/test/java/com/unicenta/pos/util/QRCodeTest.java new file mode 100644 index 0000000..f637feb --- /dev/null +++ b/src/test/java/com/unicenta/pos/util/QRCodeTest.java @@ -0,0 +1,73 @@ +package com.unicenta.pos.util; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import org.junit.jupiter.api.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +import static org.junit.jupiter.api.Assertions.*; + +class QRCodeTest { + + @Test + void shouldPrintQRCode() throws Exception { + // Name + QRObject name = new QRObject(1, "Hugh Stevenson"); + byte nameTagByte = (byte) name.getTag(); + byte nameLengthByte = (byte) name.getLength(); + byte[] nameBytes = {nameTagByte, nameLengthByte}; + String nameString = new String(nameBytes, StandardCharsets.UTF_8)+name.getValue(); + + //vat number + QRObject vat = new QRObject(2, "1234567890"); + byte vatTagByte = (byte) vat.getTag(); + byte vatLengthByte = (byte) vat.getLength(); + byte[] vatBytes = {vatTagByte, vatLengthByte}; + String vatString = new String(vatBytes, StandardCharsets.UTF_8)+vat.getValue(); + + // date + QRObject date = new QRObject(3, "2021-11-28 09:30:00"); + byte dateTagByte = (byte) date.getTag(); + byte dateLengthByte = (byte) date.getLength(); + byte[] dateBytes = {dateTagByte, dateLengthByte}; + String dateString = new String(dateBytes, StandardCharsets.UTF_8)+date.getValue(); + + // amount + QRObject amount = new QRObject(4, "1000.00"); + byte amountTagByte = (byte) amount.getTag(); + byte amountLengthByte = (byte) amount.getLength(); + byte[] amountBytes = {amountTagByte, amountLengthByte}; + String amountString = new String(amountBytes, StandardCharsets.UTF_8)+amount.getValue(); + + + // Vat amount + QRObject vatAmount = new QRObject(5, "150.00"); + byte vatAmountTag = (byte) vatAmount.getTag(); + byte vatAmountLengthByte = (byte) vatAmount.getLength(); + byte[] vatAmountBytes = {vatAmountTag, vatAmountLengthByte}; + String vatAmountString = new String(vatAmountBytes, StandardCharsets.UTF_8)+vatAmount.getValue(); + + + //barcode + String barCodeString = nameString+vatString+dateString+amountString+vatAmountString; + String encodedBarcode = Base64.getEncoder().encodeToString(barCodeString.getBytes(StandardCharsets.UTF_8)); + + assert encodedBarcode != null; + + QRCodeWriter barcodeWriter = new QRCodeWriter(); + BitMatrix bitMatrix = barcodeWriter.encode(encodedBarcode, BarcodeFormat.QR_CODE, 200, 200); + + BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix); + + File outputfile = new File(""); + assert ImageIO.write(bufferedImage, "jpg", outputfile); + + } +} \ No newline at end of file