office-alexander-logistics/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java

347 lines
14 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 com.alexanderlogistics.KreditorDebitorService;
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 BusinessParter mit dem Event 300 angelegt.
* <p>
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies
* ist nur eine Performance Optimierung.
*
* @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 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;
}
// check source
if (event.getEventType() == DocumentEvent.ON_DOCUMENT_SAVE
&& "cargosoftkreditor".equals(event.getDocument().getType())) {
// set NOSNAPSHOT=true fro cargosoft item (migration)
event.getDocument().setItemValue(SnapshotService.NOSNAPSHOT, true);
// run only if we have the model 'businesspartner-*';
if (modelService.findVersionsByRegEx("(businesspartner*)").size() == 0) {
// no business partner workflow found
return;
}
logger.fine("Verify business partner object....");
ItemCollection importDoc = event.getDocument();
String name = event.getDocument().getItemValueString("name");
boolean isCreditor = name.toUpperCase().startsWith("K");
String partnerID = InvoiceUtil.buildBPID(name);
// 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", name);
if (businesspartner.isItemEmpty("cdtr.mail")) {
businesspartner.setItemValue("cdtr.mail", importDoc.getItemValueString("_vendor_email"));
}
} else {
businesspartner.setItemValue("dbtr.number", name);
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"));
// 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
// event errechnen
if (!businesspartner.hasItem(WorkflowKernel.LASTEVENT)) {
// create new!
if (ibanDublette) {
eventID = 300; // Exception
} else {
eventID = 100; // update/create
}
}
businesspartner.setEventID(eventID);
try {
workflowService.processWorkItemByNewTransaction(businesspartner);
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException e) {
logger.warning("Failed to update Business Partner Object " + name + " - " + e.getMessage());
}
}
}
}
/**
* Erstellt ein neues leeres Business Partner Object
*
* @return
*/
private ItemCollection createBusinessPartner(String partnerID) {
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 cargoShortID = partnerID.substring(2);
String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ")";
query = query + " AND ( name:K7" + cargoShortID + " OR name:D1" + cargoShortID + " )";
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;
}
}