OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 151 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.core.sales.pos.ui;

import org.openconcerto.erp.core.sales.pos.POSConfiguration;
import org.openconcerto.erp.core.sales.pos.io.DefaultTicketPrinter;
import org.openconcerto.erp.core.sales.pos.io.Printable;
import org.openconcerto.erp.core.sales.pos.io.TicketPrinter;
import org.openconcerto.erp.core.sales.pos.model.Paiement;
import org.openconcerto.erp.core.sales.pos.model.RegisterLog;
import org.openconcerto.erp.core.sales.pos.model.RegisterState;
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status;
import org.openconcerto.erp.core.sales.pos.model.Ticket;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Level;

abstract class RegisterSummary implements Printable {

    private final String name;
    private final RegisterLog log;

    protected RegisterSummary(final String name, final RegisterLog log) {
        super();
        this.name = name;
        this.log = log;
    }

    public boolean isPrintingTicketsList() {
        return true;
    }

    public final RegisterLog getLog() {
        return this.log;
    }

    public abstract String getLabel();

    protected abstract List<Ticket> getReceipts() throws ParseException, IOException;

    @Override
    public void print(TicketPrinter prt, int ticketWidth) {
        final DateFormat dateFormat = new SimpleDateFormat("dd/MM/YYYY à HH:mm:ss");
        final String title = this.name + " de la caisse " + getLog().getRegisterID();
        prt.clearBuffer(title);
        try {
            final List<Ticket> receipts = this.getReceipts();

            final Map<Ticket, Map<String, BigDecimal>> typesByReceipt = new LinkedHashMap<>();
            final Map<Ticket, BigDecimal> paidByReceipt = new LinkedHashMap<>();
            final Map<Ticket, BigDecimal> valueByReceipt = new LinkedHashMap<>();

            final Map<String, BigDecimal> totalByType = new TreeMap<>();
            BigDecimal total = BigDecimal.ZERO;
            BigDecimal totalPaid = BigDecimal.ZERO;

            for (final Ticket t : receipts) {
                final int receiptInCents = t.getTotalInCents();
                final BigDecimal receiptValue = BigDecimal.valueOf(receiptInCents).movePointLeft(2);

                BigDecimal receiptPaid = BigDecimal.ZERO;
                final Map<String, BigDecimal> byType = new TreeMap<>();
                for (final Paiement p : t.getPaiements()) {
                    final BigDecimal paid = BigDecimal.valueOf(p.getMontantInCents()).movePointLeft(2);
                    receiptPaid = receiptPaid.add(paid);
                    addInMap(byType, p.getTypeAsString(), paid);
                    addInMap(totalByType, p.getTypeAsString(), paid);
                }
                typesByReceipt.put(t, byType);
                valueByReceipt.put(t, receiptValue);
                paidByReceipt.put(t, receiptPaid);
                total = total.add(receiptValue);
                totalPaid = totalPaid.add(receiptPaid);
            }
            final BigDecimal rendu = totalPaid.subtract(total);

            prt.addToBuffer(title, TicketPrinter.BOLD_LARGE);
            prt.addToBuffer("");
            prt.addToBuffer("Edité le " + dateFormat.format(new Date()));
            final RegisterState registerState = getLog().getRegisterState();
            prt.addToBuffer((registerState.getStatus() == Status.OPEN ? "Ouvert" : "Fermé") + " le " + registerState.formatDate(dateFormat));
            prt.addToBuffer("");
            prt.addToBuffer("");
            prt.addToBuffer("Tickets de caisse", TicketPrinter.BOLD_LARGE);
            prt.addToBuffer("");

            Paiement espece = new Paiement(Paiement.ESPECES);
            // TODO same name as "Total TTC"
            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total des ventes", total.toPlainString()), TicketPrinter.BOLD);
            for (final Entry<String, BigDecimal> e2 : totalByType.entrySet()) {
                final String typePayment = e2.getKey();
                if (typePayment.equals(espece.getTypeAsString())) {
                    BigDecimal value = e2.getValue();
                    value = value.subtract(rendu);
                    prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "      " + typePayment, value.toPlainString()));
                } else {
                    prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "      " + typePayment, e2.getValue().toPlainString()));
                }
            }

            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total des paiements", totalPaid.toPlainString()), TicketPrinter.BOLD);
            for (final Entry<String, BigDecimal> e2 : totalByType.entrySet()) {
                prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "      " + e2.getKey(), e2.getValue().toPlainString()));
            }
            prt.addToBuffer("");
            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total rendu", rendu.toPlainString()), TicketPrinter.BOLD);
            prt.addToBuffer("");
            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total TTC (Euros)", total.toPlainString()), TicketPrinter.BOLD);
            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Nombre de tickets", "" + receipts.size()));
            final long avg = receipts.isEmpty() ? 0 : total.movePointRight(2).longValueExact() / receipts.size();
            prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Panier moyen (Euros)", BigDecimal.valueOf(avg).movePointLeft(2).toPlainString()));
            prt.addToBuffer("");
            if (isPrintingTicketsList()) {
                prt.addToBuffer("");
                prt.addToBuffer("Liste des tickets", TicketPrinter.BOLD_LARGE);
                prt.addToBuffer("");
                for (final Entry<Ticket, Map<String, BigDecimal>> e : typesByReceipt.entrySet()) {
                    final Ticket t = e.getKey();
                    final BigDecimal receiptValue = valueByReceipt.get(t);
                    prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, t.getCode(), receiptValue.toPlainString()), TicketPrinter.BOLD);
                    for (final Entry<String, BigDecimal> e2 : e.getValue().entrySet()) {
                        prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, " " + e2.getKey(), e2.getValue().toPlainString()));
                    }
                    // rendu
                    final BigDecimal receiptChange = paidByReceipt.get(t).subtract(receiptValue);
                    if (receiptChange.signum() != 0)
                        prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, " rendu", receiptChange.toPlainString()));

                    prt.addToBuffer("");
                }
            }
        } catch (Exception e) {
            POSConfiguration.getLogger().log(Level.WARNING, "Couldn't fill " + this.name, e);
            prt.addToBuffer("Erreur");
        }
        try {
            prt.printBuffer();
        } catch (Exception e) {
            POSConfiguration.getLogger().log(Level.WARNING, "Couldn't print " + this.name, e);
        }
    }

    static private final <K> void addInMap(final Map<K, BigDecimal> m, final K key, final BigDecimal val) {
        final BigDecimal prev = m.get(key);
        m.put(key, prev == null ? val : prev.add(val));
    }
}