From 93263280dc3a563ff679f8160f24d4417d55289b Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Mon, 31 Mar 2025 20:42:56 +0200 Subject: [PATCH] update --- .../office/journal/JournalAccounting.java | 206 ------------- .../journal/JournalAccountingAttribute.java | 95 ------ .../journal/JournalAccountingService.java | 270 ------------------ .../src/main/resources/imixs.properties | 2 +- workflow/analyse-debitor-de-1.0.0.bpmn | 8 +- 5 files changed, 5 insertions(+), 576 deletions(-) delete mode 100644 office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccounting.java delete mode 100644 office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingAttribute.java delete mode 100644 office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingService.java diff --git a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccounting.java b/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccounting.java deleted file mode 100644 index 0695dce..0000000 --- a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccounting.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.imixs.workflow.office.journal; - -import java.math.BigDecimal; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import org.imixs.workflow.ItemCollection; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.Temporal; -import jakarta.persistence.TemporalType; - -@Entity -@Table(name = "journal_accounting") -public class JournalAccounting { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(precision = 19, scale = 4, nullable = false) - private BigDecimal amount; - - // base amount (optional) - @Column(precision = 19, scale = 4) - private BigDecimal baseAmount; - - // ISO currency code (e.g. "USD", "GBP") - @Column(length = 3) - private String currency; - - // exchange rate (foreign currency -> base currency) - @Column(precision = 19, scale = 6) - private BigDecimal exchangeRate; - - @Column() - private String reference; - - @Column() - private String workflowGroup; - - @Column() - private String modelVersion; - - @Column() - private int taskId; - - @Temporal(TemporalType.DATE) - @Column(nullable = false) - private Date date; - - @Column(nullable = false) - private String type; - - @OneToMany(mappedBy = "journalAccounting", cascade = CascadeType.ALL, orphanRemoval = true) - private Set attributes = new HashSet<>(); - - // Constructors - public JournalAccounting() { - } - - public JournalAccounting(ItemCollection workitem) { - updateWorkitem(workitem); - } - - public void updateWorkitem(ItemCollection workitem) { - this.reference = workitem.getUniqueID(); - this.workflowGroup = workitem.getWorkflowGroup(); - this.modelVersion = workitem.getModelVersion(); - this.taskId = workitem.getTaskID(); - this.type = workitem.getType(); - } - - // Helper methods for attribute management - public void addAttribute(String key, String value) { - JournalAccountingAttribute attr = new JournalAccountingAttribute(this, key, value); - attributes.add(attr); - } - - public String getAttribute(String key) { - return attributes.stream() - .filter(a -> a.getKey().equals(key)) - .map(JournalAccountingAttribute::getValue) - .findFirst() - .orElse(null); - } - - public void removeAttribute(String key) { - attributes.removeIf(attr -> attr.getKey().equals(key)); - } - - public Set getAttributesByKey(String key) { - Set result = new HashSet<>(); - for (JournalAccountingAttribute attr : attributes) { - if (attr.getKey().equals(key)) { - result.add(attr); - } - } - return result; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public BigDecimal getAmount() { - return amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public BigDecimal getBaseAmount() { - return baseAmount; - } - - public void setBaseAmount(BigDecimal baseAmount) { - this.baseAmount = baseAmount; - } - - public String getCurrency() { - return currency; - } - - public void setCurrency(String currency) { - this.currency = currency; - } - - public BigDecimal getExchangeRate() { - return exchangeRate; - } - - public void setExchangeRate(BigDecimal exchangeRate) { - this.exchangeRate = exchangeRate; - } - - public String getReference() { - return reference; - } - - public void setReference(String businessProcessReference) { - this.reference = businessProcessReference; - } - - public String getWorkflowGroup() { - return workflowGroup; - } - - public void setWorkflowGroup(String workflowGroup) { - this.workflowGroup = workflowGroup; - } - - public String getModelVersion() { - return modelVersion; - } - - public void setModelVersion(String modelVersion) { - this.modelVersion = modelVersion; - } - - public int getTaskId() { - return taskId; - } - - public void setTaskId(int taskId) { - this.taskId = taskId; - } - - public Date getDate() { - return date; - } - - public void setDate(Date entryDate) { - this.date = entryDate; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - -} diff --git a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingAttribute.java b/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingAttribute.java deleted file mode 100644 index 28fc971..0000000 --- a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingAttribute.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.imixs.workflow.office.journal; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; - -@Entity -@Table(name = "journal_accounting_attribute") -public class JournalAccountingAttribute { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(optional = false) - private JournalAccounting journalAccounting; - - @Column(nullable = false) - private String key; - - @Column(nullable = false) - private String value; - - // Constructors - public JournalAccountingAttribute() { - } - - public JournalAccountingAttribute(JournalAccounting journalAccounting, String key, String value) { - this.journalAccounting = journalAccounting; - this.key = key; - this.value = value; - } - - // Standard getters and setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public JournalAccounting getJournalAccounting() { - return journalAccounting; - } - - public void setJournalAccounting(JournalAccounting journalAccounting) { - this.journalAccounting = journalAccounting; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - // Equals and hashCode for proper collection behavior - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - JournalAccountingAttribute that = (JournalAccountingAttribute) o; - - if (id != null ? !id.equals(that.id) : that.id != null) - return false; - if (!key.equals(that.key)) - return false; - return value.equals(that.value); - } - - @Override - public int hashCode() { - int result = id != null ? id.hashCode() : 0; - result = 31 * result + key.hashCode(); - result = 31 * result + value.hashCode(); - return result; - } -} \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingService.java b/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingService.java deleted file mode 100644 index 14e1f19..0000000 --- a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/journal/JournalAccountingService.java +++ /dev/null @@ -1,270 +0,0 @@ -/******************************************************************************* - * 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 org.imixs.workflow.office.journal; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.List; - -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.exceptions.AccessDeniedException; -import org.imixs.workflow.faces.data.WorkflowEvent; - -import com.alexanderlogistics.InvoiceUtil; - -import jakarta.annotation.security.DeclareRoles; -import jakarta.annotation.security.RolesAllowed; -import jakarta.annotation.security.RunAs; -import jakarta.ejb.Stateless; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.persistence.TypedQuery; - -/** - * 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" }) -@Stateless -@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") -public class JournalAccountingService { - - @PersistenceContext(unitName = "org.imixs.workflow.jpa") - private EntityManager entityManager; - - @Inject - DocumentService documentService; - - /** - * WorkflowEvent listener to store an accounting entry - * - * Demo: - * invoice: - * http://localhost:8080/pages/workitems/workitem.xhtml?id=a6524e28-eb06-4a0d-ae2f-f0cac29b126f - * payment: - * http://localhost:8080/pages/workitems/workitem.xhtml?id=e2aa082f-7e61-4cbe-abc8-be06d1aacc3f - * - * @param workflowEvent - * @throws AccessDeniedException - */ - public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException { - - ItemCollection workitem = workflowEvent.getWorkitem(); - if (workitem == null) { - return; - } - if (WorkflowEvent.WORKITEM_AFTER_PROCESS == workflowEvent.getEventType()) { - - // create / update? - if (workitem.getModelVersion().startsWith("rechnungsausgang-")) { - processInvoice(workitem); - } - - // Payment? - if (workitem.getModelVersion().startsWith("zahlungseingang-")) { - processPayment(workitem); - } - } - } - - /** - * Process an invoice workitem - creates or updates accounting entry - * - * The reference is the uniqueId of the invoice. - */ - private void processInvoice(ItemCollection workitem) { - - // Try to find existing entry - JournalAccounting accounting = findAccountingEntryByInvoice(workitem.getUniqueID()); - - // Create new or update existing - if (accounting == null) { - accounting = new JournalAccounting(workitem); - } else { - accounting.updateWorkitem(workitem); - } - - // Update/set values - accounting.setDate(workitem.getItemValueDate("invoice.date")); - - BigDecimal amount = BigDecimal.valueOf(workitem.getItemValueDouble("invoice.total")) - .setScale(2, RoundingMode.HALF_UP); - accounting.setAmount(amount); - accounting.setCurrency(workitem.getItemValueString("invoice.currency")); - // foreign currency - if (workitem.getItemValueDouble("invoice.rate") != 0.0) { - // YES - BigDecimal exchangeRate = BigDecimal.valueOf(workitem.getItemValueDouble("invoice.rate")) - .setScale(6, RoundingMode.HALF_UP); - // Hauswährung = Fremdwährung * Wechselkurs (auf 2 Stellen gerundet) - BigDecimal baseAmount = amount.divide(exchangeRate, 6, RoundingMode.HALF_UP).setScale(2, - RoundingMode.HALF_UP); - accounting.setExchangeRate(exchangeRate); - accounting.setBaseAmount(baseAmount); - - } else { - // NO - accounting.setExchangeRate(null); - accounting.setBaseAmount(null); - } - - // Update attributes - // Clear and add attributes (or use selective update if needed) - accounting.getAttributes().clear(); - accounting.addAttribute("dbtr.name", workitem.getItemValueString("dbtr.name")); - accounting.addAttribute("dbtr.number", workitem.getItemValueString("dbtr.number")); - accounting.addAttribute("space.name", workitem.getItemValueString("space.name")); - accounting.addAttribute("country", workitem.getItemValueString("invoice.country")); - - // Persist or merge - if (accounting.getId() == null) { - entityManager.persist(accounting); - } else { - entityManager.merge(accounting); - } - } - - /** - * Process a payment workitem - creates entries and links to invoices - */ - private void processPayment(ItemCollection workitem) { - List paymentDetails = InvoiceUtil.explodeChildList(workitem, "payment.details"); - - for (ItemCollection payment : paymentDetails) { - // load the invoice document - String invoiceRef = payment.getItemValueString("$uniqueid"); - ItemCollection invoice = documentService.load(invoiceRef); - - BigDecimal amount = BigDecimal.valueOf(-payment.getItemValueDouble("payment.amount")) - .setScale(2, RoundingMode.HALF_UP); - - // Find existing payment entry or create new one - JournalAccounting accounting = findAccountingEntryByPaymentReference(invoice.getUniqueID(), - workitem.getUniqueID()); - if (accounting == null) { - accounting = new JournalAccounting(workitem); - } else { - // update - accounting.updateWorkitem(workitem); - } - - // set reference to invoice - accounting.setReference(invoice.getUniqueID()); - - // Update payment values - accounting.setDate(workitem.getItemValueDate("payment.date")); - - accounting.setCurrency(invoice.getItemValueString("invoice.currency")); - accounting.setAmount(amount); - // foreign currency - if (invoice.getItemValueDouble("invoice.rate") != 0.0) { - // YES - BigDecimal exchangeRate = BigDecimal.valueOf(invoice.getItemValueDouble("invoice.rate")) - .setScale(6, RoundingMode.HALF_UP); - // Hauswährung = Fremdwährung * Wechselkurs (auf 2 Stellen gerundet) - BigDecimal baseAmount = amount.divide(exchangeRate, 6, RoundingMode.HALF_UP).setScale(2, - RoundingMode.HALF_UP); - accounting.setExchangeRate(exchangeRate); - accounting.setBaseAmount(baseAmount); - } else { - // NO - accounting.setExchangeRate(null); - accounting.setBaseAmount(null); - } - - // Update attributes - // Clear and add attributes (or use selective update if needed) - accounting.getAttributes().clear(); - accounting.addAttribute("payment.reference", workitem.getUniqueID()); - accounting.addAttribute("dbtr.name", workitem.getItemValueString("dbtr.name")); - accounting.addAttribute("dbtr.number", workitem.getItemValueString("dbtr.number")); - accounting.addAttribute("space.name", workitem.getItemValueString("space.name")); - - // Persist or merge - if (accounting.getId() == null) { - entityManager.persist(accounting); - } else { - entityManager.merge(accounting); - } - } - } - - /** - * Find an accounting entry by its business process reference - */ - private JournalAccounting findAccountingEntryByInvoice(String uniqueId) { - try { - return entityManager.createQuery( - "SELECT a FROM JournalAccounting a " + - "WHERE a.reference = :ref ", - JournalAccounting.class) - .setParameter("ref", uniqueId) - .getSingleResult(); - } catch (Exception e) { - // No result found - return null; - } - } - - /** - * Find an invoice accounting entry pointing to a given payment reference - * - * @param invoiceReference - * @param paymentReference - * @return - */ - public JournalAccounting findAccountingEntryByPaymentReference(String invoiceReference, String paymentReference) { - try { - String jpql = "SELECT account FROM JournalAccounting account " + - "JOIN account.attributes atr " + - "WHERE account.reference = :reference " + - "AND atr.key = 'payment.reference' AND atr.value = :paymentReference"; - - TypedQuery query = entityManager.createQuery(jpql, JournalAccounting.class); - query.setParameter("reference", invoiceReference); - query.setParameter("paymentReference", paymentReference); - - return query.getSingleResult(); - } catch (Exception e) { - // No result found - return null; - } - } -} diff --git a/office-alexander-logistics-app/src/main/resources/imixs.properties b/office-alexander-logistics-app/src/main/resources/imixs.properties index fb391ca..6e4d783 100644 --- a/office-alexander-logistics-app/src/main/resources/imixs.properties +++ b/office-alexander-logistics-app/src/main/resources/imixs.properties @@ -5,7 +5,7 @@ lucence.indexDir=${imixs-office.IndexDir} index.fields=txtsearchstring,txtSubject,txtname,txtEmail,txtUserName,namCreator,txtworkflowgroup,txtworkflowstatus,txtWorkflowAbstract,txtWorkflowSummary,txtworkflowhistory,txtspacename,txtprocessname,_subject,_description,_name,_projectnumber,_projectname,_ordernumber,_contractnumber,datDueDate,txtcommentlog,htmldescription,htmldocumentation,dms,dms_names,invoice.number.stripped,_childitems,$file.names,_VENDOR_NAME,dbtr.number,cdtr.number,invoice.positions,invoice.atc.number index.fields.analyze=txtUsername index.fields.noanalyze=type,$UniqueIDRef,$created,$modified,$ModelVersion,$participants,namCreator,$ProcessID,datDate,txtWorkflowGroup,txtemail, datdate, datfrom, datto, numsequencenumber,sequencenumber,dms_count,invoice.number,invoice.number.stripped,invoice.date,invoice.duedate,taxonomy.verteilung.stop,taxonomy.sachpruefung.stop,taxonomy.verteilung.start,taxonomy.sachpruefung.start,taxonomy.buchhaltung.start,taxonomy.buchhaltung.stop,dbtr.number,cdtr.number,payment.date,invoice.total,invoice.currency,invoice.positions,$lasteventdate,payment.type,cdtr.name,document.company,invoice.atc.number -index.fields.store=process.name,txtProcessName,txtWorkflowImageURL,payment.date,invoice.number,invoice.date,invoice.duedate +index.fields.store=process.name,txtProcessName,txtWorkflowImageURL,payment.date,invoice.number,invoice.date,invoice.duedate,invoice.total,invoice.currency,dbtr.name,cdtr.name index.fields.category=space.name,space.ref,taxonomy.verteilung.stop.by,taxonomy.sachpruefung.stop.by,taxonomy.buchhaltung.stop.by office.search.noanalyze=invoice.number,invoice.number.stripped,invoice.positions diff --git a/workflow/analyse-debitor-de-1.0.0.bpmn b/workflow/analyse-debitor-de-1.0.0.bpmn index f3d64ef..a596cfc 100644 --- a/workflow/analyse-debitor-de-1.0.0.bpmn +++ b/workflow/analyse-debitor-de-1.0.0.bpmn @@ -75,10 +75,10 @@ th { font-weight: bold;} - + - + StartEvent_1 @@ -458,8 +458,8 @@ th { font-weight: bold;} - - + +