kreditorenverwaltung mit multi IBAN

This commit is contained in:
Ralph Soika 2022-06-07 16:35:43 +02:00
parent 90beebd5c0
commit d7a570ac3e
4 changed files with 515 additions and 307 deletions

View file

@ -1,7 +1,13 @@
# Versionen # Versionen
### 1.2.7 (Development)
### 1.2.6 (Development) Erweiterte Kreditoren Verwaltung. Es können bis zu 4 IBAN/BIC Kombinationen pro Kreditor erfasst werden.
Wenn vom Benutezr bei der Rechnungserfassugn eine Kombination eingegeben wird die noch nicht gespeichert war,
wird diese aufgenomen und die anderen rutschen nach unten.
### 1.2.6
Übernahme von IBAN BIC aus kreditoren verwaltung Übernahme von IBAN BIC aus kreditoren verwaltung

View file

@ -121,7 +121,7 @@ public class CargosoftController implements Serializable {
searchResult.add(new KreditorSearchEntry(cdtrNo, display, buildJsonData(cdtr, searchResult.add(new KreditorSearchEntry(cdtrNo, display, buildJsonData(cdtr,
cdtr.getItemValueString("cdtr.iban"), cdtr.getItemValueString("cdtr.bic")))); cdtr.getItemValueString("cdtr.iban"), cdtr.getItemValueString("cdtr.bic"))));
// haben wir noch weitere IBAN/BIC kombis? // haben wir noch weitere IBAN/BIC kombis?
for (int j = 1; j < 4; j++) { for (int j = 1; j <=4 ; j++) {
if (!cdtr.getItemValueString("cdtr.iban" + j).isEmpty()) { if (!cdtr.getItemValueString("cdtr.iban" + j).isEmpty()) {
// Dublette mit alternativer IBAN erzeugen // Dublette mit alternativer IBAN erzeugen
display = cdtrNo + " - " + cdtr.getItemValueString("_VENDOR_Name"); display = cdtrNo + " - " + cdtr.getItemValueString("_VENDOR_Name");
@ -187,6 +187,7 @@ public class CargosoftController implements Serializable {
add("iban", cdtr.getItemValueString("cdtr.iban")). // add("iban", cdtr.getItemValueString("cdtr.iban")). //
add("bic", cdtr.getItemValueString("cdtr.bic")). // add("bic", cdtr.getItemValueString("cdtr.bic")). //
// add ibans für kreditoren verwaltung // add ibans für kreditoren verwaltung
add("iban2", cdtr.getItemValueString("cdtr.iban2")). //
add("iban3", cdtr.getItemValueString("cdtr.iban3")). // add("iban3", cdtr.getItemValueString("cdtr.iban3")). //
add("iban4", cdtr.getItemValueString("cdtr.iban4")). // add("iban4", cdtr.getItemValueString("cdtr.iban4")). //
add("bic2", cdtr.getItemValueString("cdtr.bic2")). // add("bic2", cdtr.getItemValueString("cdtr.bic2")). //

View file

@ -6,6 +6,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject;
import org.imixs.workflow.ItemCollection; import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.plugins.AbstractPlugin; import org.imixs.workflow.engine.plugins.AbstractPlugin;
import org.imixs.workflow.exceptions.PluginException; import org.imixs.workflow.exceptions.PluginException;
@ -35,342 +37,397 @@ import org.imixs.workflow.exceptions.QueryException;
*/ */
public class InvoicePlugin extends AbstractPlugin { public class InvoicePlugin extends AbstractPlugin {
public static final int TASK_ERFASSUNG = 5001; public static final int TASK_ERFASSUNG = 5001;
public static final int TASK_SACHPRUEFUNG = 5200; public static final int TASK_SACHPRUEFUNG = 5200;
public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210; public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
public static final int EVENT_FREIGEBEN = 20; public static final int EVENT_FREIGEBEN = 20;
public static final String ITEM_INVOICE_PERIOD = "invoice.period"; public static final String ITEM_INVOICE_PERIOD = "invoice.period";
public static final String CHILD_ITEM_PROPERTY = "_ChildItems"; public static final String CHILD_ITEM_PROPERTY = "_ChildItems";
public static final String ERROR_MISSING_DATA = "MISSING_DATA"; public static final String ERROR_MISSING_DATA = "MISSING_DATA";
public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER"; public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
public static final String ERROR_NEW_IBANBIC = "NEW_IBANBIC";
// XX-YYY-####-### // XX-YYY-####-###
public static final String REGEX_POSNUMER = "([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})"; public static final String REGEX_POSNUMER = "([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})";
private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName()); private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName());
/** @Inject
* Test childworkitems for empty lines KreditorService kreditorService;
*
* @throws PluginException - if data is missing
*
**/
@Override
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
updateImg(workitem); /**
* Test childworkitems for empty lines
// skip if validaten tag is required=false *
ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem); * @throws PluginException - if data is missing
if (evalItemCollection != null) { *
// evaluate the validation rules... **/
if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) { @Override
return workitem; public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
}
}
boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult"))); updateImg(workitem);
boolean isCargoRechnung = ("Rechnungseingang".equals(workitem.getWorkflowGroup()));
// Payment.type muss immer eingetragne werden! // skip if validaten tag is required=false
if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) { ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
if (workitem.getItemValueString("payment.type").trim().isEmpty()) { if (evalItemCollection != null) {
// throw a plugin exception! // evaluate the validation rules...
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
"Eingabefehler - Bitte wählen Sie eine Zahlungsart aus!"); return workitem;
} }
// doppelte Rechnungsnummer prüfen }
if (workitem.getTaskID() == TASK_ERFASSUNG) {
validateInvoiceNumber(workitem);
}
if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
|| workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION) boolean isCargoRechnung = ("Rechnungseingang".equals(workitem.getWorkflowGroup()));
&& workitem.getEventID() == EVENT_FREIGEBEN)) {
// Buchungsperiode auf plausi prüfen
if (isCargoRechnung && "workitem".equals(workitem.getType())) {
validateBuchungsperiode(workitem.getItemValueString(ITEM_INVOICE_PERIOD));
}
// Cargosoft Kreditorennnummer prüfen
if (isCargoRechnung) {
validateCargosoftCdtrNumber(workitem);
}
}
}
// die prüfung der positionsnummern und Category erfolgt nur im Status // Payment.type muss immer eingetragne werden!
// Sachprüfung (5200) und nur beim Freigeben (20)! if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
if (isCargoRechnung if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
&& ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION) // throw a plugin exception!
&& workitem.getEventID() == EVENT_FREIGEBEN)) { throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
List<ItemCollection> childs = explodeChildList(workitem); "Eingabefehler - Bitte wählen Sie eine Zahlungsart aus!");
for (ItemCollection posItem : childs) { }
if (posItem.getItemValueString("name").trim().isEmpty()) { // doppelte Rechnungsnummer prüfen
// throw a plugin exception - because name is missing! if (workitem.getTaskID() == TASK_ERFASSUNG) {
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, validateInvoiceNumber(workitem);
"Eingabefehler - Die Positionsnummer in Zeile " + posItem.getItemValueString("numpos")
+ " muss ausgefüllt sein!");
}
// validate pos for regex pattern 'XX-YYY-####-###' checkIBANNumber(workitem);
if (!posItem.getItemValueString("name").matches(REGEX_POSNUMER)) {
// throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Die Positionsnummer in Zeile " + posItem.getItemValueString("numpos")
+ " muss im Format 'XX-YYY-####-###' eingegeben werden!");
}
if (posItem.getItemValueString("category").trim().isEmpty()) { }
// throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
+ " muss ausgefüllt sein!");
}
if (posItem.getItemValueString("tax").trim().isEmpty()) { if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
// throw a plugin exception - because name is missing! || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, && workitem.getEventID() == EVENT_FREIGEBEN)) {
"Eingabefehler - Die Steuer in Zeile " + posItem.getItemValueString("numpos") // Buchungsperiode auf plausi prüfen
+ " muss ausgefüllt sein!"); if (isCargoRechnung && "workitem".equals(workitem.getType())) {
} validateBuchungsperiode(workitem.getItemValueString(ITEM_INVOICE_PERIOD));
}
// Cargosoft Kreditorennnummer prüfen
if (isCargoRechnung) {
validateCargosoftCdtrNumber(workitem);
}
}
}
if (posItem.getItemValueFloat("amount") == 0) { // die prüfung der positionsnummern und Category erfolgt nur im Status
// throw a plugin exception - because name is missing! // Sachprüfung (5200) und nur beim Freigeben (20)!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, if (isCargoRechnung
"Eingabefehler - Der Nettobetrag in Zeile " + posItem.getItemValueString("numpos") && ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
+ " darf nicht 0 sein!"); && workitem.getEventID() == EVENT_FREIGEBEN)) {
} List<ItemCollection> childs = explodeChildList(workitem);
for (ItemCollection posItem : childs) {
if (posItem.getItemValueString("name").trim().isEmpty()) {
// throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Die Positionsnummer in Zeile " + posItem.getItemValueString("numpos")
+ " muss ausgefüllt sein!");
}
// Buchunsperiode // validate pos for regex pattern 'XX-YYY-####-###'
if (!posItem.getItemValueString(ITEM_INVOICE_PERIOD).trim().isEmpty()) { if (!posItem.getItemValueString("name").matches(REGEX_POSNUMER)) {
validateBuchungsperiode(posItem.getItemValueString(ITEM_INVOICE_PERIOD)); // throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Die Positionsnummer in Zeile " + posItem.getItemValueString("numpos")
+ " muss im Format 'XX-YYY-####-###' eingegeben werden!");
}
} if (posItem.getItemValueString("category").trim().isEmpty()) {
} // throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
+ " muss ausgefüllt sein!");
}
// Ergaenzung 18.05.2021: if (posItem.getItemValueString("tax").trim().isEmpty()) {
// es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so // throw a plugin exception - because name is missing!
// das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
// fall sein. "Eingabefehler - Die Steuer in Zeile " + posItem.getItemValueString("numpos")
// Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder + " muss ausgefüllt sein!");
// die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine }
// Fehlermeldung für den Anwendere
if (isCargoRechnung && childs.size() > 0) {
String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
boolean buchungsperiodenValid = false;
for (ItemCollection posItem : childs) {
String posBuchungsperiode = posItem.getItemValueString("invoice.period");
if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
// alles fein!
buchungsperiodenValid = true;
}
}
if (buchungsperiodenValid == false) {
// fehlerhafte Buchungsperioden.
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Bitte überprüfen Sie die Hauptbuchungsperiode mit den Buchungsperioden der einzelnen Positionen!");
}
}
} if (posItem.getItemValueFloat("amount") == 0) {
// throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Der Nettobetrag in Zeile " + posItem.getItemValueString("numpos")
+ " darf nicht 0 sein!");
}
return workitem; // Buchunsperiode
} if (!posItem.getItemValueString(ITEM_INVOICE_PERIOD).trim().isEmpty()) {
validateBuchungsperiode(posItem.getItemValueString(ITEM_INVOICE_PERIOD));
/** }
* Hilfsroutine die das _img item aktualisiert. }
*/
private void updateImg(ItemCollection workitem) {
// Update _img icon list
String img=workitem.getItemValueString("_img");
// 031=ablehnen
// 100=sofortüberweichung
// 074=mahnen
// sofortüberweisung
if (workitem.getEventID()==96 && !img.contains("100.png")) {
img=img+"<img title='Sofortüberweisung' src=\"/layout/icons/icon100.png\">";
}
// mahnen
if (workitem.getEventID()==95 && !img.contains("103.png")) {
img=img+"<img title='Mahnen' src=\"/layout/icons/icon103.png\">";
}
// ablehnen
if (workitem.getTaskID()==5100 && workitem.getEventID()==90 && !img.contains("028.png")) {
img=img+"<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
}
if (workitem.getTaskID()==5200 && workitem.getEventID()==90 && !img.contains("028.png")) {
img=img+"<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
}
workitem.setItemValue("_img", img);
/*
for (String entry: eventLog) {
// sofortüberweisung
if (entry.contains(".96") && !img.contains("100.png")) {
img=img+"<img src=\"/layout/icons/icon100.png\">";
}
// mahnen
if (entry.contains(".95") && !img.contains("074.png")) {
img=img+"<img src=\"/layout/icons/icon074.png\">";
}
// ablehnen
if (entry.contains("5100.90") && !img.contains("031.png")) {
img=img+"<img src=\"/layout/icons/icon031.png\">";
}
}
workitem.setItemValue("_img", img);
*/
}
/**
* Diese Method prüft die Buchungsperiode auf Plausibilität
*
* YYYY(+1)01-12
*
* z.b. 202110 oder 202107 oder 202201
*
* @param workitem
* @throws PluginException
*/
private void validateBuchungsperiode(String period) throws PluginException {
// buchungsperionde nur prüfen wenn noch nicht archiviert // Ergaenzung 18.05.2021:
if (!period.isEmpty()) { // es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
LocalDate localDate = LocalDate.now(); // das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
int year = localDate.getYear(); // fall sein.
// build regex.... // Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])"; // die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine
// Fehlermeldung für den Anwendere
if (isCargoRechnung && childs.size() > 0) {
String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
boolean buchungsperiodenValid = false;
for (ItemCollection posItem : childs) {
String posBuchungsperiode = posItem.getItemValueString("invoice.period");
if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
// alles fein!
buchungsperiodenValid = true;
}
}
if (buchungsperiodenValid == false) {
// fehlerhafte Buchungsperioden.
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Bitte überprüfen Sie die Hauptbuchungsperiode mit den Buchungsperioden der einzelnen Positionen!");
}
}
if (!period.matches(regex)) { }
// throw a plugin exception - because name is missing!
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Eingabefehler - Bitte geben Sie eine gültige Buchungsperiode ein! Prüfen Sie auch die Spalte BP in der Positionstabelle.");
}
}
}
/** return workitem;
* Diese Method prüft ob die "invoice.number" bereits einmal im }
* Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
* ausgelöst.
* <p>
* Query Example:
* <p>
* <code>NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"</code>
*
* <p>
* in case a duplicate invoice was detected the item invoice.number.duplicate is
* filled. This item is used for a conditional event. The case is displayed as a
* warning in the form.
*
* @throws PluginException
* @throws QueryException
*
*/
private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
String invoiceNumber = workitem.getItemValueString("invoice.number"); /**
// strip * Hilfsroutine die das _img item aktualisiert.
String invoiceNumberStripped=invoiceNumber.replace(" ",""); */
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped); private void updateImg(ItemCollection workitem) {
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
// wenn keine Rechnungsnummer eingegeben wurde gehts weiter! // Update _img icon list
if (invoiceNumber.isEmpty()) { String img = workitem.getItemValueString("_img");
return; // 031=ablehnen
} // 100=sofortüberweichung
// 074=mahnen
// sofortüberweisung
if (workitem.getEventID() == 96 && !img.contains("100.png")) {
img = img + "<img title='Sofortüberweisung' src=\"/layout/icons/icon100.png\">";
}
// mahnen
if (workitem.getEventID() == 95 && !img.contains("103.png")) {
img = img + "<img title='Mahnen' src=\"/layout/icons/icon103.png\">";
// rechnungseingang only workitems... }
// Change 11.4.22 - we have now an additional field: invoice.number.stripped // ablehnen
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\"" if (workitem.getTaskID() == 5100 && workitem.getEventID() == 90 && !img.contains("028.png")) {
+ workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped + "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))"; img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
try { }
int result = this.getWorkflowService().getDocumentService().count(query, 1); if (workitem.getTaskID() == 5200 && workitem.getEventID() == 90 && !img.contains("028.png")) {
if (result > 0) { img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
// wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung }
// weiter workitem.setItemValue("_img", img);
if (!invoiceNumberDuplicate.isEmpty()) {
logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
} else {
// set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und /*
// der Vorgang nicht weitergeleitet * for (String entry: eventLog) { // sofortüberweisung if (entry.contains(".96")
workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber); * && !img.contains("100.png")) {
throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER, * img=img+"<img src=\"/layout/icons/icon100.png\">"; } // mahnen if
"ACHTUNG: Die Rechnungsnummer wurde bereits gebucht. Bitte prüfen Sie den Beleg. Sollte die Belegnummer korrekt sein, wiederholen Sie die Aktion."); * (entry.contains(".95") && !img.contains("074.png")) {
} * img=img+"<img src=\"/layout/icons/icon074.png\">"; } // ablehnen if
} else { * (entry.contains("5100.90") && !img.contains("031.png")) {
// clear ! * img=img+"<img src=\"/layout/icons/icon031.png\">"; } }
workitem.appendItemValue("invoice.number.duplicate.history", * workitem.setItemValue("_img", img);
workitem.getItemValueString("invoice.number.duplicate")); */
workitem.replaceItemValue("invoice.number.duplicate", ""); }
}
} catch (QueryException e) {
throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
}
}
/** /**
* Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft * Diese Method prüft die Buchungsperiode auf Plausibilität
* Import Datei übereinstimmt. *
* * YYYY(+1)01-12
* @param workitem *
* @throws PluginException * z.b. 202110 oder 202107 oder 202201
*/ *
private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException { * @param workitem
String crdtrNumber = workitem.getItemValueString("cdtr.number"); * @throws PluginException
*/
private void validateBuchungsperiode(String period) throws PluginException {
// wenn keine Nummer eingegeben wurde gehts weiter! // buchungsperionde nur prüfen wenn noch nicht archiviert
if (crdtrNumber.isEmpty()) { if (!period.isEmpty()) {
return; LocalDate localDate = LocalDate.now();
} int year = localDate.getYear();
// build regex....
String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
// search creditor number in cargosoft... if (!period.matches(regex)) {
// die cargosoft Kreditornummer beginnt seltsamerweise mit einem K..... // throw a plugin exception - because name is missing!
try { throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")"; "Eingabefehler - Bitte geben Sie eine gültige Buchungsperiode ein! Prüfen Sie auch die Spalte BP in der Positionstabelle.");
List<ItemCollection> result = this.getWorkflowService().getDocumentService().find(query, 1, 0); }
if (result == null || result.size() == 0) { }
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, }
"Die Kreditorennummer ist nicht gültig.");
} else { /**
// update cargosoft crediotr name * Diese Method prüft ob die "invoice.number" bereits einmal im
ItemCollection cargo = result.get(0); * Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name")); * ausgelöst.
} * <p>
} catch (QueryException e) { * Query Example:
e.printStackTrace(); * <p>
} * <code>NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"</code>
*
* <p>
* in case a duplicate invoice was detected the item invoice.number.duplicate is
* filled. This item is used for a conditional event. The case is displayed as a
* warning in the form.
*
* @throws PluginException
* @throws QueryException
*
*/
private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
} String invoiceNumber = workitem.getItemValueString("invoice.number");
// strip
String invoiceNumberStripped = invoiceNumber.replace(" ", "");
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
/** // wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
* converts the Map List of a workitem into a List of ItemCollectons if (invoiceNumber.isEmpty()) {
*/ return;
@SuppressWarnings({ "rawtypes", "unchecked" }) }
protected static List<ItemCollection> explodeChildList(ItemCollection workitem) {
// convert current list of childItems into ItemCollection elements
ArrayList<ItemCollection> childItems = new ArrayList<ItemCollection>();
List<Object> mapOrderItems = workitem.getItemValue(CHILD_ITEM_PROPERTY); // rechnungseingang only workitems...
for (Object mapOderItem : mapOrderItems) { // Change 11.4.22 - we have now an additional field: invoice.number.stripped
if (mapOderItem instanceof Map) { String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
ItemCollection itemCol = new ItemCollection((Map) mapOderItem); + workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
childItems.add(itemCol); + "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
} try {
} int result = this.getWorkflowService().getDocumentService().count(query, 1);
return childItems; if (result > 0) {
} // wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung
// weiter
if (!invoiceNumberDuplicate.isEmpty()) {
logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
} else {
// set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und
// der Vorgang nicht weitergeleitet
workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber);
throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER,
"ACHTUNG: Die Rechnungsnummer wurde bereits gebucht. Bitte prüfen Sie den Beleg. Sollte die Belegnummer korrekt sein, wiederholen Sie die Aktion.");
}
} else {
// clear !
workitem.appendItemValue("invoice.number.duplicate.history",
workitem.getItemValueString("invoice.number.duplicate"));
workitem.replaceItemValue("invoice.number.duplicate", "");
}
} catch (QueryException e) {
throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
}
}
/**
* Diese Method prüft ob die eingegebene IBAN nummer bereits in dem ausgewälten
* Kreditor bekannt ist. Fallst nicht wird diese schnell mal in den Kreditoren
* Datensatz übertragen. Dadurch muss man nicht extra die Kreditoren Verwaltung
* aufrufen. Es ist ein art selbst-lernendes System.
* <p>
* Die Mehtode ruft eine Plugin Exception aus um den User zu fragen ob er das
* möchte.
*
* @throws PluginException
* @throws QueryException
*
*/
private void checkIBANNumber(ItemCollection workitem) throws PluginException {
String cdtrNumber = workitem.getItemValueString("cdtr.number");
String iban = workitem.getItemValueString("cdtr.iban");
String bic = workitem.getItemValueString("cdtr.bic");
String overtakeIBAN = workitem.getItemValueString("ibanbic.overtake");
if (cdtrNumber.isEmpty() || iban.isEmpty() || bic.isEmpty()) {
// no op
return;
}
// wenn bereits eine Überneahme angedroht wurde dann übernehemen!
if (!overtakeIBAN.isEmpty()) {
kreditorService.addNewIBANBIC(cdtrNumber, iban, bic);
workitem.setItemValue("ibanbic.overtake","");
return;
}
// search the kreditor
ItemCollection cdtr = kreditorService.findCreditor(cdtrNumber);
if (cdtr != null) {
// Prüfen ob wir die IBAN schon kennen
if (iban.equals(cdtr.getItemValueString("cdtr.iban")) && bic.equals(cdtr.getItemValueString("cdtr.bic"))) {
return;
}
if (iban.equals(cdtr.getItemValueString("cdtr.iban2"))
&& bic.equals(cdtr.getItemValueString("cdtr.bic2"))) {
return;
}
if (iban.equals(cdtr.getItemValueString("cdtr.iban3"))
&& bic.equals(cdtr.getItemValueString("cdtr.bic3"))) {
return;
}
if (iban.equals(cdtr.getItemValueString("cdtr.iban4"))
&& bic.equals(cdtr.getItemValueString("cdtr.bic4"))) {
return;
}
// OK - scheinbar ist diese IBAN/BIC nicht bekannt. Also fragen wir mal nach....
workitem.setItemValue("ibanbic.overtake", iban + bic);
throw new PluginException(InvoicePlugin.class.getName(), ERROR_NEW_IBANBIC,
"Die von Ihnen erfasste IBAN/BIC ist noch nicht bekannt. Sollte die Eingabe korrekt sein, wiederholen Sie die Aktion.");
}
}
/**
* Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft
* Import Datei übereinstimmt.
*
* @param workitem
* @throws PluginException
*/
private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException {
String crdtrNumber = workitem.getItemValueString("cdtr.number");
// wenn keine Nummer eingegeben wurde gehts weiter!
if (crdtrNumber.isEmpty()) {
return;
}
// search creditor number in cargosoft...
// die cargosoft Kreditornummer beginnt seltsamerweise mit einem K.....
try {
String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")";
List<ItemCollection> result = this.getWorkflowService().getDocumentService().find(query, 1, 0);
if (result == null || result.size() == 0) {
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
"Die Kreditorennummer ist nicht gültig.");
} else {
// update cargosoft crediotr name
ItemCollection cargo = result.get(0);
workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
}
} catch (QueryException e) {
e.printStackTrace();
}
}
/**
* converts the Map List of a workitem into a List of ItemCollectons
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected static List<ItemCollection> explodeChildList(ItemCollection workitem) {
// convert current list of childItems into ItemCollection elements
ArrayList<ItemCollection> childItems = new ArrayList<ItemCollection>();
List<Object> mapOrderItems = workitem.getItemValue(CHILD_ITEM_PROPERTY);
for (Object mapOderItem : mapOrderItems) {
if (mapOderItem instanceof Map) {
ItemCollection itemCol = new ItemCollection((Map) mapOderItem);
childItems.add(itemCol);
}
}
return childItems;
}
} }

View file

@ -0,0 +1,144 @@
/*******************************************************************************
* Imixs Workflow
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
*
* Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
package com.alexanderlogistics;
import java.util.List;
import java.util.logging.Logger;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.RunAs;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
/**
* Der KreditorService wird verwendet um einen Kreditor zu finden oder neue
* IBAN/BIC kombinationen aufzunehmen.
*
* @author rsoika
*
*/
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@Singleton
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
public class KreditorService {
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(KreditorService.class.getName());
@EJB
DocumentService documentService;
/**
* sucht einen Kreditor
*
*
* @throws PluginException
*/
public ItemCollection findCreditor(String cdtrNumber) throws PluginException {
try {
String query = "(type:" + CargosoftController.TYPE_CARGOSOFTKREDITOR + ") AND (name:" + cdtrNumber + ")";
List<ItemCollection> result = documentService.find(query, 1, 0, "$modified", true);
if (result.size() > 0) {
return result.get(0);
}
} catch (QueryException e) {
throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
}
return null;
}
/**
* Diese Methode übertragt neue IBAN/BIC kombis in den kreditor
*
* @param cdtrNumber
* @param iban
* @param bic
* @throws PluginException
*/
public void addNewIBANBIC(String cdtrNumber, String iban, String bic) throws PluginException {
ItemCollection cdtr = findCreditor(cdtrNumber);
if (cdtr != null) {
// Wir rotieren die nummern nach unten
cdtr.setItemValue("cdtr.iban4", cdtr.getItemValue("cdtr.iban3"));
cdtr.setItemValue("cdtr.bic4", cdtr.getItemValue("cdtr.bic3"));
cdtr.setItemValue("cdtr.iban3", cdtr.getItemValue("cdtr.iban2"));
cdtr.setItemValue("cdtr.bic3", cdtr.getItemValue("cdtr.bic2"));
cdtr.setItemValue("cdtr.iban2", cdtr.getItemValue("cdtr.iban"));
cdtr.setItemValue("cdtr.bic2", cdtr.getItemValue("cdtr.bic"));
// clear slot 0
cdtr.setItemValue("cdtr.iban", "");
cdtr.setItemValue("cdtr.bic", "");
// nun können wir die neue IBAN/BIC in die erste frei park position legen
if (cdtr.getItemValueString("cdtr.iban").isEmpty()) {
cdtr.setItemValue("cdtr.iban", iban);
cdtr.setItemValue("cdtr.bic", bic);
documentService.save(cdtr);
return;
}
if (cdtr.getItemValueString("cdtr.iban2").isEmpty()) {
cdtr.setItemValue("cdtr.iban2", iban);
cdtr.setItemValue("cdtr.bic2", bic);
documentService.save(cdtr);
return;
}
if (cdtr.getItemValueString("cdtr.iban3").isEmpty()) {
cdtr.setItemValue("cdtr.iban3", iban);
cdtr.setItemValue("cdtr.bic3", bic);
documentService.save(cdtr);
return;
}
if (cdtr.getItemValueString("cdtr.iban4").isEmpty()) {
cdtr.setItemValue("cdtr.iban4", iban);
cdtr.setItemValue("cdtr.bic4", bic);
documentService.save(cdtr);
return;
}
}
}
}