394 lines
16 KiB
Java
394 lines
16 KiB
Java
/*
|
|
* Imixs-Workflow
|
|
*
|
|
* Copyright (C) 2001-2020 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:
|
|
* https://www.imixs.org
|
|
* https://github.com/imixs/imixs-workflow
|
|
*
|
|
* Contributors:
|
|
* Imixs Software Solutions GmbH - Project Management
|
|
* Ralph Soika - Software Developer
|
|
*/
|
|
|
|
package com.alexanderlogistics.xml;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.logging.Logger;
|
|
|
|
import org.imixs.archive.core.SnapshotService;
|
|
import org.imixs.workflow.ItemCollection;
|
|
import org.imixs.workflow.WorkflowKernel;
|
|
import org.imixs.workflow.engine.DocumentEvent;
|
|
import org.imixs.workflow.engine.DocumentService;
|
|
import org.imixs.workflow.engine.ModelService;
|
|
import org.imixs.workflow.engine.WorkflowService;
|
|
import org.imixs.workflow.exceptions.AccessDeniedException;
|
|
import org.imixs.workflow.exceptions.ModelException;
|
|
import org.imixs.workflow.exceptions.PluginException;
|
|
import org.imixs.workflow.exceptions.ProcessingErrorException;
|
|
import org.imixs.workflow.exceptions.QueryException;
|
|
|
|
import com.alexanderlogistics.BusinessPartnerService;
|
|
import com.alexanderlogistics.InvoiceUtil;
|
|
|
|
import jakarta.annotation.security.DeclareRoles;
|
|
import jakarta.annotation.security.RolesAllowed;
|
|
import jakarta.annotation.security.RunAs;
|
|
import jakarta.ejb.EJB;
|
|
import jakarta.ejb.Stateless;
|
|
import jakarta.enterprise.event.Observes;
|
|
|
|
/**
|
|
* Der BusinessPartnerImportService hängt sich an den standard CSVImport Service
|
|
* der die Cargosoft Stammdaten aktualisiert. Es ist ein simples Observer
|
|
* Pattern das auf das Document Event "ON_DOCUMENT_SAVE" reagiert. Hier hängt
|
|
* sich der BusinessPartnerImportService ein und prüft ob der Workflow schon
|
|
* existiert oder ggf. aktualisiert werden muss.
|
|
* <p>
|
|
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der
|
|
* Business partner erstmals neu angelegt wird.
|
|
* <p>
|
|
* Falls bei der ersten Migration erkannt wird, dass die IBAN Nummern nicht
|
|
* eindeutig sind wir der BusinessPartner mit dem Event 300 angelegt.
|
|
* <p>
|
|
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies
|
|
* ist nur eine Performance Optimierung.
|
|
* <p>
|
|
* Die Umsetzung erfolgt nach folgendem Prinzip:
|
|
* Die K- bzw. D-Nummer (K70725 , D10725 ) werden die ersten beiden Stellen
|
|
* abgeschnitten und mit BP ersetzt.
|
|
* D.h. K70725 => BP0725 bzw. D10725 => BP0725
|
|
* Change: 24.8.2025: Da nun auch K8 und D2 Nummern auftauchen können wird in
|
|
* diesen Fällen die Nummer hinter BP um 1 erweitert. Also nun auch
|
|
* D.h. K80725 => BP10725 bzw. D20725 => BP10725
|
|
*
|
|
* @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" })
|
|
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
|
@Stateless
|
|
public class BusinessPartnerImportService {
|
|
|
|
private static Logger logger = Logger.getLogger(BusinessPartnerImportService.class.getName());
|
|
|
|
public static final String TYPE_CARGOSOFTKREDITOR = "cargosoftkreditor";
|
|
|
|
// public static final String OPTION_MANDANT_ID = "mandant.id";
|
|
// public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
|
// public static final String REGEX_IMPORTTEXTPATTERN = "^R[1-8] .*$";
|
|
|
|
@EJB
|
|
WorkflowService workflowService;
|
|
|
|
@EJB
|
|
DocumentService documentService;
|
|
|
|
@EJB
|
|
ModelService modelService;
|
|
|
|
/**
|
|
* Die Methode reagiert auf das CDI DocumentEvent beim Import von cargosoft
|
|
* cargosoftkreditor documenten.
|
|
*
|
|
*
|
|
*/
|
|
public void onEvent(@Observes DocumentEvent event) {
|
|
|
|
if (event == null || event.getDocument() == null) {
|
|
return;
|
|
}
|
|
// run only if we have the model 'businesspartner-*';
|
|
if (modelService.findVersionsByRegEx("(businesspartner*)").size() == 0) {
|
|
// no business partner workflow found
|
|
return;
|
|
}
|
|
|
|
// check source
|
|
if ("cargosoftkreditor".equals(event.getDocument().getType())) {
|
|
|
|
if (event.getEventType() == DocumentEvent.ON_DOCUMENT_SAVE) {
|
|
// set NOSNAPSHOT=true fro cargosoft item (migration)
|
|
event.getDocument().setItemValue(SnapshotService.NOSNAPSHOT, true);
|
|
logger.fine("Verify business partner object....");
|
|
ItemCollection importDoc = event.getDocument();
|
|
syncCargosoftBusinessPartner(importDoc);
|
|
}
|
|
|
|
if (event.getEventType() == DocumentEvent.ON_DOCUMENT_DELETE) {
|
|
ItemCollection importDoc = event.getDocument();
|
|
String cargosoftID = importDoc.getItemValueString("name");
|
|
String partnerID = InvoiceUtil.buildBPID(cargosoftID);
|
|
ItemCollection businesspartner = lookupBusinessPartner(partnerID);
|
|
if (businesspartner != null && businesspartner.getTaskID() != 1800) {
|
|
logger.info("lock business partner object....");
|
|
try {
|
|
businesspartner.setEventID(80);
|
|
workflowService.processWorkItemByNewTransaction(businesspartner);
|
|
} catch (Exception e) {
|
|
logger.warning(
|
|
"Failed to lock Business Partner Object " + cargosoftID + " - " + e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Synchronisiert ein Cargosoft Objekt mit dem neuen Business partner
|
|
* Objekt
|
|
*
|
|
* Die K- bzw. D-Nummer (K70725 , D10725 ) werden die ersten beiden Stellen
|
|
* abgeschnitten und mit BP ersetzt.
|
|
* D.h. K70725 => BP0725 bzw. D10725 => BP0725
|
|
* D.h. K80725 => BP10725 bzw. D20725 => BP10725
|
|
*
|
|
* Die Methode gibt true zurück wenn sich das BusinessPartner Objekt geändert
|
|
* oder neu erstellt wurde.
|
|
*
|
|
* @param creditor
|
|
*/
|
|
public boolean syncCargosoftBusinessPartner(ItemCollection importDoc) {
|
|
String cargosoftID = importDoc.getItemValueString("name");
|
|
// K bedeutet Kreditor D bedeutet Debitor - beides kann vorkommen
|
|
boolean isCreditor = cargosoftID.toUpperCase().startsWith("K");
|
|
// Konvertiere die KNummer in eine BP Nummer
|
|
String partnerID = InvoiceUtil.buildBPID(cargosoftID);
|
|
|
|
// Prüfen ob es diesen partner schon gibt?
|
|
ItemCollection businesspartner = lookupBusinessPartner(partnerID);
|
|
if (businesspartner == null) {
|
|
businesspartner = createBusinessPartner(partnerID);
|
|
}
|
|
ItemCollection oldBussinessPartnerItemColl = (ItemCollection) businesspartner.clone();
|
|
|
|
// Update Fields...
|
|
businesspartner.setItemValue("name", partnerID);
|
|
businesspartner.setItemValue("partner.id", partnerID);
|
|
if (isCreditor) {
|
|
businesspartner.setItemValue("cdtr.number", cargosoftID);
|
|
if (businesspartner.isItemEmpty("cdtr.mail")) {
|
|
businesspartner.setItemValue("cdtr.mail", importDoc.getItemValueString("_vendor_email"));
|
|
}
|
|
} else {
|
|
businesspartner.setItemValue("dbtr.number", cargosoftID);
|
|
if (businesspartner.isItemEmpty("dbtr.mail")) {
|
|
businesspartner.setItemValue("dbtr.mail", importDoc.getItemValueString("_vendor_email"));
|
|
}
|
|
}
|
|
businesspartner.setItemValue("partner.country", importDoc.getItemValueString("_vendor_country"));
|
|
businesspartner.setItemValue("partner.name", importDoc.getItemValueString("_vendor_name"));
|
|
businesspartner.setItemValue("partner.phone", importDoc.getItemValueString("_vendor_phone"));
|
|
businesspartner.setItemValue("partner.address", importDoc.getItemValueString("_vendor_str"));
|
|
businesspartner.setItemValue("partner.zip", importDoc.getItemValueString("_vendor_zip_code"));
|
|
businesspartner.setItemValue("partner.city", importDoc.getItemValueString("_vendor_city"));
|
|
businesspartner.setItemValue("partner.vat", importDoc.getItemValueString("_vendor_vat_registration_id"));
|
|
|
|
// hat sich das Objekt verändert?
|
|
if (!businesspartner.equals(oldBussinessPartnerItemColl)) {
|
|
|
|
// Prüfe IBAN auf plausibilität
|
|
List<ItemCollection> bankList = BusinessPartnerService.getBanks(businesspartner);
|
|
boolean ibanDublette = false;
|
|
List<String> dublettenIban = new ArrayList<>();
|
|
for (ItemCollection bank : bankList) {
|
|
String iban = bank.getItemValueString("iban");
|
|
// erkenne fehlerhaften kontonummern
|
|
if (dublettenIban.contains(iban)) {
|
|
// ACHTUNG - uneindeutige Bankverbindung
|
|
ibanDublette = true;
|
|
} else {
|
|
dublettenIban.add(iban);
|
|
}
|
|
}
|
|
|
|
int eventID = 200; // default update
|
|
// event errechnen
|
|
if (!businesspartner.hasItem(WorkflowKernel.LASTEVENT)) {
|
|
// create new!
|
|
if (ibanDublette) {
|
|
eventID = 300; // Exception
|
|
} else {
|
|
eventID = 100; // new import
|
|
}
|
|
}
|
|
businesspartner.setEventID(eventID);
|
|
try {
|
|
workflowService.processWorkItemByNewTransaction(businesspartner);
|
|
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException e) {
|
|
logger.warning("Failed to update Business Partner Object " + cargosoftID + " - " + e.getMessage());
|
|
}
|
|
return true;
|
|
} else {
|
|
return false; // no changes
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Erstellt ein neues leeres Business Partner Object
|
|
*
|
|
* @return
|
|
*/
|
|
private ItemCollection createBusinessPartner(String cargosoftID) {
|
|
ItemCollection businessPartner = new ItemCollection();
|
|
businessPartner.setType("workitem");
|
|
businessPartner.setWorkflowGroup("Business Partner");
|
|
businessPartner.task(1000);
|
|
|
|
// Hier migrieren wir jetzt auch die alten IBAN/BIC Daten
|
|
try {
|
|
String query = "(type:" + TYPE_CARGOSOFTKREDITOR + ")";
|
|
query = query + " AND ( name:" + cargosoftID + " )";
|
|
|
|
List<ItemCollection> oldList = documentService.find(query, 2, 0);
|
|
|
|
// es können 2 Datensätze ankommen
|
|
|
|
// Items:
|
|
// cdtr.mail (Liste)
|
|
// cdtr.creditperiod
|
|
// cdtr.iban , cdtr.iban2 - 4
|
|
// cdtr.bic , cdtr.bic2 - 4
|
|
List<String> ibanList = new ArrayList<>();
|
|
List<String> bicList = new ArrayList<>();
|
|
for (ItemCollection oldData : oldList) {
|
|
if (!oldData.getItemValueString("cdtr.mail").isEmpty()) {
|
|
businessPartner.setItemValue("cdtr.mail", oldData.getItemValue("cdtr.mail"));
|
|
businessPartner.setItemValue("dbtr.mail", oldData.getItemValue("cdtr.mail"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.creditperiod").isEmpty()) {
|
|
businessPartner.setItemValue("cdtr.creditperiod", oldData.getItemValue("cdtr.creditperiod"));
|
|
}
|
|
|
|
if (!oldData.getItemValueString("cdtr.iban").isEmpty()) {
|
|
ibanList.add(oldData.getItemValueString("cdtr.iban"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.bic").isEmpty()) {
|
|
bicList.add(oldData.getItemValueString("cdtr.bic"));
|
|
}
|
|
|
|
if (!oldData.getItemValueString("cdtr.iban2").isEmpty()) {
|
|
ibanList.add(oldData.getItemValueString("cdtr.iban2"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.bic2").isEmpty()) {
|
|
bicList.add(oldData.getItemValueString("cdtr.bic2"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.iban3").isEmpty()) {
|
|
ibanList.add(oldData.getItemValueString("cdtr.iban3"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.bic3").isEmpty()) {
|
|
bicList.add(oldData.getItemValueString("cdtr.bic3"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.iban4").isEmpty()) {
|
|
ibanList.add(oldData.getItemValueString("cdtr.iban4"));
|
|
}
|
|
if (!oldData.getItemValueString("cdtr.bic4").isEmpty()) {
|
|
bicList.add(oldData.getItemValueString("cdtr.bic4"));
|
|
}
|
|
|
|
}
|
|
|
|
// build partner.iban.list - dublettenprüfung und Trim
|
|
List<String> dubletten = new ArrayList<>();
|
|
List<String> dublettenIban = new ArrayList<>();
|
|
|
|
if (ibanList.size() > 0) {
|
|
List<ItemCollection> bankList = new ArrayList<>();
|
|
for (int i = 0; i < ibanList.size(); i++) {
|
|
String iban = ibanList.get(i);
|
|
String bic = "";
|
|
if (bicList.size() > i) {
|
|
bic = bicList.get(i);
|
|
}
|
|
|
|
iban = superTrim(iban);
|
|
bic = superTrim(bic);
|
|
if (dubletten.contains(iban + "/" + bic)) {
|
|
// voll dublette
|
|
continue;
|
|
} else {
|
|
dubletten.add(iban + "/" + bic);
|
|
}
|
|
|
|
ItemCollection bank = new ItemCollection();
|
|
// {cdtr.iban=[A], name=[cdtr1], cdtr.name=[a], cdtr.bic=[a]}
|
|
bank.setItemValue("id", "bank" + (i + 1));
|
|
bank.setItemValue("name", "Bank " + (i + 1));
|
|
bank.setItemValue("iban", iban);
|
|
bank.setItemValue("bic", bic);
|
|
|
|
bankList.add(bank);
|
|
}
|
|
Iterator<?> var3 = bankList.iterator();
|
|
List<Map> mapOrderItems = new ArrayList();
|
|
while (var3.hasNext()) {
|
|
ItemCollection orderItem = (ItemCollection) var3.next();
|
|
mapOrderItems.add(orderItem.getAllItems());
|
|
}
|
|
businessPartner.setItemValue(BusinessPartnerService.ITEM_IBAN_LIST, mapOrderItems);
|
|
}
|
|
|
|
} catch (QueryException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return businessPartner;
|
|
}
|
|
|
|
/**
|
|
* entfernt alle leerzeichen
|
|
*/
|
|
public String superTrim(String data) {
|
|
String result = data.trim();
|
|
result = result.replace(" ", "");
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Sucht nach einem Business partner
|
|
*
|
|
* @param id
|
|
* @return
|
|
*/
|
|
private ItemCollection lookupBusinessPartner(String id) {
|
|
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:businesspartner*) AND (name:" + id
|
|
+ ")";
|
|
|
|
try {
|
|
List<ItemCollection> result = documentService.find(query, 1, 0, null, false);
|
|
if (result.size() > 0) {
|
|
return result.get(0);
|
|
}
|
|
} catch (QueryException e) {
|
|
logger.warning("Failed to query businesspartner: " + query + " - Error: " + e.getMessage());
|
|
|
|
}
|
|
return null;
|
|
}
|
|
}
|