package com.alexanderlogistics; import java.io.IOException; import java.io.Serializable; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import java.util.stream.Collectors; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.exceptions.PluginException; import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.faces.util.ErrorHandler; import jakarta.enterprise.context.ConversationScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.json.Json; import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; /** * The CargosoftController CDI Bean provides Front-End methods for the cargosoft * kreditore objects. *

* The method search provides a suggest list searching a phrase within the * cargosoft creditor list (type=cargosoftkreditor). * *

* Besonderheit *

* Wir transportieren in der Resutl Liste eine versteckte JSON Struktur mit * allen IBAN Informationen Das ist im Grunde etwas irre aber durch die * JSF-Ajax-JavaScript Hölle kommern wir derzeit aus der Nummer nicht mehr * anders raus. * * @author rsoika * */ @Named @ConversationScoped public class CargosoftController implements Serializable { private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(CargosoftController.class.getName()); @Inject protected DocumentService documentService; private List searchResult = null; private ItemCollection kreditor = null; // used for zahlungsziel (kreidtor.xhtml) /** * This method searches a text phrase within the list of cargosoft kreditor * objects (type=cargosoftkreditor). *

* JSF Integration: * * {@code * * } * *

* JavaScript Example: * *

	 * {@code
	 *  imixsOfficeWorkflow.cargosoftSearch({ item: '_invoicenumber' })
	 *  }
	 * 
* * @param searchmode - if 'multi', display multiple IBANs in seperate lines */ public void searchCreditor(String searchmode) { boolean bMulitMode = "multi".equalsIgnoreCase(searchmode); searchResult = new ArrayList(); // get the param from faces context.... FacesContext fc = FacesContext.getCurrentInstance(); String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase"); if (phrase == null) { return; } logger.fine("search prase '" + phrase + "'"); // String input =workflowController.getWorkitem().getItemValueString(itemName); if (phrase == null || phrase.length() < 2) { return; } // die cargosoft Kreditornummer beginnt seltsamerweise mit einem K // und die Debitoren mit einem D..... String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ")"; if (phrase.toUpperCase().startsWith("K") || phrase.toUpperCase().startsWith("D")) { query = query + " AND ( (name:" + phrase + "*) OR (" + phrase.toLowerCase() + "*) )"; } else { // query with K and D prafix query = query + " AND ( (name:K" + phrase + "*) OR (name:D" + phrase + "*) " + " OR (" + phrase.toLowerCase() + "*) )"; } try { List result = documentService.find(query, 20, 0, "$modified", true); logger.info("found " + result.size() + " creditors..."); if (result != null) { for (ItemCollection cdtr : result) { // Aenderugn 22. Jun wir geben das K/D direkt weiter String cdtrNo = cdtr.getItemValueString("_VENDOR_NUM"); String display = cdtrNo + " - " + cdtr.getItemValueString("_VENDOR_Name"); // Im MulitMode zeigen wir pro IBAN (1-4) eine eigene Zeile an. Dieser // Modus wird für die Rechnungserfassung benötigt. // im SingleMode wird hingegen nur ein Datensatz in der Trefferliste angezeigt. // (Ein Kreditoren Eintrag kann bis zu 4 IBANs / BICs haben if (bMulitMode) { // in der JSON Struktur werden alle IBANS übertragen display = display + " |" + cdtr.getItemValueString("cdtr.creditperiod"); display = display + "|" + cdtr.getItemValueString("cdtr.iban"); display = display + "|" + cdtr.getItemValueString("cdtr.bic"); 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++) { if (!cdtr.getItemValueString("cdtr.iban" + j).isEmpty()) { // Dublette mit alternativer IBAN erzeugen display = cdtrNo + " - " + cdtr.getItemValueString("_VENDOR_Name"); display = display + " |" + cdtr.getItemValueString("cdtr.creditperiod"); display = display + "|" + cdtr.getItemValueString("cdtr.iban" + j); display = display + "|" + cdtr.getItemValueString("cdtr.bic" + j); searchResult.add(new KreditorSearchEntry(cdtrNo, display, buildJsonData(cdtr, cdtr.getItemValueString("cdtr.iban" + j), cdtr.getItemValueString("cdtr.bic" + j)))); } } } else { // Modus für Kreditoren Verwaltung searchResult.add(new KreditorSearchEntry(cdtrNo, display, buildJsonData(cdtr))); } } } } catch (QueryException e) { e.printStackTrace(); } } /** * This method searches a text phrase within the list of cargosoft Debitor * objects (type=cargosoftkreditor). *

* JSF Integration: * * {@code * * } * *

* JavaScript Example: * *

	 * {@code
	 *  imixsOfficeWorkflow.cargosoftSearch({ item: '_invoicenumber' })
	 *  }
	 * 
* * @param searchmode - if 'multi', display multiple IBANs in seperate lines */ public void searchDebitor() { searchResult = new ArrayList(); // get the param from faces context.... FacesContext fc = FacesContext.getCurrentInstance(); String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase"); if (phrase == null) { return; } logger.fine("search prase '" + phrase + "'"); // String input =workflowController.getWorkitem().getItemValueString(itemName); if (phrase == null || phrase.length() < 2) { return; } // die cargosoft Kreditornummer beginnt seltsamerweise mit einem K // und die Debitoren mit einem D..... String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ") AND (name:D*) AND ((name:D" + phrase + "*) OR (" + phrase.toLowerCase() + "*) )"; try { List result = documentService.find(query, 20, 0, "$modified", true); logger.fine("found " + result.size() + " debitors..."); if (result != null) { for (ItemCollection dbtr : result) { // Aenderugn 22. Jun wir geben das K/D direkt witer String dbtrNo = dbtr.getItemValueString("_VENDOR_NUM"); String display = dbtrNo + " - " + dbtr.getItemValueString("_VENDOR_Name"); display = display.replace("\"", ""); display = display.replace("'", ""); searchResult.add(new KreditorSearchEntry(dbtrNo, display, buildJsonData(dbtr))); } } } catch (QueryException e) { e.printStackTrace(); } } /** * Hilfsmethode die eine JSON Struktur mit einer IBAN/BIC kombinatuion erzeugt. * Diese JSON Struktur wird von der Rechnungserfassungs Maske benötigt * * @return */ private String buildJsonData(ItemCollection cdtr, String iban, String bic) { JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). // add("no", jsonVal(cdtr.getItemValueString("_VENDOR_NUM"))). // add("name", jsonVal(cdtr.getItemValueString("_VENDOR_Name"))). // add("creditperiod", jsonVal(cdtr.getItemValueString("cdtr.creditperiod"))). // add("iban", jsonVal(iban)). // add("bic", jsonVal(bic)); JsonObject jsonObject = objectBuilder.build(); String jsonString = "{}"; try (Writer writer = new StringWriter()) { Json.createWriter(writer).write(jsonObject); jsonString = writer.toString(); } catch (IOException e) { logger.warning("Unable to build json structure"); } return jsonString; } /** * Hilfsmethode die eine JSON Struktur mit allen IBN/BIC kombinationen erzeugt. * Diese JSON Strukur wird dann von der Kreitoren.xhtml Maske wieder ausgelesen. * * @return */ private String buildJsonData(ItemCollection cdtr) { JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). // add("no", jsonVal(cdtr.getItemValueString("_VENDOR_NUM"))). // add("name", jsonVal(cdtr.getItemValueString("_VENDOR_Name"))). // add("country", jsonVal(cdtr.getItemValueString("_VENDOR_COUNTRY"))). // add("creditperiod", jsonVal(cdtr.getItemValueString("cdtr.creditperiod"))). // // add("mail", jsonVal(cdtr.getItemValue("cdtr.mail"))). // add("mail", jsonVal((String) cdtr.getItemValue("cdtr.mail").stream() .collect(Collectors.joining("\\n")))) . // add("iban", jsonVal(cdtr.getItemValueString("cdtr.iban"))). // add("bic", jsonVal(cdtr.getItemValueString("cdtr.bic"))). // // add ibans für kreditoren verwaltung add("iban2", jsonVal(cdtr.getItemValueString("cdtr.iban2"))). // add("iban3", jsonVal(cdtr.getItemValueString("cdtr.iban3"))). // add("iban4", jsonVal(cdtr.getItemValueString("cdtr.iban4"))). // add("bic2", jsonVal(cdtr.getItemValueString("cdtr.bic2"))). // add("bic3", jsonVal(cdtr.getItemValueString("cdtr.bic3"))). // add("bic4", jsonVal(cdtr.getItemValueString("cdtr.bic4"))); // JsonObject jsonObject = objectBuilder.build(); String jsonString = "{}"; try (Writer writer = new StringWriter()) { Json.createWriter(writer).write(jsonObject); jsonString = writer.toString(); } catch (IOException e) { logger.warning("Unable to build json structure"); } return jsonString; } /** * Helper method to remove " and ' characters - causing problems * * @param val * @return */ public static String jsonVal(String val) { val = val.replace("\"", ""); val = val.replace("'", ""); val = val.replace("\"", ""); return val; } /** * Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste * Eintrag * * @return */ public List getSearchResult() { return searchResult; } /** * This method reset the search and input state. */ public void reset() { searchResult = new ArrayList(); logger.fine("reset"); } public ItemCollection getKreditor() { if (kreditor == null) { kreditor = new ItemCollection(); } return kreditor; } public void setKreditor(ItemCollection kreditor) { this.kreditor = kreditor; } /** * Diese Method überträgt die geänderten Daten in das Kreidtoren/Debitoren * Objekt (cdtr.creditperiod,cdtr.iban,cdtr.bic) * * Zusätzlich wird geprüft ob die eingegebene Mail Adresse eine gültige SMTP * Adresse ist * * @throws PluginException */ public void updateZahlungsziel() throws PluginException { String cdtrNumber = kreditor.getItemValueString("cdtr.number"); logger.fine("Zahlungsziel = " + cdtrNumber); // search workitem String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ") AND (name:" + cdtrNumber + ")"; List result; try { result = documentService.find(query, 1, 0); if (result.size() == 1) { ItemCollection cargoCreditor = result.get(0); try { cargoCreditor.setItemValue("cdtr.creditperiod", Integer.parseInt(kreditor.getItemValueString("cdtr.creditperiod"))); } catch (NumberFormatException nfe) { // no op } List mailList = kreditor.getItemValue("cdtr.mail"); mailList = mailList.stream() .filter(str -> str != null && !str.isEmpty()) .map(String::trim) .collect(Collectors.toList()); for (String mail : mailList) { if (!InvoiceUtil.validateEmail(mail)) { throw new PluginException(CargosoftController.class.getName(), "INVALID_EMAIL", "Die Daten konnten nicht aktualisiert werden! Bitte geben Sie eine gültige E-Mail Adresse ein!"); } } cargoCreditor.setItemValue("cdtr.mail", mailList); cargoCreditor.setItemValue("cdtr.iban", kreditor.getItemValueString("cdtr.iban")); cargoCreditor.setItemValue("cdtr.bic", kreditor.getItemValueString("cdtr.bic")); cargoCreditor.setItemValue("cdtr.iban2", kreditor.getItemValueString("cdtr.iban2")); cargoCreditor.setItemValue("cdtr.bic2", kreditor.getItemValueString("cdtr.bic2")); cargoCreditor.setItemValue("cdtr.iban3", kreditor.getItemValueString("cdtr.iban3")); cargoCreditor.setItemValue("cdtr.bic3", kreditor.getItemValueString("cdtr.bic3")); cargoCreditor.setItemValue("cdtr.iban4", kreditor.getItemValueString("cdtr.iban4")); cargoCreditor.setItemValue("cdtr.bic4", kreditor.getItemValueString("cdtr.bic4")); documentService.save(cargoCreditor); } } catch (QueryException e) { logger.severe("Unable to find cargosoft kreditor " + e.getMessage()); } catch (PluginException pe) { // add a new FacesMessage into the FacesContext ErrorHandler.handlePluginException(pe); throw pe; } } }