anpassung invoice bp sync

This commit is contained in:
Ralph Soika 2025-04-27 10:53:17 +02:00
parent 5aa7113d7f
commit ac4127e353
10 changed files with 6271 additions and 29 deletions

View file

@ -20,6 +20,11 @@
ACHTUNG kann sehr sehr sehr!! lange laufen (3 Stunde) ACHTUNG kann sehr sehr sehr!! lange laufen (3 Stunde)
kann aber auch dann mehrfach aufgerufen werden so dass sich das alles zum guten wendet kann aber auch dann mehrfach aufgerufen werden so dass sich das alles zum guten wendet
- Modelle Anpassen
in allen Rechnungsmodellen müssen die alten form parts `alexander/cdtreingabe` und `alexander/dbtreingabe` mit dem neuen `alexander/businesspartner_search` ausgetauscht werden.
Der `BusinessPartnerController` bzw. das `InvoicePlugin` bzw. `InvoiceOutgoingPlugin` kümmert sich automatisch um die Migration
### 1.3.3 ### 1.3.3
- Imixs-Archive 3.1.1. Compactor Sevrvice - Imixs-Archive 3.1.1. Compactor Sevrvice

View file

@ -124,15 +124,46 @@ public class BusinessPartnerService {
* Die Methode wirft eine PluginException falls das BusinessPartner Objekt * Die Methode wirft eine PluginException falls das BusinessPartner Objekt
* gesperrt oder in verification ist! * 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 partnerID
* @param workitem * @param workitem
* @throws PluginException * @throws PluginException
*/ */
public void updateBusinessPartner(String partnerID, ItemCollection workitem) throws PluginException { public void updateBusinessPartnerData(ItemCollection workitem) throws PluginException {
workitem.setItemValue("partner.id", partnerID); 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); ItemCollection businessPartner = getBusinessPartnerByID(partnerID);
if (businessPartner != null) { if (businessPartner != null) {
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name")); 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) { if (businessPartner.getTaskID() == TASK_VERIFICATION) {
throw new PluginException(InvoicePlugin.class.getName(), throw new PluginException(InvoicePlugin.class.getName(),
ERROR_BUSINESSPARTNER_VERIFICATION, ERROR_BUSINESSPARTNER_VERIFICATION,
@ -143,7 +174,7 @@ public class BusinessPartnerService {
ERROR_BUSINESSPARTNER_LOCKED, ERROR_BUSINESSPARTNER_LOCKED,
"Businesspartner is locked. Invoice can't be processed!"); "Businesspartner is locked. Invoice can't be processed!");
} }
// update business partner object... // update business partner status...
try { try {
if (businessPartner.getTaskID() == TASK_INACTIVE) { if (businessPartner.getTaskID() == TASK_INACTIVE) {
// Workitem erneut aktivieren // Workitem erneut aktivieren

View file

@ -31,17 +31,12 @@ public class InvoiceOutgoingPlugin extends AbstractPlugin {
@Override @Override
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException { public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
// Update BUsiness Partner Data
businessPartnerService.updateBusinessPartnerData(workitem);
// Update Invoice.positions // Update Invoice.positions
InvoiceUtil.updateInvoicePositions(workitem); InvoiceUtil.updateInvoicePositions(workitem);
String dbtrNumber = workitem.getItemValueString("dbtr.number");
ItemCollection debitor = kreditorService.findDebitor(dbtrNumber);
if (debitor != null) {
// update mail and country
workitem.setItemValue("dbtr.mail", debitor.getItemValueString("cdtr.mail"));
workitem.setItemValue("invoice.country", debitor.getItemValueString("_vendor_country"));
}
String img = ""; String img = "";
if (workitem.getItemValueBoolean("invoice.protest")) { if (workitem.getItemValueBoolean("invoice.protest")) {
img = img + "<img title='Reklamiert' src=\"/layout/icons/icon106.png\">"; img = img + "<img title='Reklamiert' src=\"/layout/icons/icon106.png\">";
@ -49,10 +44,6 @@ public class InvoiceOutgoingPlugin extends AbstractPlugin {
} }
workitem.setItemValue("_img", img); workitem.setItemValue("_img", img);
// Update BUsiness Partner Data
String partnerID = InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number"));
businessPartnerService.updateBusinessPartner(partnerID, workitem);
return workitem; return workitem;
} }

View file

@ -37,7 +37,7 @@ import jakarta.inject.Inject;
* 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von * 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von
* Sofortüberweisung, Mahnung und Ablehnung anzeigt. * Sofortüberweisung, Mahnung und Ablehnung anzeigt.
* *
* 26.4.25 - Das Plugin setzt nun auch bpid.name und bpid * 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id
* zusätzlich processed es das BP Workitem * zusätzlich processed es das BP Workitem
* *
* @author rsoika * @author rsoika
@ -87,6 +87,9 @@ public class InvoicePlugin extends AbstractPlugin {
@Override @Override
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException { public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
// Update BUsiness Partner Data
businessPartnerService.updateBusinessPartnerData(workitem);
updateImg(workitem); updateImg(workitem);
// Update Invoice.positions // Update Invoice.positions
@ -208,10 +211,6 @@ public class InvoicePlugin extends AbstractPlugin {
} }
// Update BUsiness Partner Data
String partnerID = InvoiceUtil.buildBPID(workitem.getItemValueString("cdtr.number"));
businessPartnerService.updateBusinessPartner(partnerID, workitem);
return workitem; return workitem;
} }

View file

@ -249,4 +249,19 @@ public class InvoiceUtil {
} }
return result; return result;
} }
/**
* Gibt true zurück wenn es sich um eine Debitoren Rechnung/Gutschrift handelt.
*
* @param invoice
* @return
*/
public static boolean isDebitorInvoice(ItemCollection invoice) {
boolean result = false;
if (invoice.getModelVersion().startsWith("rechnungsausgang")) {
result = true;
}
return result;
}
} }

View file

@ -5,7 +5,7 @@
<!-- businsspartner Search integration <!-- businsspartner Search integration
This subform is a custom form part. This subform is a custom form part for the items 'item.id' and 'item.name'
The subform provides a jsf commandScript which calls the businessPartnerController.search method in the backend. The subform provides a jsf commandScript which calls the businessPartnerController.search method in the backend.
@ -18,12 +18,12 @@
https://www.w3schools.com/howto/howto_js_autocomplete.asp https://www.w3schools.com/howto/howto_js_autocomplete.asp
--> -->
<ui:param name="item_konto_name" value="#{item.name}.name"></ui:param>
<ui:fragment rendered="#{!readonly}"> <ui:fragment rendered="#{!readonly}">
<h:inputText value="#{workitem.item[item.name]}" pt:data-item="#{item.name}" /> <h:inputText value="#{workitem.item['partner.id']}" pt:data-item="partner.id" />
<h:inputHidden value="#{workitem.item[item_konto_name]}" pt:data-item="#{item_konto_name}" /> <h:inputHidden value="#{workitem.item['partner.name']}" pt:data-item="partner.name" />
<br /> <br />
<span id='businsspartner-konto-id' class='small'>#{workitem.item[item_konto_name]}</span> <span id='businsspartner-konto-id' class='small'>#{workitem.item['partner.name']}</span>
<h:commandScript name="businsspartnerSearch" action="#{businessPartnerController.search(options)}" <h:commandScript name="businsspartnerSearch" action="#{businessPartnerController.search(options)}"
render="autocomplete-resultlist-businsspartner" onevent="autocompleteShowResult" /> render="autocomplete-resultlist-businsspartner" onevent="autocompleteShowResult" />
@ -33,20 +33,21 @@
// init input fields... // init input fields...
$(document).ready(function () { $(document).ready(function () {
// add autocomplete feature .. // add autocomplete feature ..
var creditorField = $("input[data-item='#{item.name}']"); var creditorField = $("input[data-item='partner.id']");
$(creditorField).each(function () { $(creditorField).each(function () {
$(this).addClass("imixs-ml"); $(this).addClass("imixs-ml");
autocompleteInitInput(this, businsspartnerSearch, 'autocomplete-resultlist-businsspartner', selectDebitorCreditorCallback); autocompleteInitInput(this, businsspartnerSearch, 'autocomplete-resultlist-businsspartner', selectDebitorCreditorCallback);
}); });
}); });
// Hier bekommen wir die JSON Struktur mit allen daten. // Hier bekommen wir die JSON Struktur mit allen Daten.
// diese Daten werden auf die einzelnen Felder verteilt. // diese Daten werden auf die einzelnen Felder verteilt.
function selectDebitorCreditorCallback(selection) { function selectDebitorCreditorCallback(selection) {
const kontoData = JSON.parse(selection); const kontoData = JSON.parse(selection);
// fill data into the fields.... // fill data into the fields....
var inputElementKonto = $("input[data-item='#{item.name}']"); var inputElementKonto = $("input[data-item='partner.id']");
var inputElementKreditor = $("input[data-item='#{item_konto_name}']"); var inputElementKreditor = $("input[data-item='partner.name']");
inputElementKonto.val(kontoData.name); inputElementKonto.val(kontoData.name);
inputElementKreditor.val(kontoData['partner.name']); inputElementKreditor.val(kontoData['partner.name']);
// remove old konto name // remove old konto name

View file

@ -89,6 +89,9 @@
<imixs:item name="namaddwriteaccess" type="xs:string"> <imixs:item name="namaddwriteaccess" type="xs:string">
<imixs:value/> <imixs:value/>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_a83GTA"/> <bpmn2:documentation id="documentation_a83GTA"/>
<bpmn2:incoming>sequenceFlow_25otUg</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_25otUg</bpmn2:incoming>
@ -140,6 +143,9 @@
<imixs:item name="keyaddwritefields" type="xs:string"> <imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[process.team]]></imixs:value> <imixs:value><![CDATA[process.team]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_M7b42w"/> <bpmn2:documentation id="documentation_M7b42w"/>
<bpmn2:incoming>sequenceFlow_avahXg</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_avahXg</bpmn2:incoming>
@ -374,6 +380,9 @@
<imixs:item name="keyaddwritefields" type="xs:string"> <imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[process.team]]></imixs:value> <imixs:value><![CDATA[process.team]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_1TuLXg"/> <bpmn2:documentation id="documentation_1TuLXg"/>
<bpmn2:outgoing>sequenceFlow_NNbMhg</bpmn2:outgoing> <bpmn2:outgoing>sequenceFlow_NNbMhg</bpmn2:outgoing>

View file

@ -89,6 +89,9 @@
<imixs:item name="namaddwriteaccess" type="xs:string"> <imixs:item name="namaddwriteaccess" type="xs:string">
<imixs:value/> <imixs:value/>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_a83GTA"/> <bpmn2:documentation id="documentation_a83GTA"/>
<bpmn2:incoming>sequenceFlow_25otUg</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_25otUg</bpmn2:incoming>
@ -140,6 +143,9 @@
<imixs:item name="keyaddwritefields" type="xs:string"> <imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[process.team]]></imixs:value> <imixs:value><![CDATA[process.team]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_M7b42w"/> <bpmn2:documentation id="documentation_M7b42w"/>
<bpmn2:incoming>sequenceFlow_avahXg</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_avahXg</bpmn2:incoming>
@ -377,6 +383,9 @@
<imixs:item name="keyaddwritefields" type="xs:string"> <imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[process.team]]></imixs:value> <imixs:value><![CDATA[process.team]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txttype" type="xs:string">
<imixs:value><![CDATA[workitem]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_1TuLXg"/> <bpmn2:documentation id="documentation_1TuLXg"/>
<bpmn2:outgoing>sequenceFlow_NNbMhg</bpmn2:outgoing> <bpmn2:outgoing>sequenceFlow_NNbMhg</bpmn2:outgoing>

View file

@ -1611,6 +1611,9 @@ result.isValid=true;
<bpmn2:sequenceFlow id="sequenceFlow_OttgXA" sourceRef="event_iUSXSg" targetRef="Task_2"> <bpmn2:sequenceFlow id="sequenceFlow_OttgXA" sourceRef="event_iUSXSg" targetRef="Task_2">
<bpmn2:documentation id="documentation_W9nXJQ"/> <bpmn2:documentation id="documentation_W9nXJQ"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:association id="association_xVkeww" sourceRef="DataObject_2" targetRef="Task_1">
<bpmn2:documentation id="documentation_euQGuA"/>
</bpmn2:association>
</bpmn2:process> </bpmn2:process>
<bpmn2:process id="process_2" name="Default Process" processType="Public"> <bpmn2:process id="process_2" name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_J67Rkw"/> <bpmn2:documentation id="documentation_J67Rkw"/>
@ -2096,6 +2099,12 @@ result.isValid=true;
<di:waypoint x="766.0" y="257.0"/> <di:waypoint x="766.0" y="257.0"/>
<di:waypoint x="766.0" y="280.0"/> <di:waypoint x="766.0" y="280.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_xVkeww" id="BPMNEdge_dHIjPw" sourceElement="BPMNShape_DataObject_1" targetElement="BPMNShape_Task_3">
<di:waypoint x="605.0" y="195.0"/>
<di:waypoint x="648.0" y="195.0"/>
<di:waypoint x="648.0" y="755.0"/>
<di:waypoint x="690.0" y="755.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane> </bpmndi:BPMNPlane>
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1"> <bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
<dc:Font name="arial" size="9.0"/> <dc:Font name="arial" size="9.0"/>

File diff suppressed because it is too large Load diff