/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * * This program is free software, you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program, if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package ar.com.ergio.print.fiscal.hasar; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import ar.com.ergio.print.fiscal.AbstractFiscalPacket; import ar.com.ergio.print.fiscal.FiscalPrinterDevice; import ar.com.ergio.print.fiscal.util.ArrayUtils; import ar.com.ergio.print.fiscal.util.ByteFormatter; /** The FiscalPacket implementation used by HasarFiscalDevice and BasicFiscalDevice. */ /** * @author Franco Bonafine * @date 24/01/2008 */ public class HasarFiscalPacket extends AbstractFiscalPacket { private static final long serialVersionUID = 3113281446232338907L; private static final byte FS = 0x1C; private static final byte NL = 0x0D; private final String encoding; private final int baseRolloverYear; private final int baseRolloverCentury; private final int rolloverYear; public HasarFiscalPacket(String encoding, int baseRolloverYear, FiscalPrinterDevice fiscalPrinter) { super(fiscalPrinter); if (baseRolloverYear < 0) { throw new IllegalArgumentException(); } this.encoding = encoding; this.baseRolloverYear = baseRolloverYear; rolloverYear = baseRolloverYear % 100; baseRolloverCentury = baseRolloverYear - rolloverYear; } public String toString() { StringBuffer b = new StringBuffer(); b.append('{'); for (int i = 0, s = getSize(); i < s; i++) { b.append(' '); if (i == 0) { byte[] f = get(i); if (f.length == 1) ByteFormatter.toHex(b, f[0]); else ByteFormatter.toHexString(b, f); } else ByteFormatter.toASCIIString(b, get(i)); } b.append(' ').append('}'); return b.toString(); } /** Get the encoding in use for strings. */ public String getEncoding() { return encoding; } /** Get the base roll-over year in use for dates. Valid years are from baseRolloverYear to baseRolloverYear + 99 inclusive. */ public int getBaseRolloverYear() { return baseRolloverYear; } // String Fields public void setString(int field, String value) { byte[] f; try { f = value.getBytes(encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported encoding (" + encoding + ")"); } set(field, f); } public void setString(int field, String value, int style) { byte[] f; try { f = value.getBytes(encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported encoding (" + encoding + ")"); } if (style != STYLE_NORMAL) { if (style < 0 || style > 15) throw new IllegalArgumentException(); int l = f.length; byte[] x = new byte[l + 1]; x[0] = (byte) (0xF0 | style); System.arraycopy(f, 0, x, 1, l); f = x; } set(field, f); } public String getString(int field) { byte[] f = get(field); try { return f.length == 0 || (f[0] & 0xF0) != 0xF0 ? new String(f, encoding) : new String(f, 1, f.length - 1, encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported encoding (" + encoding + ")"); } } public int getStringStyle(int field) { byte[] f = get(field); return f.length == 0 || (f[0] & 0xF0) != 0xF0 ? STYLE_NORMAL : f[0] & 0xF; } // Date And Time Fields public void setDate(int field, int year, int month, int day) { if (year < baseRolloverYear || year >= baseRolloverYear + 100 || month < 1 || month > 12 || day < 1 || day > 31) throw new IllegalArgumentException(); setString(field, String.valueOf(1000000 + (year % 100) * 10000 + month * 100 + day).substring(1, 7)); } public int getDateYear(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int y = Integer.parseInt(v.substring(0, 2)); if (y < 0) throw new NumberFormatException(); return y + baseRolloverCentury + (y < rolloverYear ? 100 : 0); } public int getDateMonth(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int m = Integer.parseInt(v.substring(2, 4)); if (m < 0) throw new NumberFormatException(); return m; } public int getDateDay(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int d = Integer.parseInt(v.substring(4, 6)); if (d < 0) throw new NumberFormatException(); return d; } public void setTime(int field, int hour, int minute, int second) { if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) throw new IllegalArgumentException(); setString(field, String.valueOf(1000000 + hour * 10000 + minute * 100 + second).substring(1, 7)); } public int getTimeHour(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int h = Integer.parseInt(v.substring(0, 2)); if (h < 0) throw new NumberFormatException(); return h; } public int getTimeMinute(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int m = Integer.parseInt(v.substring(2, 4)); if (m < 0) throw new NumberFormatException(); return m; } public int getTimeSecond(int field) { String v = getString(field); if (v.length() != 6) throw new NumberFormatException(); int s = Integer.parseInt(v.substring(4, 6)); if (s < 0) throw new NumberFormatException(); return s; } // Special Fields public void setCommandCode(int value) { setByte(0, value); } public int getCommandCode() { return getByte(0); } public void setPrinterStatus(int value) { setHex16(1, value); } public int getPrinterStatus() { return getHex16(1); } public void setFiscalStatus(int value) { setHex16(2, value); } public int getFiscalStatus() { return getHex16(2); } public byte[] encodeBytes() { byte[] result = new byte[0]; for (int i = 0, s = getSize(); i < s; i++) { byte[] bytes = get(i); if(bytes.length > 0) result = ArrayUtils.append(result, bytes); if(i != s - 1) result = ArrayUtils.append(result, FS); } result = ArrayUtils.append(result, NL); return result; } public String encodeString() { try { return new String(encodeBytes(), getEncoding()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return ""; } } public void decode(byte[] packetBytes) { ByteArrayOutputStream bstr = new ByteArrayOutputStream(); int f = 0; clear(); bstr.reset(); for(int i = 0; i < packetBytes.length; i++) { int b = packetBytes[i]; if(!(0x00 <= b && b < 0x20)) { bstr.write(b); } if (b == FS || i == (packetBytes.length - 1)) { set(f++, bstr.toByteArray()); bstr.reset(); } } } public void decode(int cmd, byte[] packetBytes) { byte[] cmdBytes = {(byte) cmd, FS}; byte[] newPacketBytes = ArrayUtils.append(cmdBytes,packetBytes); decode(newPacketBytes); } }