/* * 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. *
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der * Business partner erstmals neu angelegt wird. *
* Falls bei der ersten Migration erkannt wird, dass die IBAN Nummern nicht * eindeutig sind wir der BusinessPartner mit dem Event 300 angelegt. *
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies * ist nur eine Performance Optimierung. *
* 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