kreditorenverwaltung mit multi IBAN
This commit is contained in:
parent
90beebd5c0
commit
d7a570ac3e
4 changed files with 515 additions and 307 deletions
|
|
@ -1,7 +1,13 @@
|
|||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class CargosoftController implements Serializable {
|
|||
searchResult.add(new KreditorSearchEntry(cdtrNo, display, buildJsonData(cdtr,
|
||||
cdtr.getItemValueString("cdtr.iban"), cdtr.getItemValueString("cdtr.bic"))));
|
||||
// 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()) {
|
||||
// Dublette mit alternativer IBAN erzeugen
|
||||
display = cdtrNo + " - " + cdtr.getItemValueString("_VENDOR_Name");
|
||||
|
|
@ -187,6 +187,7 @@ public class CargosoftController implements Serializable {
|
|||
add("iban", cdtr.getItemValueString("cdtr.iban")). //
|
||||
add("bic", cdtr.getItemValueString("cdtr.bic")). //
|
||||
// add ibans für kreditoren verwaltung
|
||||
add("iban2", cdtr.getItemValueString("cdtr.iban2")). //
|
||||
add("iban3", cdtr.getItemValueString("cdtr.iban3")). //
|
||||
add("iban4", cdtr.getItemValueString("cdtr.iban4")). //
|
||||
add("bic2", cdtr.getItemValueString("cdtr.bic2")). //
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.engine.plugins.AbstractPlugin;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
|
|
@ -35,342 +37,397 @@ import org.imixs.workflow.exceptions.QueryException;
|
|||
*/
|
||||
public class InvoicePlugin extends AbstractPlugin {
|
||||
|
||||
public static final int TASK_ERFASSUNG = 5001;
|
||||
public static final int TASK_SACHPRUEFUNG = 5200;
|
||||
public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
|
||||
public static final int EVENT_FREIGEBEN = 20;
|
||||
public static final String ITEM_INVOICE_PERIOD = "invoice.period";
|
||||
public static final int TASK_ERFASSUNG = 5001;
|
||||
public static final int TASK_SACHPRUEFUNG = 5200;
|
||||
public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
|
||||
public static final int EVENT_FREIGEBEN = 20;
|
||||
public static final String ITEM_INVOICE_PERIOD = "invoice.period";
|
||||
|
||||
public static final String CHILD_ITEM_PROPERTY = "_ChildItems";
|
||||
public static final String ERROR_MISSING_DATA = "MISSING_DATA";
|
||||
public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
|
||||
public static final String CHILD_ITEM_PROPERTY = "_ChildItems";
|
||||
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_NEW_IBANBIC = "NEW_IBANBIC";
|
||||
|
||||
// XX-YYY-####-###
|
||||
public static final String REGEX_POSNUMER = "([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})";
|
||||
// XX-YYY-####-###
|
||||
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());
|
||||
|
||||
/**
|
||||
* Test childworkitems for empty lines
|
||||
*
|
||||
* @throws PluginException - if data is missing
|
||||
*
|
||||
**/
|
||||
@Override
|
||||
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
||||
@Inject
|
||||
KreditorService kreditorService;
|
||||
|
||||
updateImg(workitem);
|
||||
|
||||
// skip if validaten tag is required=false
|
||||
ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
|
||||
if (evalItemCollection != null) {
|
||||
// evaluate the validation rules...
|
||||
if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
|
||||
return workitem;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Test childworkitems for empty lines
|
||||
*
|
||||
* @throws PluginException - if data is missing
|
||||
*
|
||||
**/
|
||||
@Override
|
||||
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
||||
|
||||
boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
|
||||
boolean isCargoRechnung = ("Rechnungseingang".equals(workitem.getWorkflowGroup()));
|
||||
updateImg(workitem);
|
||||
|
||||
// Payment.type muss immer eingetragne werden!
|
||||
if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
|
||||
if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
|
||||
// throw a plugin exception!
|
||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
||||
"Eingabefehler - Bitte wählen Sie eine Zahlungsart aus!");
|
||||
}
|
||||
// doppelte Rechnungsnummer prüfen
|
||||
if (workitem.getTaskID() == TASK_ERFASSUNG) {
|
||||
validateInvoiceNumber(workitem);
|
||||
}
|
||||
// skip if validaten tag is required=false
|
||||
ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
|
||||
if (evalItemCollection != null) {
|
||||
// evaluate the validation rules...
|
||||
if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
|
||||
return workitem;
|
||||
}
|
||||
}
|
||||
|
||||
if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
|
||||
|| workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||
&& 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
|
||||
boolean isCargoRechnung = ("Rechnungseingang".equals(workitem.getWorkflowGroup()));
|
||||
|
||||
// die prüfung der positionsnummern und Category erfolgt nur im Status
|
||||
// Sachprüfung (5200) und nur beim Freigeben (20)!
|
||||
if (isCargoRechnung
|
||||
&& ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||
&& 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!");
|
||||
}
|
||||
// Payment.type muss immer eingetragne werden!
|
||||
if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
|
||||
if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
|
||||
// throw a plugin exception!
|
||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
||||
"Eingabefehler - Bitte wählen Sie eine Zahlungsart aus!");
|
||||
}
|
||||
// doppelte Rechnungsnummer prüfen
|
||||
if (workitem.getTaskID() == TASK_ERFASSUNG) {
|
||||
validateInvoiceNumber(workitem);
|
||||
|
||||
// validate pos for regex pattern 'XX-YYY-####-###'
|
||||
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!");
|
||||
}
|
||||
checkIBANNumber(workitem);
|
||||
|
||||
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()) {
|
||||
// throw a plugin exception - because name is missing!
|
||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
||||
"Eingabefehler - Die Steuer in Zeile " + posItem.getItemValueString("numpos")
|
||||
+ " muss ausgefüllt sein!");
|
||||
}
|
||||
if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
|
||||
|| workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||
&& 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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!");
|
||||
}
|
||||
// die prüfung der positionsnummern und Category erfolgt nur im Status
|
||||
// Sachprüfung (5200) und nur beim Freigeben (20)!
|
||||
if (isCargoRechnung
|
||||
&& ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||
&& 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
|
||||
if (!posItem.getItemValueString(ITEM_INVOICE_PERIOD).trim().isEmpty()) {
|
||||
validateBuchungsperiode(posItem.getItemValueString(ITEM_INVOICE_PERIOD));
|
||||
// validate pos for regex pattern 'XX-YYY-####-###'
|
||||
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!");
|
||||
}
|
||||
|
||||
// Ergaenzung 18.05.2021:
|
||||
// es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
|
||||
// das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
|
||||
// fall sein.
|
||||
// Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
|
||||
// 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.getItemValueString("tax").trim().isEmpty()) {
|
||||
// throw a plugin exception - because name is missing!
|
||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
||||
"Eingabefehler - Die Steuer in Zeile " + posItem.getItemValueString("numpos")
|
||||
+ " muss ausgefüllt sein!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
if (!period.isEmpty()) {
|
||||
LocalDate localDate = LocalDate.now();
|
||||
int year = localDate.getYear();
|
||||
// build regex....
|
||||
String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
|
||||
// Ergaenzung 18.05.2021:
|
||||
// es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
|
||||
// das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
|
||||
// fall sein.
|
||||
// Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
|
||||
// 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return workitem;
|
||||
}
|
||||
|
||||
String invoiceNumber = workitem.getItemValueString("invoice.number");
|
||||
// strip
|
||||
String invoiceNumberStripped=invoiceNumber.replace(" ","");
|
||||
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
|
||||
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
|
||||
/**
|
||||
* Hilfsroutine die das _img item aktualisiert.
|
||||
*/
|
||||
private void updateImg(ItemCollection workitem) {
|
||||
|
||||
// wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
|
||||
if (invoiceNumber.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 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\">";
|
||||
|
||||
// rechnungseingang only workitems...
|
||||
// Change 11.4.22 - we have now an additional field: invoice.number.stripped
|
||||
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
|
||||
+ workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped + "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
|
||||
try {
|
||||
int result = this.getWorkflowService().getDocumentService().count(query, 1);
|
||||
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 {
|
||||
}
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
// wenn keine Nummer eingegeben wurde gehts weiter!
|
||||
if (crdtrNumber.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// buchungsperionde nur prüfen wenn noch nicht archiviert
|
||||
if (!period.isEmpty()) {
|
||||
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...
|
||||
// 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.");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// update cargosoft crediotr name
|
||||
ItemCollection cargo = result.get(0);
|
||||
workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
|
||||
}
|
||||
} catch (QueryException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
String invoiceNumberStripped = invoiceNumber.replace(" ", "");
|
||||
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
|
||||
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
|
||||
|
||||
/**
|
||||
* 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>();
|
||||
// wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
|
||||
if (invoiceNumber.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// rechnungseingang only workitems...
|
||||
// Change 11.4.22 - we have now an additional field: invoice.number.stripped
|
||||
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
|
||||
+ workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
|
||||
+ "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
|
||||
try {
|
||||
int result = this.getWorkflowService().getDocumentService().count(query, 1);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue