// uniCenta oPOS - Touch Friendly Point Of Sale // Copyright (c) 2009-2018 uniCenta // https://unicenta.com // // This file is part of uniCenta oPOS // // uniCenta oPOS is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // uniCenta oPOS 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 uniCenta oPOS. If not, see . package com.unicenta.pos.ticket; import com.unicenta.basic.BasicException; import com.unicenta.data.loader.DataRead; import com.unicenta.data.loader.LocalRes; import com.unicenta.data.loader.SerializableRead; import com.unicenta.format.Formats; import com.unicenta.pos.customers.CustomerInfoExt; import com.unicenta.pos.forms.AppConfig; import com.unicenta.pos.forms.AppLocal; import com.unicenta.pos.payment.PaymentInfo; import com.unicenta.pos.payment.PaymentInfoMagcard; import com.unicenta.pos.payment.PaymentInfoTicket; import com.unicenta.pos.util.StringUtils; import java.io.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; /** * * @author adrianromero */ public final class TicketInfo implements SerializableRead, Externalizable { private static final long serialVersionUID = 2765650092387265178L; public static final int RECEIPT_NORMAL = 0; public static final int RECEIPT_REFUND = 1; public static final int RECEIPT_PAYMENT = 2; public static final int RECEIPT_NOSALE = 3; // JG Jun 2017 - contain partial/full refunds public static final int REFUND_NOT = 0; // is a non-refunded ticket public static final int REFUND_PARTIAL = 1; public static final int REFUND_ALL = 2; private static final DateFormat m_dateformat = new SimpleDateFormat("hh:mm"); private String host; private String id; private int ticketType; private int ticketId; private int pickupId; private java.util.Date date; private Properties attributes; private UserInfo userInfo; private Double multiply; private CustomerInfoExt cutomerInfoExt; private String activeCash; private List ticketLines; private List payments; private List taxes; private final String m_sResponse; private String loyaltyCardNumber; private Boolean oldTicket; private boolean tip; private PaymentInfoTicket ticketPaymentInfo; private boolean isProcessed; private final String locked; private Double nsum; private int ticketstatus; private static String hostname; public static void setHostname(String name) { hostname = name; } public static String getHostname() { return hostname; } /** Creates new TicketModel */ public TicketInfo() { id = UUID.randomUUID().toString(); ticketType = RECEIPT_NORMAL; ticketId = 0; // incrementamos date = new Date(); attributes = new Properties(); userInfo = null; cutomerInfoExt = null; activeCash = null; ticketLines = new ArrayList<>(); payments = new ArrayList<>(); taxes = null; m_sResponse = null; oldTicket = false; AppConfig config = new AppConfig(new File(new File( System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); config.load(); tip = Boolean.valueOf(config.getProperty("machine.showTip")); isProcessed = false; locked = null; ticketstatus = 0; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(id); out.writeInt(ticketType); out.writeInt(ticketId); out.writeObject(cutomerInfoExt); out.writeObject(date); out.writeObject(attributes); out.writeObject(ticketLines); out.writeInt(ticketstatus); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { id = (String) in.readObject(); ticketType = in.readInt(); ticketId = in.readInt(); cutomerInfoExt = (CustomerInfoExt) in.readObject(); date = (Date) in.readObject(); attributes = (Properties) in.readObject(); ticketLines = (List) in.readObject(); userInfo = null; activeCash = null; payments = new ArrayList<>(); // JG June 2102 diamond inference taxes = null; ticketstatus = in.readInt(); } /** * * @param dr * @throws BasicException */ @Override public void readValues(DataRead dr) throws BasicException { id = dr.getString(1); ticketType = dr.getInt(2); ticketId = dr.getInt(3); date = dr.getTimestamp(4); activeCash = dr.getString(5); try { byte[] img = dr.getBytes(6); if (img != null) { attributes.loadFromXML(new ByteArrayInputStream(img)); } } catch (IOException e) { } userInfo = new UserInfo(dr.getString(7), dr.getString(8)); cutomerInfoExt = new CustomerInfoExt(dr.getString(9)); ticketLines = new ArrayList<>(); payments = new ArrayList<>(); taxes = null; ticketstatus = dr.getInt(10); } /** * * @return */ public TicketInfo copyTicket() { TicketInfo ticketInfo = new TicketInfo(); ticketInfo.ticketType = ticketType; ticketInfo.ticketId = ticketId; ticketInfo.date = date; ticketInfo.activeCash = activeCash; ticketInfo.attributes = (Properties) attributes.clone(); ticketInfo.userInfo = userInfo; ticketInfo.cutomerInfoExt = cutomerInfoExt; ticketInfo.ticketLines = new ArrayList<>(); // JG June 2102 diamond inference ticketLines.forEach((line) -> { ticketInfo.ticketLines.add(line.copyTicketLine()); }); ticketInfo.refreshLines(); ticketInfo.payments = new LinkedList<>(); // JG June 2102 diamond inference payments.forEach((p) -> { ticketInfo.payments.add(p.copyPayment()); }); ticketInfo.oldTicket = oldTicket; // taxes are not copied, must be calculated again. ticketInfo.ticketstatus = ticketstatus; return ticketInfo; } public String getId() { return id; } public int getTicketType() { return ticketType; } public void setTicketType(int tickettype) { this.ticketType = tickettype; } public int getTicketId() { return ticketId; } public void setTicketId(int iTicketId) { ticketId = iTicketId; } public int getTicketStatus() { return ticketstatus; } public void setTicketStatus(int ticketstatus) { if (ticketId > 0) { this.ticketstatus = ticketId; } else { this.ticketstatus = ticketstatus; } } public void setPickupId(int iTicketId) { pickupId = iTicketId; } public int getPickupId() { return pickupId; } public String getName(Object info) { // JG Aug 2014 - Add User info List name = new ArrayList<>(); String nameprop = getProperty("name"); if (nameprop != null) { name.add(nameprop); } if (userInfo != null) { name.add(userInfo.getName()); } if (info == null) { if (ticketId == 0) { name.add("(" + m_dateformat.format(date) + " " + Long.toString(date.getTime() % 1000) + ")"); } else { name.add(Integer.toString(ticketId)); } } else { name.add(info.toString()); } if (cutomerInfoExt != null) { name.add(cutomerInfoExt.getName()); } return org.apache.commons.lang.StringUtils.join(name, " - "); } public String getName() { return getName(null); } public java.util.Date getDate() { return date; } public void setDate(java.util.Date dDate) { date = dDate; } public String getHost() { AppConfig m_config_host = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); m_config_host.load(); String machineHostname = (m_config_host.getProperty("machine.hostname")); m_config_host = null; return machineHostname; } public UserInfo getUserInfo() { return userInfo; } public void setUserInfo(UserInfo value) { userInfo = value; } public CustomerInfoExt getCustomer() { return cutomerInfoExt; } public void setCustomer(CustomerInfoExt value) { cutomerInfoExt = value; } public String getCustomerId() { if (cutomerInfoExt == null) { return null; } else { return cutomerInfoExt.getId(); } } public String getTransactionID() { return (getPayments().size() > 0) ? (getPayments().get(getPayments().size() - 1)).getTransactionID() : StringUtils.getCardNumber(); // random transaction ID } public String getReturnMessage() { return ((getPayments().get(getPayments().size() - 1)) instanceof PaymentInfoMagcard) ? ((PaymentInfoMagcard) (getPayments().get(getPayments().size() - 1))).getReturnMessage() : LocalRes.getIntString("button.OK"); } public void setActiveCash(String value) { activeCash = value; } public String getActiveCash() { return activeCash; } public String getProperty(String key) { return attributes.getProperty(key); } public String getProperty(String key, String defaultvalue) { return attributes.getProperty(key, defaultvalue); } public void setProperty(String key, String value) { attributes.setProperty(key, value); } public Properties getProperties() { return attributes; } public TicketLineInfo getLine(int index) { return ticketLines.get(index); } public void addLine(TicketLineInfo oLine) { oLine.setTicket(id, ticketLines.size()); ticketLines.add(oLine); } public void insertLine(int index, TicketLineInfo oLine) { ticketLines.add(index, oLine); refreshLines(); } public void setLine(int index, TicketLineInfo oLine) { oLine.setTicket(id, index); ticketLines.set(index, oLine); } public void removeLine(int index) { ticketLines.remove(index); refreshLines(); } public void refreshLines() { for (int i = 0; i < ticketLines.size(); i++) { getLine(i).setTicket(id, i); } } public int getLinesCount() { return ticketLines.size(); } public double getArticlesCount() { double dArticles = 0.0; TicketLineInfo oLine; for (Iterator i = ticketLines.iterator(); i.hasNext();) { oLine = i.next(); dArticles += oLine.getMultiply(); } return dArticles; } public double getSubTotal() { double sum = 0.0; sum = ticketLines.stream().map((line) -> line.getSubValue()).reduce(sum, (accumulator, _item) -> accumulator + _item); return sum; } public double getTax() { double sum = 0.0; if (hasTaxesCalculated()) { for (TicketTaxInfo tax : taxes) { sum += tax.getTax(); // Taxes are already rounded... nsum = sum; } } else { sum = ticketLines.stream().map((line) -> line.getTax()).reduce(sum, (accumulator, _item) -> accumulator + _item); } return sum; } public double getTotal() { return getSubTotal() + getTax(); } public double getServiceCharge() { return (getTotal() + getTax()); } public double getTotalPaid() { double sum = 0.0; sum = payments.stream().filter((p) -> (!"debtpaid".equals(p.getName()))).map((p) -> p.getTotal()).reduce(sum, (accumulator, _item) -> accumulator + _item); return sum; } public double getTendered() { return getTotalPaid(); } public List getLines() { return ticketLines; } public void setLines(List l) { ticketLines = l; } public List getPayments() { return payments; } public void setPayments(List l) { payments = l; } public void resetPayments() { payments = new ArrayList<>(); // JG June 2102 diamond inference } public List getTaxes() { return taxes; } public boolean hasTaxesCalculated() { return taxes != null; } public void setTaxes(List l) { taxes = l; } public void resetTaxes() { taxes = null; } public void setTip(boolean tips) { tip = tips; } public boolean hasTip() { return tip; } public void setIsProcessed(boolean isP) { isProcessed = isP; } public TicketTaxInfo getTaxLine(TaxInfo tax) { for (TicketTaxInfo taxline : taxes) { if (tax.getId().equals(taxline.getTaxInfo().getId())) { return taxline; } } return new TicketTaxInfo(tax); } public TicketTaxInfo[] getTaxLines() { Map m = new HashMap<>(); TicketLineInfo oLine; for (Iterator i = ticketLines.iterator(); i.hasNext();) { oLine = i.next(); TicketTaxInfo t = m.get(oLine.getTaxInfo().getId()); if (t == null) { t = new TicketTaxInfo(oLine.getTaxInfo()); m.put(t.getTaxInfo().getId(), t); } t.add(oLine.getSubValue()); } // return dSuma; Collection avalues = m.values(); return avalues.toArray(new TicketTaxInfo[avalues.size()]); } public String printId() { AppConfig m_config = new AppConfig(new File( (System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); m_config.load(); String receiptSize = (m_config.getProperty("till.receiptsize")); String receiptPrefix = (m_config.getProperty("till.receiptprefix")); m_config = null; if (ticketId > 0) { String tmpTicketId = Integer.toString(ticketId); if (receiptSize == null || (Integer.parseInt(receiptSize) <= tmpTicketId.length())) { if (receiptPrefix != null) { tmpTicketId = receiptPrefix + tmpTicketId; } return tmpTicketId; } while (tmpTicketId.length() < Integer.parseInt(receiptSize)) { tmpTicketId = "0" + tmpTicketId; } if (receiptPrefix != null) { tmpTicketId = receiptPrefix + tmpTicketId; } return tmpTicketId; } else { return ""; } } public String printDate() { return Formats.TIMESTAMP.formatValue(date); } public String printUser() { return userInfo == null ? "" : userInfo.getName(); } public String printHost() { return host; } // Added JDL 28.05.13 for loyalty card functions /** * */ public void clearCardNumber() { loyaltyCardNumber = null; } /** * * @param cardNumber */ public void setLoyaltyCardNumber(String cardNumber) { loyaltyCardNumber = cardNumber; } /** * * @return */ public String getLoyaltyCardNumber() { return (loyaltyCardNumber); } public String printCustomer() { return cutomerInfoExt == null ? "" : cutomerInfoExt.getName(); } public String printPhone1() { return cutomerInfoExt == null ? "" : cutomerInfoExt.getPhone1(); } public String printArticlesCount() { return Formats.DOUBLE.formatValue(getArticlesCount()); } public String printSubTotal() { return Formats.CURRENCY.formatValue(getSubTotal()); } public String printTax() { return Formats.CURRENCY.formatValue(getTax()); } public String printTotal() { return Formats.CURRENCY.formatValue(getTotal()); } public String printTotalPaid() { return Formats.CURRENCY.formatValue(getTotalPaid()); } public String printTendered() { return Formats.CURRENCY.formatValue(getTendered()); } public String VoucherReturned() { return Formats.CURRENCY.formatValue(getTotalPaid() - getTotal()); } public boolean getOldTicket() { return (oldTicket); } public void setOldTicket(Boolean otState) { oldTicket = otState; } public String getTicketHeaderFooterData(String data) { AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); m_config.load(); 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"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketHeaderLine2() { String lineData = getTicketHeaderFooterData("header2"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketHeaderLine3() { String lineData = getTicketHeaderFooterData("header3"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketHeaderLine4() { String lineData = getTicketHeaderFooterData("header4"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketHeaderLine5() { String lineData = getTicketHeaderFooterData("header5"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketHeaderLine6() { String lineData = getTicketHeaderFooterData("header6"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine1() { String lineData = getTicketHeaderFooterData("footer1"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine2() { String lineData = getTicketHeaderFooterData("footer2"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine3() { String lineData = getTicketHeaderFooterData("footer3"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine4() { String lineData = getTicketHeaderFooterData("footer4"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine5() { String lineData = getTicketHeaderFooterData("footer5"); if (lineData != null) { return lineData; } else { return ""; } } public String printTicketFooterLine6() { String lineData = getTicketHeaderFooterData("footer6"); if (lineData != null) { return lineData; } else { return ""; } } }