From 1448c51e45dfe97d767dc3ba1f92a4a4b6d597f6 Mon Sep 17 00:00:00 2001 From: TheBestPessimist Date: Fri, 6 Dec 2019 11:36:56 +0200 Subject: [PATCH] Update an existing `I_C_InvoiceCandidate_InOutLine` or create a new one. https://github.com/metasfresh/metasfresh/issues/5874 --- .../invoicecandidate/api/IInvoiceCandDAO.java | 13 +++++----- .../api/impl/InvoiceCandDAO.java | 26 ++++++++++--------- .../api/impl/InvoiceCandInvalidUpdater.java | 14 +++++----- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java index dbe022ce761..b65e12e42b6 100644 --- a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java +++ b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java @@ -31,6 +31,7 @@ import java.util.Properties; import java.util.Set; +import lombok.NonNull; import org.adempiere.ad.dao.IQueryBuilder; import org.adempiere.exceptions.AdempiereException; import org.adempiere.util.lang.IContextAware; @@ -57,6 +58,8 @@ import de.metas.process.PInstanceId; import de.metas.util.ISingletonService; +import javax.annotation.Nullable; + public interface IInvoiceCandDAO extends ISingletonService { I_C_Invoice_Candidate getById(InvoiceCandidateId invoiceCandId); @@ -298,14 +301,12 @@ public interface IInvoiceCandDAO extends ISingletonService List retrieveInOutLinesForCandidate(I_C_Invoice_Candidate ic, Class clazz); /** - * Checks if there exists an allocation between given invoice candidate and given receipt/shipment line. - * - * @param ic invoice candidate - * @param iol receipt/shipment line - * @return true if an allocation exists + * Return the unique allocation between the given invoice candidate and receipt/shipment line. + * We know it's unique as there is a Unique Index on the 2 columns named C_IC_IOL_Unique_Active. * @see I_C_InvoiceCandidate_InOutLine */ - boolean existsInvoiceCandidateInOutLinesForInvoiceCandidate(I_C_Invoice_Candidate ic, I_M_InOutLine iol); + @Nullable + I_C_InvoiceCandidate_InOutLine retrieveInvoiceCandidateInOutLine(@NonNull I_C_Invoice_Candidate ic, @NonNull I_M_InOutLine iol); /** * Checks if the given ic is referenced by a C_Invoice_Candidate_Recompute record. The check is made within the ic's transaction.
diff --git a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java index 98eae9a1a16..e810d4304c9 100644 --- a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java +++ b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java @@ -363,9 +363,11 @@ public List retrieveInvoiceCandidatesForOrderLineId(@NonN .list(I_C_Invoice_Candidate.class); } + @Nullable @Override - public boolean existsInvoiceCandidateInOutLinesForInvoiceCandidate(final I_C_Invoice_Candidate ic, final I_M_InOutLine iol) + public I_C_InvoiceCandidate_InOutLine retrieveInvoiceCandidateInOutLine(@NonNull final I_C_Invoice_Candidate ic, @NonNull final I_M_InOutLine iol) { + // there is a Unique Index on the 2 columns C_IC_IOL_Unique_Active, so i'm sure there's at most 1 line return Services.get(IQueryBL.class) .createQueryBuilder(I_C_InvoiceCandidate_InOutLine.class, ic) .addEqualsFilter(I_C_InvoiceCandidate_InOutLine.COLUMN_C_Invoice_Candidate_ID, ic.getC_Invoice_Candidate_ID()) @@ -373,7 +375,7 @@ public boolean existsInvoiceCandidateInOutLinesForInvoiceCandidate(final I_C_Inv .addOnlyActiveRecordsFilter() // .create() - .anyMatch(); + .firstOnly(I_C_InvoiceCandidate_InOutLine.class); } @Override @@ -428,8 +430,8 @@ private IQueryBuilder retrieveICIOLAssociationsF .orderBy() .addColumn(I_C_InvoiceCandidate_InOutLine.COLUMN_M_InOutLine_ID) .endOrderBy() - // - ; + // + ; } @Override @@ -846,9 +848,9 @@ protected final void invalidateCandsForSelection(final PInstanceId pinstanceId, final IQueryBuilder icQueryBuilder = Services.get(IQueryBL.class) .createQueryBuilder(I_C_Invoice_Candidate.class, ctx, trxName) .setOnlySelection(pinstanceId) - // Invalidate no matter if Processed or not - // .addEqualsFilter(I_C_Invoice_Candidate.COLUMN_Processed, false) - ; + // Invalidate no matter if Processed or not + // .addEqualsFilter(I_C_Invoice_Candidate.COLUMN_Processed, false) + ; invalidateCandsFor(icQueryBuilder); // logger.info("Invalidated {} C_Invoice_Candidates for AD_PInstance_ID={}", new Object[] { count, adPInstanceId }); @@ -952,7 +954,7 @@ private final IQueryBuilder retrieveInvoiceCand if (invoiceCandidateIds == null || invoiceCandidateIds.isEmpty()) { // i.e. tag none - queryBuilder.filter(ConstantQueryFilter. of(false)); + queryBuilder.filter(ConstantQueryFilter.of(false)); } else { @@ -1271,9 +1273,9 @@ private PaymentTermId retrievePaymentTermId(final PInstanceId selectionId) * If there were any changes, those invoice candidates will be invalidated. * * @param invoiceCandidateColumnName {@link I_C_Invoice_Candidate}'s column to update - * @param value value to set (you can also use {@link ModelColumnNameValue}) - * @param updateOnlyIfNull if true then it will update only if column value is null (not set) - * @param selectionId invoice candidates selection (AD_PInstance_ID) + * @param value value to set (you can also use {@link ModelColumnNameValue}) + * @param updateOnlyIfNull if true then it will update only if column value is null (not set) + * @param selectionId invoice candidates selection (AD_PInstance_ID) */ private final void updateColumnForSelection( @NonNull final String columnName, @@ -1289,7 +1291,7 @@ private final void updateColumnForSelection( .createQueryBuilder(I_C_Invoice_Candidate.class) .setOnlySelection(selectionId) .addNotEqualsFilter(columnName, value) // skip those which have our value set - ; + ; if (updateOnlyIfNull) { selectionQueryBuilder.addEqualsFilter(columnName, null); diff --git a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandInvalidUpdater.java b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandInvalidUpdater.java index 70f1da2d62f..cbaf8fd85bb 100644 --- a/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandInvalidUpdater.java +++ b/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandInvalidUpdater.java @@ -163,7 +163,7 @@ private void updateTagged() final ICUpdateResult result = new ICUpdateResult(); try (final IAutoCloseable updateInProgressCloseable = invoiceCandBL.setUpdateProcessInProgress()) { - trxItemProcessorExecutorService. createExecutor() + trxItemProcessorExecutorService.createExecutor() .setContext(getCtx(), getTrxName()) // if called from process or wp-processor then getTrxName() is null because *we* want to manage the trx => commit after each chunk .setItemsPerBatch(itemsPerBatch) @@ -239,7 +239,7 @@ public void completeChunk() Loggables.addLog("Update invalid result: {}", result.getSummary()); } - private final void updateInvalid(final I_C_Invoice_Candidate icRecord) + private void updateInvalid(final I_C_Invoice_Candidate icRecord) { final Properties ctx = InterfaceWrapperHelper.getCtx(icRecord); @@ -354,13 +354,13 @@ private void populateC_InvoiceCandidate_InOutLine( final List inoutLines = inOutDAO.retrieveLinesForOrderLine(orderLine, I_M_InOutLine.class); for (final I_M_InOutLine inOutLine : inoutLines) { - if (invoiceCandDAO.existsInvoiceCandidateInOutLinesForInvoiceCandidate(ic, inOutLine)) + // create a new PO or update the unique existing one + I_C_InvoiceCandidate_InOutLine iciol = invoiceCandDAO.retrieveInvoiceCandidateInOutLine(ic, inOutLine); + if (iciol == null) { - continue; // nothing to to, record already exists + iciol = newInstance(I_C_InvoiceCandidate_InOutLine.class, context); + iciol.setC_Invoice_Candidate(ic); } - - final I_C_InvoiceCandidate_InOutLine iciol = newInstance(I_C_InvoiceCandidate_InOutLine.class, context); - iciol.setC_Invoice_Candidate(ic); Services.get(IInvoiceCandBL.class).updateICIOLAssociationFromIOL(iciol, inOutLine); } }