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

467 lines
18 KiB
Java

/*******************************************************************************
* Imixs Workflow Technology
* Copyright (C) 2003, 2008 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
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
*
*******************************************************************************/
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.regex.Matcher;
import java.util.regex.Pattern;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.AccessDeniedException;
import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.faces.data.WorkflowEvent;
import org.imixs.workflow.office.forms.ValidationController;
import jakarta.enterprise.context.ConversationScoped;
import jakarta.enterprise.event.Observes;
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;
/**
* Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms
* sowie für die das Suche-Widget 'businesspartner_search' bereit.
*
*
* @author rsoika
* @version 1.0
*/
@Named
@ConversationScoped
public class BusinessPartnerController implements Serializable {
private static final long serialVersionUID = 1L;
protected List<ItemCollection> ibanList = null;
protected List<ItemCollection> invoicesOut = null;
protected List<ItemCollection> invoicesIn = null;
protected List<ItemCollection> dunnings = null;
@Inject
DocumentService documentService;
@Inject
BusinessPartnerService businessPartnerService;
@Inject
ValidationController validationController;
private List<BusinessPartnerSearchEntry> searchResult = null;
private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName());
public List<ItemCollection> getInvoicesOut() {
if (invoicesOut == null) {
invoicesOut = new ArrayList<>();
}
return invoicesOut;
}
public List<ItemCollection> getInvoicesIn() {
if (invoicesIn == null) {
invoicesIn = new ArrayList<>();
}
return invoicesIn;
}
public List<ItemCollection> getDunnings() {
if (dunnings == null) {
dunnings = new ArrayList<>();
}
return dunnings;
}
/**
* This method searches a text phrase within the list of DATEV kreditoren
* <p>
* JSF Integration:
*
* {@code
<h:commandScript name="datevSearch" action=
* "#{datevSearchController.searchCdtr()}" render=
* "autocomplete-resultlist-datev" onevent="autocompleteShowResult" /> }
*/
public void search(String options) {
List<ItemCollection> resultList = null;
searchResult = new ArrayList<BusinessPartnerSearchEntry>();
// 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 + "'");
if (phrase == null || phrase.length() < 2) {
return;
}
logger.fine("search for=" + phrase);
Pattern pattern = null;
resultList = businessPartnerService.search(phrase);
// Compile the regex pattern if available
if (options.contains("regexPattern=")) {
String regexPattern = options.substring(options.indexOf("regexPattern=") + 13);
logger.fine("regex=" + regexPattern);
pattern = Pattern.compile(regexPattern);
}
// Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry
for (ItemCollection businessPartner : resultList) {
String name = businessPartner.getItemValueString("name");
// Prüfen, ob der name der Regex entspricht
if (pattern != null) {
Matcher matcher = pattern.matcher(name);
if (!matcher.matches()) {
// Kein passendes Konto
continue;
}
}
String display = businessPartner.getItemValueString("$workflowsummary");
display = display.replace("\"", "");
display = display.replace("'", "");
searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner)));
}
}
/**
* Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
* angegeben wurde. Damit löst die Suchmaske businesspartner_search.xhtml eine
* komplette rerender Phase der Form aus. Dies ist z.b. für den workflow
* 'analyse-debitor.bpmn' nützlich
*
* @param options
* @return
*/
public boolean isRerenderMode(String options) {
return options.toLowerCase().contains("rerender");
}
/**
* Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste
* Eintrag
*
* @return
*/
public List<BusinessPartnerSearchEntry> getSearchResult() {
return searchResult;
}
public ItemCollection getBusinessPartnerByID(String bpid) {
ItemCollection partner = businessPartnerService.getBusinessPartnerByID(bpid);
return partner;
}
/**
* Helper method to disable the form validation during a metadata update
*/
public void disableValidation() {
logger.info("Disable Validation");
validationController.setRequired(false);
}
/**
* WorkflowEvent listener resolved additional data.
*
* For businesspartner the method converts the IBAN child list embeded HashMaps
* into ItemCollections and reconvert them before processing
*
* for invoices the method resolve the partner.id and partner.name
*
* @param workflowEvent
* @throws AccessDeniedException
*/
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
int eventType = workflowEvent.getEventType();
ItemCollection workitem = workflowEvent.getWorkitem();
if (workitem == null) {
return;
}
if (workitem.getModelVersion().startsWith("businesspartner-")) {
// reset orderItems if workItem has changed
if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) {
// reset state
ibanList = BusinessPartnerService.explodeBanks(workitem);
loadStats(workitem);
}
// before the workitem is saved we update the field txtOrderItems
if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
BusinessPartnerService.implodeBanks(workitem, ibanList);
}
if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) {
// reset state
ibanList = BusinessPartnerService.explodeBanks(workitem);
}
}
if (workitem.getModelVersion().startsWith("rechnungsausgang-")) {
// resolve partner.id and partner.name
if (workitem.getItemValueString("partner.id").isEmpty()) {
// try to resolve the data
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
if (bpWorkitem != null) {
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
}
}
}
if (workitem.getModelVersion().startsWith("rechnungseingang-")) {
// resolve partner.id and partner.name
if (workitem.getItemValueString("partner.id").isEmpty()) {
// try to resolve the data
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
if (bpWorkitem != null) {
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
}
}
}
if (workitem.getModelVersion().startsWith("zahlungseingang-")) {
// resolve partner.id and partner.name
if (workitem.getItemValueString("partner.id").isEmpty()) {
// try to resolve the data
ItemCollection bpWorkitem = getBusinessPartnerByID(
InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number")));
if (bpWorkitem != null) {
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
}
}
}
}
/**
* Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event
* aufgerufen.
*
* @param workitem
*/
private void loadStats(ItemCollection workitem) {
try {
// Ausgangsrechnungen
String dbtrNumber = workitem.getItemValueString("dbtr.number");
if (!dbtrNumber.isEmpty()) {
invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
// Mahnungen
String query = "(type:workitem) AND ($modelversion:mahnlauf-*) " + " AND (dbtr.number:" + dbtrNumber
+ ")";
dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false);
}
// Eingangsrechnungen
String cdtrNumber = workitem.getItemValueString("cdtr.number");
if (!cdtrNumber.isEmpty()) {
String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) " + " AND (cdtr.number:"
+ cdtrNumber + ")";
invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
}
} catch (QueryException e) {
logger.severe("failed to load stats: " + e.getMessage());
}
}
public List<ItemCollection> getIbanList() {
return ibanList;
}
public void addIBAN() {
if (ibanList == null) {
ibanList = new ArrayList<ItemCollection>();
}
ItemCollection source = new ItemCollection();
ibanList.add(source);
}
/**
* Removes an dbtr item from the list
*
* @param name - name of dbtr
*/
public void removeIBAN(String id) {
if (id != null && ibanList != null) {
for (ItemCollection cdtr : ibanList) {
if (id.equals(cdtr.getItemValueString("id"))) {
ibanList.remove(cdtr);
break;
}
}
}
}
/**
* This JSF backing method is called by businesspartner_search.xhtml after the
* user has selected a new businesspartner.
* <p>
* The method lookups the given BusinessPartner and updates the metadata for
* dbtr/cdtr depending on the workflow type. A form will than rerender the
* opList section.
*/
public void updateMetaData(ItemCollection workitem) {
FacesContext fc = FacesContext.getCurrentInstance();
String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
logger.info("....update metadata.....bpid = " + bpid);
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
searchResult = null;
if (businessPartner != null) {
// Eingangsrechnung
if (InvoiceUtil.isCreditorInvoice(workitem)) {
workitem.setItemValue("cdtr.number",
businessPartner.getItemValueString("cdtr.number"));
workitem.setItemValue("cdtr.name",
businessPartner.getItemValueString("partner.name"));
workitem.setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail"));
// Anforderung Frau Kück vom 20.8.2025
// bei Auswahl eines Kreditors sollen IBAN/BIC mit dem ersten vorhandenen
// IBAN/BIC Kombination
// im Business Partner überschreiben werden falls möglich!
List<ItemCollection> bankList = BusinessPartnerService.getBanks(businessPartner);
if (bankList != null && bankList.size() > 0) {
ItemCollection bank = bankList.get(0);
if (!bank.getItemValueString("iban").isEmpty()) {
workitem.setItemValue("cdtr.iban", bank.getItemValueString("iban"));
}
if (!bank.getItemValueString("bic").isEmpty()) {
workitem.setItemValue("cdtr.bic", bank.getItemValueString("bic"));
}
}
} else
// Ausgangsrechnung
if (InvoiceUtil.isDebitorInvoice(workitem)) {
workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number"));
workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} else
// Zahlungseingang
if (workitem.getModelVersion().startsWith("zahlungseingang")) {
workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number"));
workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} else
// Analyse Debitor
if (workitem.getModelVersion().startsWith("analyse-debitor")) {
workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number"));
workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} else {
// default behavior
if (workitem.getItemValueString("dbtr.number").isEmpty()) {
String number = businessPartner.getItemValueString("dbtr.number");
workitem.setItemValue("dbtr.number", number);
if (number.length() > 1) {
workitem.setItemValue("dbtr.number.short",
number.substring(1));
}
}
if (workitem.getItemValueString("cdtr.number").isEmpty()) {
String number = businessPartner.getItemValueString("cdtr.number");
workitem.setItemValue("cdtr.number", number);
if (number.length() > 1) {
workitem.setItemValue("cdtr.number.short",
number.substring(1));
}
}
}
}
}
/**
* Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen
* BusinessPartner erzeugt.
*
* @return
*/
private String buildJsonData(ItemCollection businessPartner) {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). //
add("name", jsonVal(businessPartner.getItemValueString("name"))). //
add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). //
add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). //
add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name")));
// get iban list
// {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]}
ibanList = BusinessPartnerService.getBanks(businessPartner);
int i = 1;
for (ItemCollection iban : ibanList) {
objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). //
add("bic" + 1, jsonVal(iban.getItemValueString("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;
}
/**
* Helper method to remove " and ' characters - causing problems
*
* @param val
* @return
*/
public static String jsonVal(String val) {
val = val.replace("\"", "");
val = val.replace("'", "");
return val;
}
}