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

400 lines
15 KiB
Java

/*******************************************************************************
* Imixs Workflow
* Copyright (C) 2001, 2011 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:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
package com.alexanderlogistics;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.ItemCollectionComparator;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.engine.index.SchemaService;
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 jakarta.annotation.PostConstruct;
import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RolesAllowed;
import jakarta.annotation.security.RunAs;
import jakarta.ejb.Singleton;
import jakarta.inject.Inject;
/**
* Der BusinessPartnerService stellt Methoden für den Zugriff auf Business
* Partner bereit.
*
* @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" })
@Singleton
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
public class BusinessPartnerService {
public static final int MAX_SEARCH_RESULT = 100;
public static final String ITEM_IBAN_LIST = "partner.bank.list";
public static final String WORKFLOW_SERVICE_ENDPOINT = "workflow.service.endpoint";
public static final String WORKFLOW_SERVICE_USER = "workflow.service.user";
public static final String WORKFLOW_SERVICE_PASSWORD = "workflow.service.password";
public static final String ERROR_BUSINESSPARTNER_MISSING = "ERROR_BUSINESSPARTNER_MISSING";
public static final String ERROR_BUSINESSPARTNER_LOCKED = "ERROR_BUSINESSPARTNER_LOCKED";
public static final String ERROR_BUSINESSPARTNER_VERIFICATION = "ERROR_BUSINESSPARTNER_VERIFICATION";
public static final int TASK_ACTIVE = 1100;
public static final int TASK_VERIFICATION = 1300;
public static final int TASK_INACTIVE = 1700;
public static final int TASK_LOCKED = 1800;
public static final int EVENT_ACTIVATE = 210;
private static Logger logger = Logger.getLogger(BusinessPartnerService.class.getName());
@Inject
@ConfigProperty(name = WORKFLOW_SERVICE_ENDPOINT)
Optional<String> workflowServiceEndpoint;
@Inject
@ConfigProperty(name = WORKFLOW_SERVICE_USER)
Optional<String> workflowServiceUser;
@Inject
@ConfigProperty(name = WORKFLOW_SERVICE_PASSWORD)
Optional<String> workflowServicePassword;
@Inject
DocumentService documentService;
@Inject
WorkflowService workflowService;
@Inject
SchemaService schemaService;
/**
* Initialize the rest clients
*/
@PostConstruct
public void init() {
}
/**
* Diese Methode aktualisiert das business Partner object. Sie wird von den
* Invoice Plugins genutzt.
* Die Methode wirft eine PluginException falls das BusinessPartner Objekt
* gesperrt oder in verification ist!
*
* Gleichzeitig wird bei Rechnungen in Abhängigkeit der Rechnungsart die
* dbtr./cdtr. items sowie mail und country aktualisiert.
*
* @param partnerID
* @param workitem
* @throws PluginException
*/
public void updateBusinessPartnerData(ItemCollection workitem) throws PluginException {
String partnerID = workitem.getItemValueString("partner.id");
// Migration wenn keine partner.id existier!
if (partnerID.isEmpty()) {
if (InvoiceUtil.isCreditorInvoice(workitem)) {
partnerID = InvoiceUtil.buildBPID(workitem.getItemValueString("cdtr.number"));
}
if (InvoiceUtil.isDebitorInvoice(workitem)) {
partnerID = InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number"));
}
workitem.setItemValue("partner.id", partnerID);
}
// load Business Partner
ItemCollection businessPartner = getBusinessPartnerByID(partnerID);
if (businessPartner != null) {
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name"));
// Update Invoice Partner Meta Data
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.getItemValueString("dbtr.mail"));
workitem.setItemValue("invoice.country", businessPartner.getItemValueString("_vendor_country"));
}
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.getItemValueString("cdtr.mail"));
workitem.setItemValue("invoice.country", businessPartner.getItemValueString("_vendor_country"));
}
// Validate Business Partner Status!
if (businessPartner.getTaskID() == TASK_VERIFICATION) {
throw new PluginException(InvoicePlugin.class.getName(),
ERROR_BUSINESSPARTNER_VERIFICATION,
"Businesspartner is in verification. Invoice can't be processed!");
}
if (businessPartner.getTaskID() == TASK_LOCKED) {
throw new PluginException(InvoicePlugin.class.getName(),
ERROR_BUSINESSPARTNER_LOCKED,
"Businesspartner is locked. Invoice can't be processed!");
}
// update business partner status...
try {
if (businessPartner.getTaskID() == TASK_INACTIVE) {
// Workitem erneut aktivieren
businessPartner.event(EVENT_ACTIVATE);
workflowService.processWorkItem(businessPartner);
} else {
// workItem einfach nur speichern!
documentService.save(businessPartner);
}
} catch (PluginException | ProcessingErrorException | AccessDeniedException | ModelException e) {
logger.warning("Failed to update BusinessPartner object '" + partnerID + "'!");
}
} else {
logger.warning("BusinessPartner '" + partnerID + "' not found!");
}
}
/**
* Returns the stubs of all outgoing invoices
*
* @param _dbtrNumber
* @return
*/
public List<ItemCollection> findOutgoingInvoices(String _dbtrNumber) {
// Aus der dbtrNummer muss das führendde D entfernt werden
String query = "(type:workitem) AND ($modelversion:rechnungsausgang-*)";
// Aus der dbtrNummer muss das führendde D entfernt werden
// wir speichern dieses zwar im Zahlungseingangs Workflow, aber eine
// Ausganksrechnung kennt das nicht
// Das ganze ist ein übles Relikt aus Cargosoft und kann nicht vermieden werden
String _dbtrNumberOld = _dbtrNumber;
if (_dbtrNumberOld.startsWith("D")) {
_dbtrNumberOld = _dbtrNumber.substring(1);
}
query = query + " AND (dbtr.number:" + _dbtrNumber + " OR dbtr.number:" + _dbtrNumberOld + ")";
try {
return documentService.find(query, 999, 0, "invoice.number", false);
} catch (QueryException e) {
logger.severe("Failed to compute outgoing invoices: " + e.getMessage());
}
return new ArrayList<>();
}
/**
* Diese Methode sucht einen Business Partner anhand seiner BPID
*
* @param bpid
* - business partner id phrase
* @return - matching business partner
*/
public ItemCollection getBusinessPartnerByID(String bpid) {
if (bpid == null || bpid.isEmpty()) {
return null;
}
List<ItemCollection> result;
try {
String sQuery = "(type:\"workitem\" OR type:\"workitemarchive\" ) AND ($modelversion:businesspartner-*)";
sQuery += " AND (name:" + bpid.trim() + ")";
logger.finest("SearchQuery= " + sQuery);
result = documentService.find(sQuery, 1, 0);
if (result.size() > 0) {
return result.get(0);
}
} catch (Exception e) {
logger.warning(" lucene error - " + e.getMessage());
}
return null;
}
/**
* Diese Methode sucht Business Partner anhand einer Suchphrase
*
* @param phrase
* - search phrase
* @return - list of matching business partners
*/
public List<ItemCollection> search(String phrase) {
List<ItemCollection> searchResult = new ArrayList<ItemCollection>();
if (phrase == null || phrase.isEmpty()) {
return searchResult;
}
try {
phrase = phrase.trim();
// phrase = LuceneSearchService.escapeSearchTerm(phrase);
phrase = schemaService.normalizeSearchTerm(phrase);
String sQuery = "(type:\"workitem\" OR type:\"workitemarchive\") AND ($modelversion:businesspartner-*)";
sQuery += " AND (" + phrase + "*)";
logger.finest("SearchQuery= " + sQuery);
searchResult = documentService.find(sQuery, MAX_SEARCH_RESULT, 0);
} catch (Exception e) {
logger.warning(" lucene error - " + e.getMessage());
}
// sort by txtname..
Collections.sort(searchResult, new ItemCollectionComparator("$workflowsummary", true));
return searchResult;
}
/**
* Packt die Liste der Bank Details (ItemCollections) in ein Workitem
*
* @param workitem
*/
public static void implodeBanks(ItemCollection workitem, List<ItemCollection> ibanList) {
List<Map> mapOrderItems = new ArrayList();
if (ibanList != null) {
logger.fine("Convert child items into Map...");
Iterator<?> var3 = ibanList.iterator();
while (var3.hasNext()) {
ItemCollection orderItem = (ItemCollection) var3.next();
mapOrderItems.add(orderItem.getAllItems());
}
workitem.replaceItemValue(BusinessPartnerService.ITEM_IBAN_LIST, mapOrderItems);
}
}
/**
* Enpackt die iban Map Liste von eiem Worktiem in eine Liste von ItemCollection
*
* @param workitem
*/
public static List<ItemCollection> explodeBanks(ItemCollection workitem) {
List<ItemCollection> ibanList = new ArrayList();
List<Object> mapOrderItems = workitem.getItemValue(BusinessPartnerService.ITEM_IBAN_LIST);
Iterator<?> var4 = mapOrderItems.iterator();
while (var4.hasNext()) {
Object mapOderItem = var4.next();
if (mapOderItem instanceof Map) {
ItemCollection itemCol = new ItemCollection((Map) mapOderItem);
ibanList.add(itemCol);
}
}
return ibanList;
}
/**
* Liefert die ChildItems mit den IBAN daten
*
* @param workitem
* @return
*/
public static List<ItemCollection> getBanks(ItemCollection workitem) {
List<ItemCollection> result = new ArrayList<>();
List<Object> mapOrderItems = workitem.getItemValue(BusinessPartnerService.ITEM_IBAN_LIST);
Iterator<?> var4 = mapOrderItems.iterator();
while (var4.hasNext()) {
Object mapOderItem = var4.next();
if (mapOderItem instanceof Map) {
ItemCollection itemCol = new ItemCollection((Map) mapOderItem);
result.add(itemCol);
}
}
return result;
}
/**
* Diese Methode übertragt neue IBAN/BIC Pare in den Kreditor Banken Bereich
*
* @param cdtrNumber
* @param iban
* @param bic
* @throws PluginException
*/
public void addNewIBANBIC(ItemCollection businessPartner, String iban, String bic) throws PluginException {
if (businessPartner != null) {
List<ItemCollection> bankenListe = explodeBanks(businessPartner);
ItemCollection newbank = new ItemCollection();
// {iban=[IBAN], name=[Test Bank], id=[test ], bic=[BIC]}
newbank.setItemValue("iban", iban);
newbank.setItemValue("bic", bic);
newbank.setItemValue("id", bankenListe.size() + 1);
newbank.setItemValue("name", "Bank-" + bankenListe.size() + 1);
bankenListe.add(newbank);
implodeBanks(businessPartner, bankenListe);
documentService.save(businessPartner);
}
}
/**
* Diese Methode gibt true zurück wenn die angegebene IBAN/BIC Kombination als
* bank bereits bekannt ist
*
* @param cdtrNumber
* @param iban
* @param bic
* @throws PluginException
*/
public boolean isIBANBICKnown(ItemCollection businessPartner, String iban, String bic) throws PluginException {
if (businessPartner != null) {
List<ItemCollection> bankenListe = explodeBanks(businessPartner);
for (ItemCollection bank : bankenListe) {
if (iban.equals(bank.getItemValueString("iban"))
&& bic.equals(bank.getItemValueString("bic"))) {
// known!
return true;
}
}
}
return false;
}
}