OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

package org.openconcerto.modules.label;

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterJob;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.SimpleDoc;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.BaseDirs;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.ProductInfo;

public class ZPLPrinterPanel extends JPanel {
    private final HashMap<String, String> mapName = new HashMap<>();
    private final List<String> variables;
    private final List<String> knownVariables = new ArrayList<>();
    private Map<String, JTextField> editorMap = new HashMap<>();
    private String zpl;
    private final Properties properties = new Properties();

    public static void main(String[] args) throws IOException {
        // final File f = new File("Templates/Labels", "50x50.zpl");
        final File file = new File("Template/Labels", "57x32.zpl");
        String zpl = FileUtils.read(file);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                ZPLPrinterPanel p = new ZPLPrinterPanel(zpl);
                p.initUI(null);
                JFrame f = new JFrame();
                f.setTitle(file.getName());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setContentPane(p);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });

    }

    public ZPLPrinterPanel(String zpl) {
        this.zpl = zpl;
        this.variables = getVariables(zpl);
        this.knownVariables.add("product.code");
        this.knownVariables.add("product.name");
        this.knownVariables.add("product.material");
        this.knownVariables.add("product.color");
        this.knownVariables.add("product.size");
        this.knownVariables.add("product.ean13");
        this.knownVariables.add("product.price");
        this.knownVariables.add("product.pricewithtax");
        //
        this.mapName.put("product.name", "Nom");
        this.mapName.put("product.code", "Code");
        this.mapName.put("product.ean13", "Code à barres");
        this.mapName.put("product.price", "Prix HT");
        this.mapName.put("product.pricewithtax", "Prix TTC");
        this.mapName.put("product.treatment", "Traitement");
        this.mapName.put("product.origin", "Origine");
        this.mapName.put("product.batch", "Lot");
        this.mapName.put("product.size", "Taille");
        this.mapName.put("product.color", "Couleur");
        this.mapName.put("product.material", "Matière");
    }

    private final File getPrefFile() {
        final File prefsFolder = BaseDirs.create(ProductInfo.getInstance()).getPreferencesFolder();
        if (!prefsFolder.exists()) {
            prefsFolder.mkdirs();
        }
        return new File(prefsFolder, "labels.properties");
    }

    protected void initUI(SQLRowAccessor row) {
        final File prefsFolder = BaseDirs.create(ProductInfo.getInstance()).getPreferencesFolder();
        if (!prefsFolder.exists()) {
            prefsFolder.mkdirs();
        }

        final File file = getPrefFile();
        System.out.println(file.getAbsolutePath());
        if (file.exists()) {
            try {
                this.properties.load(new FileInputStream(file));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        this.setLayout(new GridBagLayout());
        GridBagConstraints c = new DefaultGridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        this.removeAll();

        // Fields

        Set<String> added = new HashSet<>();
        for (String v : this.knownVariables) {
            if (this.variables.contains(v)) {
                // Non editable
                String label = getName(v);
                c.gridx = 0;
                c.weightx = 0;
                this.add(new JLabel(label, SwingConstants.RIGHT), c);
                c.gridx++;
                c.weightx = 1;

                String value = getValueAsString(row, v);
                JTextField txt = new JTextField(20);
                if (value != null) {
                    txt.setText(value);
                    txt.setEditable(false);
                }
                this.editorMap.put(v, txt);
                this.add(txt, c);
                added.add(v);
                c.gridy++;
            }
        }
        for (String v : this.variables) {
            if (!added.contains(v)) {
                // Editable
                String label = getName(v);
                c.gridx = 0;
                c.weightx = 0;
                this.add(new JLabel(label, SwingConstants.RIGHT), c);
                c.gridx++;
                c.weightx = 1;
                JTextField txt = new JTextField(20);
                this.editorMap.put(v, txt);
                this.add(txt, c);
                added.add(v);
                c.gridy++;
            }

        }

        c.gridwidth = 2;
        c.gridx = 0;
        this.add(new JLabelBold("Paramètres d'impression"), c);
        // Printer selector
        c.gridx = 0;
        c.gridy++;
        final JPanel l1 = new JPanel();
        l1.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));

        l1.add(new JLabel("Nombre d'étiquettes"));
        final JSpinner nbLabels = new JSpinner(new SpinnerNumberModel(1, 1, 1000, 10));
        l1.add(nbLabels);
        this.add(l1, c);
        // Delay
        l1.add(new JLabel(" Pause entre chaque impression"));
        final JSpinner delayLabels = new JSpinner(new SpinnerNumberModel(800, 100, 10000, 100));
        l1.add(delayLabels);
        this.add(l1, c);
        l1.add(new JLabel("ms"));

        c.gridy++;

        final JPanel lPrintNetwork = new JPanel();
        lPrintNetwork.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
        JRadioButton radioNetworkPrinter = new JRadioButton("imprimante réseau    IP :");
        lPrintNetwork.add(radioNetworkPrinter);
        JTextField textPrinterIP = new JTextField(16);
        lPrintNetwork.add(textPrinterIP);
        lPrintNetwork.add(new JLabel(" Port :"));
        JSpinner portZPL = new JSpinner(new SpinnerNumberModel(9100, 24, 10000, 1));
        lPrintNetwork.add(portZPL);
        this.add(lPrintNetwork, c);

        c.gridy++;
        final JPanel lPrintLocal = new JPanel();
        lPrintLocal.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
        JRadioButton radioLocalPrinter = new JRadioButton("imprimante locale");
        lPrintLocal.add(radioLocalPrinter);
        radioLocalPrinter.setSelected(true);
        this.add(lPrintLocal, c);

        final ButtonGroup gr = new ButtonGroup();
        gr.add(radioLocalPrinter);
        gr.add(radioNetworkPrinter);
        c.gridy++;
        c.weighty = 1;
        c.gridx = 1;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.SOUTHEAST;

        // Restore state from properties
        if (this.properties.getOrDefault("printerType", "local").equals("local")) {
            radioLocalPrinter.setSelected(true);
        } else {
            radioNetworkPrinter.setSelected(true);
        }
        textPrinterIP.setText(this.properties.getOrDefault("printerIp", "").toString());
        portZPL.setValue(Long.parseLong(this.properties.getOrDefault("printerPort", "9100").toString()));
        nbLabels.setValue(Long.parseLong(this.properties.getOrDefault("nbLabels", "1").toString()));
        delayLabels.setValue(Long.parseLong(this.properties.getOrDefault("delay", "800").toString()));
        // Print

        JButton printButton = new JButton("Imprimer");
        this.add(printButton, c);
        printButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    if (radioLocalPrinter.isSelected()) {
                        ZPLPrinterPanel.this.properties.put("printerType", "local");
                    } else {
                        ZPLPrinterPanel.this.properties.put("printerType", "network");
                        ZPLPrinterPanel.this.properties.put("printerIp", textPrinterIP.getText());
                        ZPLPrinterPanel.this.properties.put("printerPort", portZPL.getValue().toString());
                    }
                    ZPLPrinterPanel.this.properties.put("nbLabels", nbLabels.getValue().toString());
                    ZPLPrinterPanel.this.properties.put("delay", delayLabels.getValue().toString());
                    // Save Prefs
                    ZPLPrinterPanel.this.properties.store(new FileOutputStream(getPrefFile()), "");
                } catch (Exception e1) {
                    ExceptionHandler.handle("Erreur de sauvegarde de " + getPrefFile().getAbsolutePath(), e1);
                }
                final String code = createZPLCode();
                System.out.println("ZPL:");
                System.out.println(code);
                byte[] data = code.getBytes(StandardCharsets.UTF_8);
                if (radioNetworkPrinter.isSelected()) {
                    Socket socket = null;
                    try {
                        socket = new Socket(textPrinterIP.getText(), ((Number) portZPL.getValue()).intValue());
                        final DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                        final int nb = ((Number) nbLabels.getValue()).intValue();
                        for (int i = 0; i < nb; i++) {
                            out.write(data);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(printButton, "Erreur d'impression réseau : " + ex.getMessage());
                    } finally {
                        if (socket != null) {
                            try {
                                socket.close();
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                        }

                    }
                } else {
                    try {
                        final PrinterJob pj1 = PrinterJob.getPrinterJob();
                        if (pj1.printDialog()) {
                            final PrintService ps = pj1.getPrintService();
                            final int nb = ((Number) nbLabels.getValue()).intValue();
                            for (int i = 0; i < nb; i++) {
                                final DocPrintJob pj = ps.createPrintJob();
                                final SimpleDoc doc = new SimpleDoc(data, DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
                                pj.print(doc, null);
                                Thread.sleep(((Number) delayLabels.getValue()).intValue());
                            }
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(printButton, "Erreur d'impression locale : " + ex.getMessage());
                    }
                }

            }
        });

    }

    private String createZPLCode() {

        final BufferedReader reader = new BufferedReader(new StringReader(this.zpl));
        final StringBuilder builder = new StringBuilder();

        try {
            String line = reader.readLine();
            while (line != null) {
                if (line.contains("${")) {
                    boolean add = false;
                    for (String v : this.editorMap.keySet()) {
                        if (line.contains("${" + v + "}")) {
                            final String value = this.editorMap.get(v).getText();
                            line = line.replace("${" + v + "}", value);
                            if (!value.trim().isEmpty()) {
                                add = true;
                            }
                        }
                    }
                    if (add) {
                        builder.append(line);
                        builder.append("\n");
                    }

                } else {
                    builder.append(line);
                    builder.append("\n");
                }
                line = reader.readLine();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return builder.toString();
    }

    public String getValueAsString(SQLRowAccessor row, String variableName) {
        if (row == null) {
            return null;
        }
        System.err.println("ZPLPrinterPanel.getValueAsString()" + variableName + " : " + row);
        if (variableName.equals("product.code")) {
            return row.getString("CODE");
        } else if (variableName.equals("product.name")) {
            return row.getString("NOM");
        } else if (variableName.equals("product.ean13")) {
            return row.getString("CODE_BARRE");
        } else if (variableName.equals("product.price")) {
            final BigDecimal bigDecimal = row.getBigDecimal("PV_HT");
            return new DecimalFormat("#0.00").format(bigDecimal);
        } else if (variableName.equals("product.pricewithtax")) {
            final BigDecimal bigDecimal = row.getBigDecimal("PV_TTC");
            return new DecimalFormat("#0.00").format(bigDecimal);
        } else if (variableName.equals("product.material")) {
            return row.getString("MATIERE");
        } else if (variableName.equals("product.color")) {
            if (row.getTable().contains("ID_ARTICLE_DECLINAISON_COULEUR")) {
                if (row.getObject("ID_ARTICLE_DECLINAISON_COULEUR") != null && !row.isForeignEmpty("ID_ARTICLE_DECLINAISON_COULEUR")) {
                    return row.getForeign("ID_ARTICLE_DECLINAISON_COULEUR").getString("NOM");
                }
            }
        } else if (variableName.equals("product.size")) {
            if (row.getTable().contains("ID_ARTICLE_DECLINAISON_TAILLE")) {
                if (row.getObject("ID_ARTICLE_DECLINAISON_TAILLE") != null && !row.isForeignEmpty("ID_ARTICLE_DECLINAISON_TAILLE")) {
                    return row.getForeign("ID_ARTICLE_DECLINAISON_TAILLE").getString("NOM");
                }
            }
        }
        return "";
    }

    public String getName(String variableName) {
        String n = this.mapName.get(variableName);
        if (n == null) {
            return variableName;
        }
        return n;
    }

    public List<String> getVariables(String str) {
        final List<String> result = new ArrayList<>();
        if (str == null || str.length() < 4) {
            return result;
        }
        final int l = str.length() - 1;
        int start = 0;
        boolean inName = false;
        for (int i = 0; i < l; i++) {
            char c1 = str.charAt(i);
            char c2 = str.charAt(i + 1);
            if (!inName) {
                if (c1 == '$' && c2 == '{') {
                    start = i + 2;
                    inName = true;
                }
            } else if (c2 == '}') {
                final int stop = i + 1;
                String v = str.substring(start, stop);
                result.add(v);
                inName = false;
            }
        }
        return result;
    }
}