Dépôt officiel du code source de l'ERP OpenConcerto
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()));
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;
}
}