Line 83... |
Line 83... |
83 |
import org.jdom2.Document;
|
83 |
import org.jdom2.Document;
|
84 |
import org.jdom2.Element;
|
84 |
import org.jdom2.Element;
|
85 |
import org.jdom2.Namespace;
|
85 |
import org.jdom2.Namespace;
|
86 |
|
86 |
|
87 |
public final class SDDMessageSQLElement extends ComptaSQLConfElement {
|
87 |
public final class SDDMessageSQLElement extends ComptaSQLConfElement {
|
88 |
static final String TABLE_NAME = "SEPA_DIRECT_DEBIT_MESSAGE";
|
88 |
static public final String TABLE_NAME = "SEPA_DIRECT_DEBIT_MESSAGE";
|
89 |
static public final String XML_LOCATION_PREF_KEY = "SDD.XML.location";
|
89 |
static public final String XML_LOCATION_PREF_KEY = "SDD.XML.location";
|
90 |
public static final String SERIAL_MD = "SDD_MESSAGE_SERIAL";
|
90 |
public static final String SERIAL_MD = "SDD_MESSAGE_SERIAL";
|
91 |
|
91 |
|
92 |
public static SQLCreateTable getCreateTable(final DBRoot root) {
|
92 |
public static SQLCreateTable getCreateTable(final DBRoot root) {
|
93 |
if (root.contains(TABLE_NAME))
|
93 |
if (root.contains(TABLE_NAME))
|
Line 170... |
Line 170... |
170 |
@Override
|
170 |
@Override
|
171 |
protected String createCode() {
|
171 |
protected String createCode() {
|
172 |
// TODO rename createCodeFromPackage() to createCodeOfPackage() and change createCode()
|
172 |
// TODO rename createCodeFromPackage() to createCodeOfPackage() and change createCode()
|
173 |
// implementation to use a new createCodeFromPackage() which uses the class name (w/o
|
173 |
// implementation to use a new createCodeFromPackage() which uses the class name (w/o
|
174 |
// SQLElement suffix)
|
174 |
// SQLElement suffix)
|
175 |
return this.createCodeFromPackage() + ".SDDMessage";
|
175 |
return this.createCodeOfPackage() + ".SDDMessage";
|
176 |
}
|
176 |
}
|
177 |
|
177 |
|
178 |
public final void exportXML(final Component comp, final List<? extends SQLRowAccessor> messages) {
|
178 |
public final void exportXML(final Component comp, final List<? extends SQLRowAccessor> messages) {
|
179 |
final Preferences sddMsgPrefs = getPreferences();
|
179 |
final Preferences sddMsgPrefs = getPreferences();
|
180 |
final String storedPath = sddMsgPrefs.get(XML_LOCATION_PREF_KEY, "");
|
180 |
final String storedPath = sddMsgPrefs.get(XML_LOCATION_PREF_KEY, "");
|
Line 236... |
Line 236... |
236 |
}
|
236 |
}
|
237 |
|
237 |
|
238 |
static private final class InvoicesByPaymentInfo {
|
238 |
static private final class InvoicesByPaymentInfo {
|
239 |
private final Date lowerBound, upperBound;
|
239 |
private final Date lowerBound, upperBound;
|
240 |
|
240 |
|
- |
|
241 |
// { collection date -> { sequence type -> invoice } }
|
241 |
private final NavigableMap<Date, ListMap<String, InvoiceElem>> map = new TreeMap<>();
|
242 |
private final NavigableMap<Date, ListMap<String, InvoiceElem>> map = new TreeMap<>();
|
242 |
private final Set<Number> lockedInvoicesIDs = new HashSet<>();
|
243 |
private final Set<Number> lockedInvoicesIDs = new HashSet<>();
|
243 |
private BigDecimal sum = BigDecimal.ZERO;
|
244 |
private BigDecimal sum = BigDecimal.ZERO;
|
244 |
private final Set<String> invoiceNumbers = new HashSet<>();
|
245 |
private final Set<String> invoiceNumbers = new HashSet<>();
|
245 |
private final Set<String> invoiceMandates = new HashSet<>();
|
246 |
private final Set<String> invoiceMandates = new HashSet<>();
|
Line 276... |
Line 277... |
276 |
throw new IllegalStateException("Duplicate invoice number : " + invoice);
|
277 |
throw new IllegalStateException("Duplicate invoice number : " + invoice);
|
277 |
final SQLRowAccessor mandate = invoice.getForeign("ID_MODE_REGLEMENT").getForeign("ID_SEPA_MANDATE");
|
278 |
final SQLRowAccessor mandate = invoice.getForeign("ID_MODE_REGLEMENT").getForeign("ID_SEPA_MANDATE");
|
278 |
if (!mandate.getBoolean("ACTIVE"))
|
279 |
if (!mandate.getBoolean("ACTIVE"))
|
279 |
throw new IllegalStateException("Inactive mandate for " + invoice);
|
280 |
throw new IllegalStateException("Inactive mandate for " + invoice);
|
280 |
// needed otherwise would have to update seqType while generating
|
281 |
// needed otherwise would have to update seqType while generating
|
- |
|
282 |
// MAYBE sum all invoices for a single mandate, but which date to choose ?
|
281 |
if (!this.invoiceMandates.add(mandate.getString("MandateIdentification")))
|
283 |
if (!this.invoiceMandates.add(mandate.getString("MandateIdentification")))
|
282 |
return IgnoreReason.DUPLICATE_MANDATE;
|
284 |
return IgnoreReason.DUPLICATE_MANDATE;
|
283 |
|
285 |
|
284 |
this.lockedInvoicesIDs.add(invoice.getIDNumber());
|
286 |
this.lockedInvoicesIDs.add(invoice.getIDNumber());
|
285 |
ListMap<String, InvoiceElem> bySeqType = this.map.get(dueDate);
|
287 |
ListMap<String, InvoiceElem> bySeqType = this.map.get(dueDate);
|
Line 403... |
Line 405... |
403 |
|
405 |
|
404 |
// find and lock invoices with TYPE_REGLEMENT direct debit and no message
|
406 |
// find and lock invoices with TYPE_REGLEMENT direct debit and no message
|
405 |
final SQLRowValues invoiceVals = new SQLRowValues(invoiceT);
|
407 |
final SQLRowValues invoiceVals = new SQLRowValues(invoiceT);
|
406 |
invoiceVals.putRowValues("ID_CLIENT").putNulls("NOM", "BIC", "IBAN");
|
408 |
invoiceVals.putRowValues("ID_CLIENT").putNulls("NOM", "BIC", "IBAN");
|
407 |
invoiceVals.putRowValues("ID_MODE_REGLEMENT").putNulls("AJOURS", "LENJOUR").putRowValues("ID_SEPA_MANDATE").setAllToNull();
|
409 |
invoiceVals.putRowValues("ID_MODE_REGLEMENT").putNulls("AJOURS", "LENJOUR").putRowValues("ID_SEPA_MANDATE").setAllToNull();
|
408 |
invoiceVals.putNulls("NET_A_PAYER", "DATE", "NUMERO");
|
410 |
invoiceVals.putNulls("NET_A_PAYER", "DATE", "NUMERO", "NOM");
|
409 |
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(invoiceVals);
|
411 |
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(invoiceVals);
|
410 |
fetcher.setReturnedRowsUnmodifiable(true);
|
412 |
fetcher.setReturnedRowsUnmodifiable(true);
|
411 |
// required for locking rows and to make sure that there's a SEPA Mandate
|
413 |
// required for locking rows and to make sure that there's a SEPA Mandate
|
412 |
fetcher.setFullOnly(true);
|
414 |
fetcher.setFullOnly(true);
|
413 |
fetcher.appendSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
|
415 |
fetcher.appendSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
|
Line 620... |
Line 622... |
620 |
res.addContent(new Element("Dbtr", painNS).addContent(elemCreator.createWithNonEmptyText("Nm", clientRow, "NOM")));
|
622 |
res.addContent(new Element("Dbtr", painNS).addContent(elemCreator.createWithNonEmptyText("Nm", clientRow, "NOM")));
|
621 |
res.addContent(new Element("DbtrAcct", painNS).addContent(new Element("Id", painNS).addContent(elemCreator.createWithNonEmptyText("IBAN", clientRow, "IBAN"))));
|
623 |
res.addContent(new Element("DbtrAcct", painNS).addContent(new Element("Id", painNS).addContent(elemCreator.createWithNonEmptyText("IBAN", clientRow, "IBAN"))));
|
622 |
|
624 |
|
623 |
res.addContent(new Element("Purp", painNS).addContent(new Element("Cd", painNS).setText("OTHR")));
|
625 |
res.addContent(new Element("Purp", painNS).addContent(new Element("Cd", painNS).setText("OTHR")));
|
624 |
|
626 |
|
625 |
// TODO <RmtInf><Ustrd>ligne de facture avec n° d'abonnement et indice de paiement.
|
627 |
final String info = (invoice.getString("NUMERO") + ' ' + invoice.getString("NOM")).trim();
|
- |
|
628 |
if (!info.isEmpty())
|
- |
|
629 |
res.addContent(new Element("RmtInf", painNS).addContent(elemCreator.create("Ustrd").setText(elemCreator.shortenText(info, 140))));
|
626 |
|
630 |
|
627 |
return res;
|
631 |
return res;
|
628 |
}
|
632 |
}
|
629 |
|
633 |
|
630 |
static public final class MissingInfoException extends Exception {
|
634 |
static public final class MissingInfoException extends Exception {
|
Line 640... |
Line 644... |
640 |
return this.label;
|
644 |
return this.label;
|
641 |
}
|
645 |
}
|
642 |
}
|
646 |
}
|
643 |
|
647 |
|
644 |
static private final class ElementCreator {
|
648 |
static private final class ElementCreator {
|
- |
|
649 |
static private final String TRUNCATED_SUFFIX = "...";
|
- |
|
650 |
static private final int TRUNCATED_SUFFIX_LENGTH = TRUNCATED_SUFFIX.length();
|
645 |
private final Namespace painNS;
|
651 |
private final Namespace painNS;
|
646 |
private final SQLFieldTranslator fieldTrans;
|
652 |
private final SQLFieldTranslator fieldTrans;
|
647 |
|
653 |
|
648 |
protected ElementCreator(Namespace painNS, final SQLFieldTranslator fieldTrans) {
|
654 |
protected ElementCreator(Namespace painNS, final SQLFieldTranslator fieldTrans) {
|
649 |
super();
|
655 |
super();
|
Line 666... |
Line 672... |
666 |
protected Element createWithNonEmptyText(final String elemName, final String text, final String label) throws MissingInfoException {
|
672 |
protected Element createWithNonEmptyText(final String elemName, final String text, final String label) throws MissingInfoException {
|
667 |
if (StringUtils.isEmpty(text))
|
673 |
if (StringUtils.isEmpty(text))
|
668 |
throw new MissingInfoException(label == null ? elemName : label);
|
674 |
throw new MissingInfoException(label == null ? elemName : label);
|
669 |
return create(elemName).setText(text);
|
675 |
return create(elemName).setText(text);
|
670 |
}
|
676 |
}
|
- |
|
677 |
|
- |
|
678 |
protected String shortenText(final String text, final int maxLength) {
|
- |
|
679 |
if (maxLength <= TRUNCATED_SUFFIX_LENGTH || text.length() <= maxLength)
|
- |
|
680 |
return text;
|
- |
|
681 |
return text.substring(0, maxLength - TRUNCATED_SUFFIX_LENGTH) + TRUNCATED_SUFFIX;
|
- |
|
682 |
}
|
671 |
}
|
683 |
}
|
672 |
|
684 |
|
673 |
}
|
685 |
}
|