office-alexander-logistics/src/main/java/com/alexanderlogistics/ZahlungseingangSaldoAdapter.java

220 lines
No EOL
9.8 KiB
Java

package com.alexanderlogistics;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.SignalAdapter;
import org.imixs.workflow.exceptions.AdapterException;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.faces.util.ResourceBundleHandler;
import com.alexanderlogistics.mahnlauf.MahnlaufService;
import jakarta.inject.Inject;
/**
* Der ZahlungseingangSaldoAdapter korrigiert den Saldo einer Ausgangsrechnung
* anhand der Zahlungsdaten in einem Zahlungseingangsworkflow.
* <p>
* Die verknüpften Rechnungen in einem Zahlungseingang können am Item
* $workitemref ermittelt werden.
* <p>
* Relevant für den Abgleich sin die felder:
* <ul>
* <li>invoice.currency
* <li>payment.amount
* <p>
* <code>com.alexanderlogistics.ZahlungseingangSaldoAdapter</code>
*
* @version 1.0
* @author rsoika
*/
public class ZahlungseingangSaldoAdapter implements SignalAdapter {
private static Logger logger = Logger.getLogger(ZahlungseingangSaldoAdapter.class.getName());
@Inject
ZahlungseingangService zahlungseingangService;
@Inject
BusinessPartnerService businessPartnerService;
@Inject
InvoiceService invoiceService;
@Inject
ResourceBundleHandler resourceBundleHandler;
/**
* This method finds the outgoing invoices and updates the saldo
* (payment.total).
*
* @throws PluginException
*/
@Override
public ItemCollection execute(ItemCollection document, ItemCollection event)
throws AdapterException, PluginException {
updateSaldo(document);
// Update Debitor E-Mail
String bpid = InvoiceUtil.buildBPID(document.getItemValueString("dbtr.number"));
ItemCollection dbtrItemCol = businessPartnerService.getBusinessPartnerByID(bpid);
if (dbtrItemCol != null) {
document.setItemValue(MahnlaufService.ITEM_DBTR_EMAIL, dbtrItemCol.getItemValue("dbtr.mail"));
}
return document;
}
/**
* Diese methode aktuallisiert alle referenzen der aktuellen Rechnungen
*
* @param workitem
* @throws PluginException
*/
private void updateSaldo(ItemCollection workitem) throws PluginException {
// payment currency
String paymentCurrency = workitem.getItemValueString("payment.currency");
double masterPaymentAmount = workitem.getItemValueDouble("payment.amount");
double masterPaymentDifference = workitem.getItemValueDouble("payment.difference");
String paymentWarning = workitem.getItemValueString("payment.warning");
List<ItemCollection> paymentDetails = zahlungseingangService.loadPaymentDetails(workitem);
// get all Invoices of this Mahnlauf
List<Map<String, List<Object>>> invoiceList = new ArrayList<Map<String, List<Object>>>();
if (paymentDetails.size() == 0) {
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
"Bitte wählen Sie die zugeordneten Rechnungen aus.");
}
logger.info("......Updating " + paymentDetails.size() + " outgoing invoices....");
// Erst müssen wir einmal prüfen ob alle einzel salden ungleich dem
// MasterPamyneAmmoutn sind!
double einzelPayments = 0;
for (ItemCollection payment : paymentDetails) {
einzelPayments = einzelPayments + payment.getItemValueFloat("payment.amount");
}
// Prüfe auf Plausisbilität
if (paymentWarning.isEmpty()) {
// falls mehr einzelsummen eingeben wurden als der oben angegeben Total Pamyment
// dann soll eine Warnung ausgegen werden.
if (InvoiceUtil.round(masterPaymentAmount + masterPaymentDifference) != InvoiceUtil.round(einzelPayments)) {
workitem.setItemValue("payment.warning", "invalid saldo");
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT2");
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
}
for (ItemCollection payment : paymentDetails) {
ItemCollection invoice = zahlungseingangService.findInvoice(payment.getUniqueID());
if (invoice != null) {
String invoiceNumber = invoice.getItemValueString("invoice.number");
String invoiceCurrency = invoice.getItemValueString("invoice.currency");
float invoiceSaldo = invoice.getItemValueFloat("invoice.saldo");
float invoicePaymentAmount = payment.getItemValueFloat("payment.amount");
float invoiceRate = invoice.getItemValueFloat("invoice.rate");
String mainCurrency = invoiceService.getCurrenciesOutMain();
if ((!invoiceCurrency.equals(paymentCurrency))
&& (!invoiceCurrency.equals(mainCurrency) && !paymentCurrency.equals(mainCurrency))) {
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT4");
message = message.replace("{1}", mainCurrency);
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
if (!invoiceCurrency.equals(paymentCurrency)) {
if (invoiceRate == 0) {
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT1");
message = message.replace("{1}", paymentCurrency);
message = message.replace("{2}", invoiceNumber);
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
}
/**
* Falls die Währung der Rechnung von der Währung der Zahlung abweicht, dann
* rechnen wir den PaymentAmmout mit der Rate aus.
*/
if ("EUR".equals(paymentCurrency) && !invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
invoicePaymentAmount = invoicePaymentAmount * invoiceRate;
// runde auf 2 Stellen
invoicePaymentAmount = (float) InvoiceUtil.round(invoicePaymentAmount);
}
// vergeiche Restsaldo mit payment für diese Rechnung
if (!isPaymentBooked(workitem) && Math.abs(InvoiceUtil.round(invoicePaymentAmount)) > Math
.abs(InvoiceUtil.round(invoiceSaldo))) {
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT3");
message = message.replace("{1}", invoiceNumber);
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
// jetzt den Rechnungsbetrag verkleinern
// Falls die Rechnung bereits 5900 (Bezahlt) ist wird der Saldo korrigiert und
// wieder aufgerechnet
if (isPaymentBooked(workitem)) {
// STORNO
invoiceSaldo = invoiceSaldo + invoicePaymentAmount;
} else {
invoiceSaldo = invoiceSaldo - invoicePaymentAmount;
}
invoiceSaldo = (float) InvoiceUtil.round(invoiceSaldo);
invoice.setItemValue("invoice.saldo", InvoiceUtil.roundToFloat(invoiceSaldo));
invoice.event(ZahlungseingangService.EVENT_UPDATE_INVOICE);
zahlungseingangService.processInvoice(invoice);
// create a workitem stub for the mail message
ItemCollection invoiceStub = new ItemCollection();
invoiceStub.setItemValue("invoice.number", invoice.getItemValue("invoice.number"));
invoiceStub.setItemValue("invoice.total", invoice.getItemValue("invoice.total"));
invoiceStub.setItemValue("invoice.saldo", invoice.getItemValue("invoice.saldo"));
invoiceStub.setItemValue("payment.amount", invoicePaymentAmount);
invoiceStub.setItemValue("invoice.currency", invoice.getItemValue("invoice.currency"));
invoiceStub.setItemValue("invoice.date", invoice.getItemValue("invoice.date"));
invoiceStub.setItemValue("invoice.duedate", invoice.getItemValue("invoice.duedate"));
invoiceStub.setItemValue("$workflowstatus", invoice.getItemValue("$workflowstatus"));
invoiceStub.setItemValue("$workflowsummary", invoice.getItemValue("$workflowsummary"));
// test if we have a international status translation..
if (!invoice.getItemValueString("workflowstatus_en").isEmpty()) {
invoiceStub.setItemValue("workflowstatus_en", invoice.getItemValue("workflowstatus_en"));
} else {
// default
invoiceStub.setItemValue("workflowstatus_en", invoice.getItemValue("$workflowstatus"));
}
invoiceList.add(invoiceStub.getAllItems());
} else {
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, "Invoice not found!");
}
}
workitem.replaceItemValue("payment.details.mail", invoiceList);
}
/**
* Returns true wenn der Zahlungseingang bereits gebucht ist
*
* @param workitem
* @return
*/
public boolean isPaymentBooked(ItemCollection workitem) {
return (workitem.getTaskID() == 1900);
}
}