Dépôt officiel du code source de l'ERP OpenConcerto
Rev 149 | Rev 156 | Go to most recent revision | 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.model;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.TotalCalculator;
import org.openconcerto.erp.core.customerrelationship.customer.element.CompteClientTransactionSQLELement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
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.RegisterFiles.HashMode;
import org.openconcerto.erp.core.sales.pos.ui.TicketCellRenderer;
import org.openconcerto.erp.generationEcritures.GenerationEcritures;
import org.openconcerto.erp.generationEcritures.GenerationMvtVirement;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.Pair;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.XMLDateFormat;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
public class Ticket implements Printable {
private static final XMLDateFormat DATE_FMT = new XMLDateFormat();
// Propre a ticket
private final List<Paiement> paiements = new ArrayList<Paiement>();
private final List<Pair<Article, Integer>> items = new ArrayList<Pair<Article, Integer>>();
private Calendar creationCal;
private Client client = Client.NONE;
private final int number;
private final String previousHash;
private boolean additionnalCopyRequested = false;
// Propre à la caisse
private final int caisseNumber;
private static final SQLTable tableArticle = Configuration.getInstance().getRoot().findTable("ARTICLE");
public static Ticket getTicketFromCode(final String code, final RegisterFiles registerFiles) {
try {
final ReceiptCode receiptCode = new ReceiptCode(code);
final Path receiptFile = registerFiles.getReceiptFile(receiptCode);
if (receiptFile != null && Files.exists(receiptFile)) {
return parseFile(receiptFile.toFile());
} else {
// old location
return parseFile(receiptCode.getFile());
}
} catch (final Exception e) {
return null;
}
}
public void setClient(final Client client) {
this.client = client;
}
public Client getClient() {
return this.client;
}
public static Ticket parseFile(final File file) {
return parseFile(file, HashMode.REQUIRED);
}
public static Ticket parseFile(final File file, final HashMode hashMode) {
if (!file.exists()) {
return null;
}
try {
// XML Reading
final Document document = RegisterFiles.parse(file.toPath(), hashMode);
final Element root = document.getRootElement();
final ReceiptCode receiptCode = new ReceiptCode(root.getAttributeValue("code"));
final String creationDateAttr = root.getAttributeValue("creationDate");
final Calendar c = (Calendar) receiptCode.getDay().clone();
if (creationDateAttr == null) {
final String h = root.getAttributeValue("hour");
final String m = root.getAttributeValue("minute");
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(h));
c.set(Calendar.MINUTE, Integer.parseInt(m));
} else {
c.setTime((Date) DATE_FMT.parseObject(creationDateAttr));
}
final String client = root.getAttributeValue("clientID", "1");
final Ticket t = new Ticket(receiptCode, c, root.getAttributeValue("previousHash"));
t.setClient(new Client(Integer.parseInt(client), "", BigDecimal.ZERO));
// article
final List<Element> children = root.getChildren("article");
for (final Element element : children) {
final int qte = Integer.parseInt(element.getAttributeValue("qte"));
final BigDecimal prix_unitaire_cents_ht = new BigDecimal(element.getAttributeValue("prixHT"));
final int idTaxe = Integer.parseInt(element.getAttributeValue("idTaxe"));
final BigDecimal prix_unitaire_cents = new BigDecimal(element.getAttributeValue("prix"));
final String categorie = element.getAttributeValue("categorie");
final String name = element.getValue();
final String codebarre = element.getAttributeValue("codebarre");
final String codeArt = element.getAttributeValue("code");
final Categorie cat = new Categorie(categorie);
final String valueID = element.getAttributeValue("id");
final int id = valueID == null || valueID.trim().length() == 0 ? tableArticle.getUndefinedID() : Integer.parseInt(valueID);
final Article art = new Article(cat, name, id);
art.setPriceWithTax(prix_unitaire_cents);
art.setCode(codeArt);
art.setPriceWithoutTax(prix_unitaire_cents_ht);
art.setIdTaxe(idTaxe);
art.setBarCode(codebarre);
final Pair<Article, Integer> line = new Pair<Article, Integer>(art, qte);
t.items.add(line);
}
// paiement
final List<Element> payChildren = root.getChildren("paiement");
for (final Element element : payChildren) {
final String type = element.getAttributeValue("type");
final int montant_cents = Integer.parseInt(element.getAttributeValue("montant"));
if (montant_cents != 0) {
int tp = Paiement.ESPECES;
if (type.equals("CB")) {
tp = Paiement.CB;
} else if (type.equals("CHEQUE")) {
tp = Paiement.CHEQUE;
} else if (type.equals("ESPECES")) {
tp = Paiement.ESPECES;
} else if (type.equals("SOLDE")) {
tp = Paiement.SOLDE;
}
final Paiement p = new Paiement(tp);
p.setMontantInCents(montant_cents);
t.paiements.add(p);
}
}
return t;
} catch (final Exception e) {
System.err.println("Error with ticket : " + file + " : " + e.getMessage());
e.printStackTrace();
return null;
}
}
// TODO receiptCode should be immutable and the day part should be the current accounting day
// not the day of the present time. E.g. for work day beginning at 15:00, even at 3:00 the
// receipt code should contain the previous day.
// The creationCal should only be set once the ticket is done (i.e. no further modifications
// should be allowed)
// create new ticket, i.e. null creationDate since it's not done
public Ticket(final int caisse, final int number, final String previousHash) {
this(new ReceiptCode(caisse, Calendar.getInstance(), number), null, previousHash);
}
// re-create existing ticket
public Ticket(final ReceiptCode code, final Calendar creationDate, final String previousHash) {
this.caisseNumber = code.getCaisseNb();
this.number = code.getDayIndex();
this.previousHash = previousHash;
this.setCreationCal(creationDate);
}
public final String getPreviousHash() {
return this.previousHash;
}
public final ReceiptCode getReceiptCode() {
// TODO replace our fields by one ReceiptCode
return new ReceiptCode(this.getCaisseNumber(), this.getCreationCal(), this.getNumber());
}
public String getCode() {
return getReceiptCode().getCode();
}
/**
* Numero du ticket fait ce jour, compteur remis à 1 chaque jour
*
* @return the index of this ticket, inside its day.
*/
public int getNumber() {
return this.number;
}
/**
* Numero de la caisse, de 1 à n
*/
final int getCaisseNumber() {
return this.caisseNumber;
}
public String save(final RegisterFiles files, final SQLElementDirectory dir) throws IOException, SQLException {
final String fileHash = files.save(this);
// FIXME handle failure
this.handleSolde(dir);
return fileHash;
}
final byte[] saveToFile(final Path f) throws IOException {
final Calendar c = getCreationCal();
final Element topLevel = new Element("ticket");
topLevel.setAttribute(new Attribute("code", this.getCode()));
if (this.getPreviousHash() != null)
topLevel.setAttribute("previousHash", this.getPreviousHash());
topLevel.setAttribute("creationDate", DATE_FMT.format(c.getTime()));
topLevel.setAttribute("clientID", String.valueOf(this.client.getId()));
// Articles
for (final Pair<Article, Integer> item : this.items) {
final Element e = new Element("article");
e.setAttribute("qte", String.valueOf(item.getSecond()));
// Prix unitaire
e.setAttribute("prix", String.valueOf(item.getFirst().getPriceWithTax()));
e.setAttribute("prixHT", String.valueOf(item.getFirst().getPriceWithoutTax()));
e.setAttribute("idTaxe", String.valueOf(item.getFirst().getIdTaxe()));
e.setAttribute("categorie", item.getFirst().getCategorie().getName());
e.setAttribute("codebarre", item.getFirst().getBarCode());
e.setAttribute("code", item.getFirst().getCode());
e.setAttribute("id", String.valueOf(item.getFirst().getId()));
e.setText(item.getFirst().getName());
topLevel.addContent(e);
}
// Paiements
for (final Paiement paiement : this.paiements) {
final int montantInCents = paiement.getMontantInCents();
if (montantInCents != 0) {
final Element e = new Element("paiement");
String type = "";
if (paiement.getType() == Paiement.CB) {
type = "CB";
} else if (paiement.getType() == Paiement.CHEQUE) {
type = "CHEQUE";
} else if (paiement.getType() == Paiement.ESPECES) {
type = "ESPECES";
} else if (paiement.getType() == Paiement.SOLDE) {
type = "SOLDE";
}
e.setAttribute("type", type);
e.setAttribute("montant", String.valueOf(montantInCents));
topLevel.addContent(e);
}
}
return RegisterFiles.save(new Document(topLevel), f);
}
private final void handleSolde(final SQLElementDirectory dir) throws SQLException {
final SQLTable table = dir.getElement(CompteClientTransactionSQLELement.class).getTable();
final SQLTable tablePrefCompte = table.getDBRoot().findTable("PREFS_COMPTE");
final SQLRow rowPrefsCompte = tablePrefCompte.getRow(2);
final Calendar c = getCreationCal();
SQLUtils.executeAtomic(table.getDBSystemRoot().getDataSource(), new SQLUtils.SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
for (final Paiement paiement : Ticket.this.paiements) {
final int montantInCents = paiement.getMontantInCents();
if (montantInCents > 0 && paiement.getType() == Paiement.SOLDE) {
final SQLRowValues rowValsTransact = new SQLRowValues(table);
rowValsTransact.put("ID_CLIENT", Ticket.this.client.getId());
rowValsTransact.put("DATE", c.getTime());
final BigDecimal amountTransaction = new BigDecimal(montantInCents).movePointLeft(2);
rowValsTransact.put("MONTANT", amountTransaction.negate());
SQLRow rowTransact = rowValsTransact.commit();
final GenerationEcritures ecr = new GenerationEcritures();
final int idMvt = ecr.getNewMouvement(table.getName(), rowTransact.getID(), 1, "Transact. " + Ticket.this.client.getFullName() + " Ticket " + getCode());
rowTransact = rowTransact.createEmptyUpdateRow().put("ID_MOUVEMENT", idMvt).commit();
// mise à jour du solde
final SQLTable tableClient = table.getForeignTable("ID_CLIENT");
final SQLRow row = tableClient.getRow(Ticket.this.client.getId());
final BigDecimal solde = row.getBigDecimal("SOLDE_COMPTE");
final BigDecimal nouveauSolde = solde.subtract(amountTransaction);
row.createEmptyUpdateRow().put("SOLDE_COMPTE", nouveauSolde).commit();
// Créeation des réglements et écritures
int idCompteAvanceClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_AVANCE_CLIENT");
int idCompteClient = row.getInt("ID_COMPTE_PCE");
if (idCompteAvanceClient <= 1) {
idCompteAvanceClient = ComptePCESQLElement.getIdComptePceDefault("AvanceClients");
}
// compte Clients
if (idCompteClient <= 1) {
idCompteClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteClient <= 1) {
idCompteClient = ComptePCESQLElement.getIdComptePceDefault("Clients");
}
}
new GenerationMvtVirement(idCompteAvanceClient, idCompteClient, 0, montantInCents, "Utilisation compte client", c.getTime(), JournalSQLElement.VENTES, "Ticket N°" + getCode())
.genereMouvement();
}
}
return null;
}
});
}
@Override
public void print(final TicketPrinter prt, final int ticketWidth) {
final int maxWidth = ticketWidth;
final int MAX_PRICE_WIDTH = 8;
final int MAX_QTE_WIDTH = 5;
prt.clearBuffer("receipt " + this.getCode());
final List<TicketLine> headers = POSConfiguration.getInstance().getHeaderLines();
for (final TicketLine line : headers) {
prt.addToBuffer(line);
}
// Date
prt.addToBuffer("");
final SimpleDateFormat df = new SimpleDateFormat("EEEE d MMMM yyyy à HH:mm", Locale.FRENCH);
prt.addToBuffer(DefaultTicketPrinter.formatCenter(maxWidth, "Le " + df.format(getCreationDate())));
prt.addToBuffer("");
List<Pair<Article, Integer>> itemsToPrint = new ArrayList<>(this.items);
Collections.sort(itemsToPrint, new Comparator<Pair<Article, Integer>>() {
@Override
public int compare(Pair<Article, Integer> o1, Pair<Article, Integer> o2) {
final Article p1 = o1.getFirst();
final Article p2 = o2.getFirst();
final Categorie c1 = p1.getCategorie();
final Categorie c2 = p2.getCategorie();
if (c1.equals(c2)) {
return p1.getName().compareTo(p2.getName());
}
// Unknown first
if (c1.isUnknown()) {
return -1;
}
if (c2.isUnknown()) {
return 1;
}
// Sort by name
return c1.getName().compareTo(c2.getName());
}
});
Categorie currentCategorie = null;
for (final Pair<Article, Integer> item : this.items) {
final Article article = item.getFirst();
if (currentCategorie == null || !currentCategorie.getName().equals(article.getCategorie().getName())) {
// Print category name, except for unknown
currentCategorie = article.getCategorie();
if (!currentCategorie.isUnknown()) {
prt.addToBuffer(currentCategorie.getName(), TicketPrinter.BOLD);
}
}
final Integer nb = item.getSecond();
final Float tauxFromId = TaxeCache.getCache().getTauxFromId(article.getIdTaxe());
final BigDecimal tauxTVA = new BigDecimal(tauxFromId).movePointLeft(2).add(BigDecimal.ONE);
final BigDecimal unitPrice = article.getPriceWithoutTax().multiply(tauxTVA, DecimalUtils.HIGH_PRECISION);
final BigDecimal multiply = article.getPriceWithoutTax().multiply(new BigDecimal(nb), DecimalUtils.HIGH_PRECISION).multiply(tauxTVA, DecimalUtils.HIGH_PRECISION);
final String qtyString = DefaultTicketPrinter.formatRight(MAX_QTE_WIDTH, String.valueOf(nb));
final String priceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(multiply.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue()));
String unitPriceString = "";
if (nb != 1) {
unitPriceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(unitPrice.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue()));
}
if (article.getCode() != null && !article.getCode().isEmpty()) {
// 2 lines
final String codeString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH - 1 - unitPriceString.length(), article.getCode());
prt.addToBuffer(qtyString + " " + codeString + " " + unitPriceString + " " + priceString);
final String nameString = DefaultTicketPrinter.formatLeft(maxWidth - MAX_QTE_WIDTH - 1, article.getName());
prt.addToBuffer(" " + nameString);
} else {
// 1 line
final String nameString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH - 1 - unitPriceString.length(), article.getName());
prt.addToBuffer(qtyString + " " + nameString + " " + unitPriceString + " " + priceString);
}
}
final StringBuilder spacer = new StringBuilder();
for (int i = 0; i <= MAX_QTE_WIDTH; i++) {
spacer.append(' ');
}
for (int i = 0; i < maxWidth - MAX_QTE_WIDTH - 1; i++) {
spacer.append('=');
}
prt.addToBuffer(spacer.toString());
final TotalCalculator calc = getTotalCalculator();
final int totalTTCInCents = calc.getTotalTTC().movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue();
prt.addToBuffer(DefaultTicketPrinter.formatRight(maxWidth - MAX_PRICE_WIDTH, "MONTANT TOTAL TTC (Euros) : ")
+ DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(totalTTCInCents)), TicketPrinter.BOLD);
final Map<SQLRowAccessor, Tuple2<BigDecimal, BigDecimal>> mapHtTVARowTaux = calc.getMapHtTVARowTaux();
for (final SQLRowAccessor row : mapHtTVARowTaux.keySet()) {
final Tuple2<BigDecimal, BigDecimal> htTVA = mapHtTVARowTaux.get(row);
final float tvaTaux = TaxeCache.getCache().getTauxFromId(row.getID());
final BigDecimal montantTVA = htTVA.get1();
if (montantTVA != null && montantTVA.signum() != 0) {
prt.addToBuffer(
DefaultTicketPrinter.formatRight(maxWidth - MAX_PRICE_WIDTH, "Dont TVA " + tvaTaux + "% : ")
+ DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(montantTVA.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue())),
TicketPrinter.NORMAL);
}
}
prt.addToBuffer("");
//
for (final Paiement paiement : this.paiements) {
String type = "";
final int montantInCents = paiement.getMontantInCents();
if (montantInCents != 0) {
if (montantInCents > 0) {
type = "Paiement ";
} else {
type = "Remboursement ";
}
if (paiement.getType() == Paiement.CB) {
type = "CB";
} else if (paiement.getType() == Paiement.CHEQUE) {
type = "par chèque";
} else if (paiement.getType() == Paiement.ESPECES) {
type = "en espèces";
} else if (paiement.getType() == Paiement.SOLDE) {
type = "depuis solde";
}
type += " de " + TicketCellRenderer.centsToString(montantInCents);
if (montantInCents > 100) {
type += " euros";
} else {
type += " euro";
}
prt.addToBuffer(type);
}
}
// Montant Rendu
if (getTotalInCents() < getPaidTotal()) {
final int montantInCents = getPaidTotal() - getTotalInCents();
String type = "Rendu : " + TicketCellRenderer.centsToString(montantInCents);
if (montantInCents > 100) {
type += " euros";
} else {
type += " euro";
}
prt.addToBuffer(type);
}
prt.addToBuffer("");
// Footer
final List<TicketLine> footers = POSConfiguration.getInstance().getFooterLines();
for (final TicketLine line : footers) {
prt.addToBuffer(line);
}
prt.addToBuffer("");
prt.addToBuffer(getCode(), TicketPrinter.BARCODE);
prt.addToBuffer("");
prt.addToBuffer("Ticket créé par l'ERP OpenConcerto.");
try {
prt.printBuffer();
} catch (final Exception e) {
e.printStackTrace();
}
}
public Date getCreationDate() {
return this.getCreationCal().getTime();
}
public Calendar getCreationCal() {
return this.creationCal;
}
public void setCreationCal(final Calendar cal) {
// FIXME date mismatch when ticket created one day and saved the next one
this.creationCal = cal == null ? null : (Calendar) cal.clone();
}
public void addPaiement(final Paiement p1) {
this.paiements.add(p1);
}
public boolean isAdditionnalCopyRequested() {
return additionnalCopyRequested;
}
public void addArticle(final Article a) {
boolean alreadyExist = false;
if (a.isAdditionalCopyRequested()) {
this.additionnalCopyRequested = true;
}
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(a)) {
alreadyExist = true;
break;
}
}
if (!alreadyExist) {
final Pair<Article, Integer> line = new Pair<Article, Integer>(new Article(a), 1);
this.items.add(line);
}
}
public void incrementArticle(final Article a) {
boolean alreadyExist = false;
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(a)) {
alreadyExist = true;
line.setSecond(line.getSecond() + 1);
break;
}
}
if (!alreadyExist) {
final Pair<Article, Integer> line = new Pair<Article, Integer>(a, 1);
this.items.add(line);
}
}
public List<Paiement> getPaiements() {
return this.paiements;
}
public int getTotalInCents() {
final TotalCalculator calc = getTotalCalculator();
final BigDecimal totalTTC = calc.getTotalTTC();
return totalTTC.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue();
}
public TotalCalculator getTotalCalculator() {
final SQLTable tableElt = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().findTable("SAISIE_VENTE_FACTURE_ELEMENT");
final TotalCalculator calc = new TotalCalculator("T_PA_HT", "T_PV_HT", null);
final String val = DefaultNXProps.getInstance().getStringProperty("ArticleService");
final Boolean bServiceActive = Boolean.valueOf(val);
calc.setServiceActive(bServiceActive != null && bServiceActive);
final int size = this.items.size();
for (int i = 0; i < size; i++) {
final Pair<Article, Integer> line = this.items.get(i);
final int count = line.getSecond();
final Article art = line.getFirst();
final SQLRowValues rowVals = new SQLRowValues(tableElt);
rowVals.put("T_PV_HT", art.getPriceWithoutTax().multiply(new BigDecimal(count)));
rowVals.put("QTE", count);
rowVals.put("ID_TAXE", art.getIdTaxe());
calc.addLine(rowVals, tableArticle.getRow(art.getId()), i, false);
}
calc.checkResult();
return calc;
}
public List<Pair<Article, Integer>> getArticles() {
return this.items;
}
public void clearArticle(final Article article) {
Pair<Article, Integer> toRemove = null;
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(article)) {
toRemove = line;
break;
}
}
if (toRemove != null) {
this.items.remove(toRemove);
}
}
public void setArticleCount(final Article article, final int count) {
// TODO Allow only if annulation?
// if (count <= 0) {
// this.clearArticle(article);
// return;
// }
Pair<Article, Integer> toModify = null;
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(article)) {
toModify = line;
break;
}
}
if (toModify != null) {
toModify.setSecond(count);
}
}
public int getItemCount(final Article article) {
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(article)) {
return line.getSecond();
}
}
return 0;
}
public int getPaidTotal() {
int paid = 0;
for (final Paiement p : this.paiements) {
paid += p.getMontantInCents();
}
return paid;
}
public void removeArticle(final Article a) {
Pair<Article, Integer> lineToDelete = null;
for (final Pair<Article, Integer> line : this.items) {
if (line.getFirst().equals(a)) {
final int count = line.getSecond() + 1;
if (count <= 0) {
lineToDelete = line;
}
line.setSecond(count);
break;
}
}
if (lineToDelete != null) {
this.items.remove(lineToDelete);
}
}
@Override
public String toString() {
return "Ticket " + getCode();
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof Ticket) {
final Ticket t = (Ticket) obj;
return t.getCode().equals(getCode());
}
return false;
}
@Override
public int hashCode() {
return getCode().hashCode();
}
public void deleteTicket(final SQLElementDirectory dir) throws IOException {
final SQLTable table = dir.getElement(CompteClientTransactionSQLELement.class).getTable();
for (final Paiement paiement : this.paiements) {
final int montantInCents = paiement.getMontantInCents();
if (montantInCents > 0 && paiement.getType() == Paiement.SOLDE) {
try {
SQLUtils.executeAtomic(table.getDBSystemRoot().getDataSource(), new SQLUtils.SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
final SQLTable tablePrefCompte = table.getDBRoot().findTable("PREFS_COMPTE");
final SQLRow rowPrefsCompte = tablePrefCompte.getRow(2);
final SQLRowValues rowValsTransact = new SQLRowValues(table);
rowValsTransact.put("ID_CLIENT", Ticket.this.client.getId());
rowValsTransact.put("DATE", getCreationCal().getTime());
final BigDecimal amountTransaction = new BigDecimal(montantInCents).movePointLeft(2);
rowValsTransact.put("MONTANT", amountTransaction);
SQLRow rowTransact = rowValsTransact.commit();
final GenerationEcritures ecr = new GenerationEcritures();
final int idMvt = ecr.getNewMouvement(table.getName(), rowTransact.getID(), 1, "Annule Transact. " + Ticket.this.client.getFullName() + " Ticket " + getCode());
rowTransact = rowTransact.createEmptyUpdateRow().put("ID_MOUVEMENT", idMvt).commit();
// mise à jour du solde
final SQLTable tableClient = table.getForeignTable("ID_CLIENT");
final SQLRow row = tableClient.getRow(Ticket.this.client.getId());
final BigDecimal solde = row.getBigDecimal("SOLDE_COMPTE");
final BigDecimal nouveauSolde = solde.add(amountTransaction);
row.createEmptyUpdateRow().put("SOLDE_COMPTE", nouveauSolde).commit();
// Créeation des réglements et écritures
int idCompteAvanceClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_AVANCE_CLIENT");
int idCompteClient = row.getInt("ID_COMPTE_PCE");
try {
if (idCompteAvanceClient <= 1) {
idCompteAvanceClient = ComptePCESQLElement.getIdComptePceDefault("AvanceClients");
}
// compte Clients
if (idCompteClient <= 1) {
idCompteClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteClient <= 1) {
idCompteClient = ComptePCESQLElement.getIdComptePceDefault("Clients");
}
}
} catch (final Exception e) {
e.printStackTrace();
throw new SQLException(e);
}
new GenerationMvtVirement(idCompteAvanceClient, idCompteClient, montantInCents, 0L, "Annulation transaction compte client", getCreationCal().getTime(),
JournalSQLElement.VENTES, "Ticket N°" + getCode()).genereMouvement();
return null;
}
});
} catch (final SQLException e) {
e.printStackTrace();
}
}
}
getReceiptCode().markDeleted();
}
}