Skip to content

Commit

Permalink
#4703-app - Support forum-datenaustausch.ch XML dunning
Browse files Browse the repository at this point in the history
* add API and SPI analog to invoice exporting

#4703
  • Loading branch information
metas-ts committed Oct 26, 2018
1 parent 348bd11 commit 7b82ed5
Show file tree
Hide file tree
Showing 36 changed files with 1,540 additions and 40 deletions.
Expand Up @@ -55,21 +55,20 @@
@Service
public class InvoiceExportService
{

private static final Logger logger = LogManager.getLogger(InvoiceExportService.class);

private final InvoiceToExportFactory exportInvoiceFactory;
private final InvoiceToExportFactory invoiceToExportFactory;

private final InvoiceExportServiceRegistry invoiceExportServiceRegistry;

private final AttachmentEntryService attachmentEntryService;

private InvoiceExportService(
@NonNull final InvoiceToExportFactory exportInvoiceFactory,
@NonNull final InvoiceToExportFactory invoiceToExportFactory,
@NonNull final InvoiceExportServiceRegistry invoiceExportServiceRegistry,
@NonNull final AttachmentEntryService attachmentEntryService)
{
this.exportInvoiceFactory = exportInvoiceFactory;
this.invoiceToExportFactory = invoiceToExportFactory;
this.invoiceExportServiceRegistry = invoiceExportServiceRegistry;
this.attachmentEntryService = attachmentEntryService;
}
Expand All @@ -78,7 +77,7 @@ public void exportInvoices(@NonNull final ImmutableList<InvoiceId> invoiceIdsToE
{
for (final InvoiceId invoiceIdToExport : invoiceIdsToExport)
{
final InvoiceToExport invoiceToExport = exportInvoiceFactory.getById(invoiceIdToExport);
final InvoiceToExport invoiceToExport = invoiceToExportFactory.getCreateForId(invoiceIdToExport);
exportInvoice(invoiceToExport);
}
}
Expand Down
Expand Up @@ -75,18 +75,18 @@
@Service
public class InvoiceToExportFactory
{
private final AttachmentEntryService attachmentEntryservice;
private final AttachmentEntryService attachmentEntryService;
private final ESRPaymentInfoProvider esrPaymentInfoProvider;

public InvoiceToExportFactory(
@NonNull final AttachmentEntryService attachmentEntryservice,
@NonNull final Optional<ESRPaymentInfoProvider> esrPaymentInfoProvider)
{
this.attachmentEntryservice = attachmentEntryservice;
this.attachmentEntryService = attachmentEntryservice;
this.esrPaymentInfoProvider = esrPaymentInfoProvider.orElse(null);
}

public InvoiceToExport getById(@NonNull final InvoiceId id)
public InvoiceToExport getCreateForId(@NonNull final InvoiceId id)
{
final I_C_Invoice invoiceRecord = load(id, I_C_Invoice.class);

Expand All @@ -95,11 +95,11 @@ public InvoiceToExport getById(@NonNull final InvoiceId id)

final boolean reversal = invoiceBL.isReversal(invoiceRecord);

final String currentyStr = invoiceRecord.getC_Currency().getISO_Code();
final Money grandTotal = Money.of(invoiceRecord.getGrandTotal(), currentyStr);
final String currencyStr = invoiceRecord.getC_Currency().getISO_Code();
final Money grandTotal = Money.of(invoiceRecord.getGrandTotal(), currencyStr);

final BigDecimal allocatedAmt = Util.coalesce(allocationDAO.retrieveAllocatedAmt(invoiceRecord), ZERO);
final Money allocatedMoney = Money.of(allocatedAmt, currentyStr);
final Money allocatedMoney = Money.of(allocatedAmt, currencyStr);

final InvoiceToExport invoiceWithoutEsrInfo = InvoiceToExport
.builder()
Expand All @@ -110,7 +110,7 @@ public InvoiceToExport getById(@NonNull final InvoiceId id)
.documentNumber(invoiceRecord.getDocumentNo())
.invoiceAttachments(createInvoiceAttachments(invoiceRecord))
.invoiceDate(createInvoiceDate(invoiceRecord))
.invoiceLines(createInvoiceLines(invoiceRecord, currentyStr))
.invoiceLines(createInvoiceLines(invoiceRecord, currencyStr))
.invoiceTaxes(createInvoiceTax(invoiceRecord))
.invoiceTimestamp(invoiceRecord.getCreated().toInstant())
.isReversal(reversal)
Expand Down Expand Up @@ -188,12 +188,12 @@ private ImmutableList<InvoiceAttachment> createInvoiceAttachments(@NonNull final
.referencedRecord(invoiceRecord)
.tagSetToAnyValue(InvoiceExportClientFactory.ATTATCHMENT_TAGNAME_EXPORT_PROVIDER)
.build();
final List<AttachmentEntry> attachments = attachmentEntryservice.getByQuery(query);
final List<AttachmentEntry> attachments = attachmentEntryService.getByQuery(query);

final ImmutableList.Builder<InvoiceAttachment> invoiceAttachments = ImmutableList.builder();
for (final AttachmentEntry attachment : attachments)
{
final byte[] attachmentData = attachmentEntryservice.retrieveData(attachment.getId());
final byte[] attachmentData = attachmentEntryService.retrieveData(attachment.getId());

final boolean isSecondaryAttachment = attachment.getTagValueOrNull(InvoiceExportClientFactory.ATTATCHMENT_TAGNAME_BELONGS_TO_EXTERNAL_REFERENCE) != null;

Expand All @@ -202,7 +202,7 @@ private ImmutableList<InvoiceAttachment> createInvoiceAttachments(@NonNull final
.mimeType(attachment.getContentType())
.data(attachmentData)
.invoiceExportProviderId(attachment.getTagValue(InvoiceExportClientFactory.ATTATCHMENT_TAGNAME_EXPORT_PROVIDER))
.primaryAttrachment(!isSecondaryAttachment)
.primaryAttachment(!isSecondaryAttachment)
.build();
invoiceAttachments.add(invoiceAttachment);
}
Expand Down
Expand Up @@ -254,7 +254,7 @@ private void deleteInvoiceLines(final I_C_Invoice invoice)
}
}

@DocValidate(timings = { ModelValidator.TIMING_BEFORE_COMPLETE })
@DocValidate(timings = ModelValidator.TIMING_BEFORE_COMPLETE)
public void linkInvoiceToPaymentIfNeeded(final I_C_Invoice invoice)
{
final I_C_Order order = invoice.getC_Order();
Expand All @@ -268,7 +268,7 @@ public void linkInvoiceToPaymentIfNeeded(final I_C_Invoice invoice)
}
}

@DocValidate(timings = { ModelValidator.TIMING_AFTER_COMPLETE })
@DocValidate(timings = ModelValidator.TIMING_AFTER_COMPLETE)
public void allocateInvoiceAgainstPaymentIfNeeded(final I_C_Invoice invoice)
{
final I_C_Order order = invoice.getC_Order();
Expand All @@ -279,7 +279,7 @@ public void allocateInvoiceAgainstPaymentIfNeeded(final I_C_Invoice invoice)
}
}

@DocValidate(timings = { ModelValidator.TIMING_AFTER_COMPLETE })
@DocValidate(timings = ModelValidator.TIMING_AFTER_COMPLETE)
public void scheduleDataExport(final I_C_Invoice invoice)
{
C_Invoice_CreateExportData.scheduleOnTrxCommit(invoice);
Expand Down
25 changes: 16 additions & 9 deletions de.metas.dunning/pom.xml
Expand Up @@ -15,6 +15,7 @@
<properties>
<!-- empty property because the sql migration dir already contains a list of base directories -->
<migration-sql-basedir></migration-sql-basedir>
<metasfresh.version>10.0.0</metasfresh.version>
</properties>

<dependencies>
Expand All @@ -26,62 +27,68 @@
<dependency>
<groupId>de.metas.document.archive</groupId>
<artifactId>de.metas.document.archive.base</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>de.metas.dunning_gateway</groupId>
<artifactId>metasfresh-dunning_gateway.api</artifactId>
<version>${metasfresh.version}</version>
</dependency>

<!-- 2103: this is required for a printing handler for dunning -->
<dependency>
<groupId>de.metas.printing</groupId>
<artifactId>de.metas.printing.base</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
</dependency>

<dependency>
<groupId>de.metas.document.archive</groupId>
<artifactId>de.metas.document.archive.base</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
</dependency>

<dependency>
<groupId>de.metas.util</groupId>
<artifactId>de.metas.util</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
</dependency>

<dependency>
<groupId>de.metas.adempiere.adempiere</groupId>
<artifactId>de.metas.adempiere.adempiere.base</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>de.metas.swat</groupId>
<artifactId>de.metas.swat.base</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
</dependency>

<dependency>
<groupId>de.metas.business</groupId>
<artifactId>de.metas.business</artifactId>
<version>10.0.0</version>
<version>${metasfresh.version}</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
@@ -0,0 +1,140 @@
package de.metas.dunning.export;

import lombok.NonNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.adempiere.exceptions.AdempiereException;
import org.adempiere.util.lang.impl.TableRecordReference;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;

import ch.qos.logback.classic.Level;
import de.metas.attachments.AttachmentConstants;
import de.metas.attachments.AttachmentEntryCreateRequest;
import de.metas.attachments.AttachmentEntryService;
import de.metas.dunning.DunningDocId;
import de.metas.dunning.model.I_C_DunningDoc;
import de.metas.dunning_gateway.api.DunningExportServiceRegistry;
import de.metas.dunning_gateway.spi.DunningExportClient;
import de.metas.dunning_gateway.spi.DunningExportClientFactory;
import de.metas.dunning_gateway.spi.model.DunningExportResult;
import de.metas.dunning_gateway.spi.model.DunningToExport;
import de.metas.logging.LogManager;
import de.metas.util.ILoggable;
import de.metas.util.Loggables;
import de.metas.util.StringUtils;

/*
* #%L
* de.metas.dunning
* %%
* Copyright (C) 2018 metas GmbH
* %%
* 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 should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/

@Service
public class DunningExportService
{

private static final Logger logger = LogManager.getLogger(DunningExportService.class);

private final DunningToExportFactory dunningToExportFactory;
private final AttachmentEntryService attachmentEntryService;
private final DunningExportServiceRegistry dunningExportServiceRegistry;

private DunningExportService(
@NonNull final DunningToExportFactory dunningToExportFactory,
@NonNull final DunningExportServiceRegistry dunningExportServiceRegistry,
@NonNull final AttachmentEntryService attachmentEntryService)
{
this.attachmentEntryService = attachmentEntryService;
this.dunningToExportFactory = dunningToExportFactory;
this.dunningExportServiceRegistry = dunningExportServiceRegistry;
}

public void exportDunnings(@NonNull final ImmutableList<DunningDocId> dunningDocIds)
{
for (final DunningDocId dunningDocId : dunningDocIds)
{
final List<DunningToExport> dunningsToExport = dunningToExportFactory.getCreateForId(dunningDocId);
for (final DunningToExport dunningToExport : dunningsToExport)
{
exportDunning(dunningToExport);
}
}
}

private void exportDunning(@NonNull final DunningToExport dunningToExport)
{
final ILoggable loggable = Loggables.get().withLogger(logger, Level.DEBUG);

final List<DunningExportClient> exportClients = dunningExportServiceRegistry.createExportClients(dunningToExport);
if (exportClients.isEmpty())
{
loggable.addLog("DunningExportService - Found no DunningExportClient implementors for dunningDocId={}; dunningToExport={}", dunningToExport.getId(), dunningToExport);
return; // nothing more to do
}

final List<AttachmentEntryCreateRequest> attachmentEntryCreateRequests = new ArrayList<>();
for (final DunningExportClient exportClient : exportClients)
{
final List<DunningExportResult> exportResults = exportClient.export(dunningToExport);
for (final DunningExportResult exportResult : exportResults)
{
attachmentEntryCreateRequests.add(createAttachmentRequest(exportResult));
}
}

for (final AttachmentEntryCreateRequest attachmentEntryCreateRequest : attachmentEntryCreateRequests)
{
attachmentEntryService.createNewAttachment(
TableRecordReference.of(I_C_DunningDoc.Table_Name, dunningToExport.getId()),
attachmentEntryCreateRequest);
loggable.addLog("DunningExportService - Attached export data to dunningDocId={}; attachment={}", dunningToExport.getId(), attachmentEntryCreateRequest);
}
}

private AttachmentEntryCreateRequest createAttachmentRequest(@NonNull final DunningExportResult exportResult)
{
byte[] byteArrayData;
try
{
byteArrayData = ByteStreams.toByteArray(exportResult.getData());
}
catch (IOException e)
{
throw AdempiereException.wrapIfNeeded(e);
}

final AttachmentEntryCreateRequest attachmentEntryCreateRequest = AttachmentEntryCreateRequest
.builderFromByteArray(
exportResult.getFileName(),
byteArrayData)
.tag(AttachmentConstants.TAGNAME_IS_DOCUMENT, StringUtils.ofBoolean(true)) // other than the "input" xml with was more or less just a template, this is a document
.tag(AttachmentConstants.TAGNAME_BPARTNER_RECIPIENT_ID, Integer.toString(exportResult.getRecipientId().getRepoId()))
.tag(DunningExportClientFactory.ATTATCHMENT_TAGNAME_EXPORT_PROVIDER, exportResult.getDunningExportProviderId())
.build();
return attachmentEntryCreateRequest;
}

}

0 comments on commit 7b82ed5

Please sign in to comment.