From 33ed08604311dea0994a05fc18dcaca20dcbfe93 Mon Sep 17 00:00:00 2001 From: pvpurcarcosmin Date: Thu, 11 Jun 2020 18:38:13 +0300 Subject: [PATCH] Extend Invoice reversal API to return affected ICs https://github.com/metasfresh/metasfresh/issues/6827 --- .../rest_api/invoice/impl/InvoiceService.java | 49 +++- .../impl/CreateInvoiceCandidatesService.java | 44 +-- .../impl/InvoicesRestControllerImpl.java | 39 ++- .../JsonCreateInvoiceCandidatesResponse.java | 6 +- ...=> JsonInvoiceCandidatesResponseItem.java} | 2 +- .../response/JsonReverseInvoiceResponse.java | 39 +++ .../invoicecandidate/api/IInvoiceCandDAO.java | 44 +-- .../api/impl/InvoiceCandDAO.java | 258 +++++++++--------- 8 files changed, 280 insertions(+), 201 deletions(-) rename backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/{JsonCreateInvoiceCandidatesResponseItem.java => JsonInvoiceCandidatesResponseItem.java} (96%) create mode 100644 backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonReverseInvoiceResponse.java diff --git a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoice/impl/InvoiceService.java b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoice/impl/InvoiceService.java index d947ccc1e13..30f83247cab 100644 --- a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoice/impl/InvoiceService.java +++ b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoice/impl/InvoiceService.java @@ -4,6 +4,12 @@ import de.metas.document.engine.IDocumentBL; import de.metas.invoice.InvoiceId; import de.metas.invoice.service.IInvoiceDAO; +import de.metas.invoicecandidate.api.IInvoiceCandDAO; +import de.metas.invoicecandidate.model.I_C_Invoice_Candidate; +import de.metas.rest_api.common.JsonExternalId; +import de.metas.rest_api.common.MetasfreshId; +import de.metas.rest_api.invoicecandidates.response.JsonInvoiceCandidatesResponseItem; +import de.metas.rest_api.invoicecandidates.response.JsonReverseInvoiceResponse; import de.metas.util.Check; import de.metas.util.Services; import lombok.NonNull; @@ -13,7 +19,6 @@ import org.compiere.model.I_AD_Archive; import org.compiere.model.I_C_Invoice; import org.compiere.util.Env; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import java.util.List; @@ -44,9 +49,11 @@ @Service public class InvoiceService { - final IInvoiceDAO invoiceDAO = Services.get(IInvoiceDAO.class); - final IArchiveDAO archiveDAO = Services.get(IArchiveDAO.class); - final IArchiveBL archiveBL = Services.get(IArchiveBL.class); + private final IInvoiceDAO invoiceDAO = Services.get(IInvoiceDAO.class); + private final IArchiveDAO archiveDAO = Services.get(IArchiveDAO.class); + private final IArchiveBL archiveBL = Services.get(IArchiveBL.class); + private final IDocumentBL documentBL = Services.get(IDocumentBL.class); + private final IInvoiceCandDAO invoiceCandDAO = Services.get(IInvoiceCandDAO.class); public Optional getInvoicePDF(@NonNull final InvoiceId invoiceId) { @@ -76,24 +83,36 @@ private Optional getLastArchive(@NonNull final InvoiceId invoiceId return Optional.of(lastArchive.get(0)); } - public ResponseEntity reverseInvoice(@NonNull final InvoiceId invoiceId) + @NonNull + public Optional reverseInvoice(@NonNull final InvoiceId invoiceId) { final I_C_Invoice documentRecord = Services.get(IInvoiceDAO.class).getByIdInTrx(invoiceId); if (documentRecord == null) { - return ResponseEntity.notFound().build(); + return Optional.empty(); } - try - { - Services.get(IDocumentBL.class).processEx(documentRecord, IDocument.ACTION_Reverse_Correct, IDocument.STATUS_Reversed); - } - catch (final Exception e) - { - return ResponseEntity.unprocessableEntity().body(e.getLocalizedMessage()); - } + documentBL.processEx(documentRecord, IDocument.ACTION_Reverse_Correct, IDocument.STATUS_Reversed); - return ResponseEntity.ok().build(); + final JsonReverseInvoiceResponse.JsonReverseInvoiceResponseBuilder responseBuilder = JsonReverseInvoiceResponse.builder(); + + invoiceCandDAO + .retrieveInvoiceCandidates(invoiceId) + .stream() + .map(this::buildJSONItem) + .forEach(responseBuilder::affectedInvoiceCandidate); + + return Optional.of(responseBuilder.build()); + } + + private JsonInvoiceCandidatesResponseItem buildJSONItem(@NonNull final I_C_Invoice_Candidate invoiceCandidate) + { + return JsonInvoiceCandidatesResponseItem + .builder() + .externalHeaderId(JsonExternalId.ofOrNull(invoiceCandidate.getExternalHeaderId())) + .externalLineId(JsonExternalId.ofOrNull(invoiceCandidate.getExternalLineId())) + .metasfreshId(MetasfreshId.of(invoiceCandidate.getC_Invoice_Candidate_ID())) + .build(); } } diff --git a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/CreateInvoiceCandidatesService.java b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/CreateInvoiceCandidatesService.java index 961851d7373..f1482776846 100644 --- a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/CreateInvoiceCandidatesService.java +++ b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/CreateInvoiceCandidatesService.java @@ -1,27 +1,8 @@ package de.metas.rest_api.invoicecandidates.impl; -import static de.metas.util.Check.isEmpty; -import static de.metas.util.lang.CoalesceUtil.coalesce; -import static java.math.BigDecimal.ZERO; - -import java.math.BigDecimal; -import java.time.LocalDate; -import java.util.List; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; - -import de.metas.invoicecandidate.externallyreferenced.*; -import org.adempiere.exceptions.AdempiereException; -import org.apache.commons.collections4.CollectionUtils; -import org.compiere.util.Env; -import org.springframework.stereotype.Service; - import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; - import de.metas.bpartner.composite.BPartnerComposite; import de.metas.bpartner.composite.BPartnerContact; import de.metas.bpartner.composite.BPartnerLocation; @@ -31,6 +12,12 @@ import de.metas.bpartner.service.BPartnerQuery; import de.metas.i18n.TranslatableStrings; import de.metas.invoicecandidate.InvoiceCandidateId; +import de.metas.invoicecandidate.externallyreferenced.ExternallyReferencedCandidate; +import de.metas.invoicecandidate.externallyreferenced.ExternallyReferencedCandidateRepository; +import de.metas.invoicecandidate.externallyreferenced.InvoiceCandidateLookupKey; +import de.metas.invoicecandidate.externallyreferenced.InvoiceDetailItem; +import de.metas.invoicecandidate.externallyreferenced.ManualCandidateService; +import de.metas.invoicecandidate.externallyreferenced.NewManualInvoiceCandidate; import de.metas.invoicecandidate.externallyreferenced.NewManualInvoiceCandidate.NewManualInvoiceCandidateBuilder; import de.metas.lang.SOTrx; import de.metas.money.CurrencyId; @@ -62,7 +49,7 @@ import de.metas.rest_api.invoicecandidates.request.JsonCreateInvoiceCandidatesRequestItem; import de.metas.rest_api.invoicecandidates.response.JsonCreateInvoiceCandidatesResponse; import de.metas.rest_api.invoicecandidates.response.JsonCreateInvoiceCandidatesResponse.JsonCreateInvoiceCandidatesResponseBuilder; -import de.metas.rest_api.invoicecandidates.response.JsonCreateInvoiceCandidatesResponseItem; +import de.metas.rest_api.invoicecandidates.response.JsonInvoiceCandidatesResponseItem; import de.metas.rest_api.utils.BPartnerCompositeLookupKey; import de.metas.rest_api.utils.BPartnerQueryService; import de.metas.rest_api.utils.CurrencyService; @@ -75,6 +62,21 @@ import de.metas.util.Services; import de.metas.util.lang.Percent; import lombok.NonNull; +import org.adempiere.exceptions.AdempiereException; +import org.apache.commons.collections4.CollectionUtils; +import org.compiere.util.Env; +import org.springframework.stereotype.Service; + +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import static de.metas.util.Check.isEmpty; +import static de.metas.util.lang.CoalesceUtil.coalesce; +import static java.math.BigDecimal.ZERO; /* * #%L @@ -156,7 +158,7 @@ public JsonCreateInvoiceCandidatesResponse createInvoiceCandidates(@NonNull fina final InvoiceCandidateId candidateId = externallyReferencedCandidateRepository.save(manualCandidateService.createInvoiceCandidate(candidateToSave)); - final JsonCreateInvoiceCandidatesResponseItem responseItem = JsonCreateInvoiceCandidatesResponseItem.builder() + final JsonInvoiceCandidatesResponseItem responseItem = JsonInvoiceCandidatesResponseItem.builder() .externalHeaderId(headerId) .externalLineId(lineId) .metasfreshId(MetasfreshId.of(candidateId)) diff --git a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/InvoicesRestControllerImpl.java b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/InvoicesRestControllerImpl.java index 47a5c057217..74b8660a719 100644 --- a/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/InvoicesRestControllerImpl.java +++ b/backend/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/invoicecandidates/impl/InvoicesRestControllerImpl.java @@ -1,18 +1,5 @@ package de.metas.rest_api.invoicecandidates.impl; -import java.util.Optional; - -import org.springframework.context.annotation.Profile; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - import de.metas.Profiles; import de.metas.invoice.InvoiceId; import de.metas.rest_api.invoice.impl.InvoiceService; @@ -25,11 +12,24 @@ import de.metas.rest_api.invoicecandidates.response.JsonCloseInvoiceCandidatesResponse; import de.metas.rest_api.invoicecandidates.response.JsonCreateInvoiceCandidatesResponse; import de.metas.rest_api.invoicecandidates.response.JsonEnqueueForInvoicingResponse; +import de.metas.rest_api.invoicecandidates.response.JsonReverseInvoiceResponse; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import lombok.NonNull; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Optional; /* * #%L @@ -168,6 +168,17 @@ public ResponseEntity revertInvoice( return ResponseEntity.notFound().build(); } - return invoiceService.reverseInvoice(invoiceId); + try + { + final Optional response = invoiceService.reverseInvoice(invoiceId); + + return response.isPresent() + ? ResponseEntity.ok(response.get()) + : ResponseEntity.notFound().build(); + } + catch (final Exception e) + { + return ResponseEntity.unprocessableEntity().body(e.getLocalizedMessage()); + } } } diff --git a/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponse.java b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponse.java index fdcb9938f90..bca0d64ac58 100644 --- a/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponse.java +++ b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponse.java @@ -1,12 +1,12 @@ package de.metas.rest_api.invoicecandidates.response; -import java.util.List; - import io.swagger.annotations.ApiModelProperty; import lombok.Builder; import lombok.Singular; import lombok.Value; +import java.util.List; + /* * #%L * de.metas.business.rest-api @@ -35,5 +35,5 @@ public class JsonCreateInvoiceCandidatesResponse { @ApiModelProperty(position = 10) @Singular - List responseItems; + List responseItems; } diff --git a/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponseItem.java b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonInvoiceCandidatesResponseItem.java similarity index 96% rename from backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponseItem.java rename to backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonInvoiceCandidatesResponseItem.java index 2c716b0798d..31711496bed 100644 --- a/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonCreateInvoiceCandidatesResponseItem.java +++ b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonInvoiceCandidatesResponseItem.java @@ -31,7 +31,7 @@ @Value @Builder -public class JsonCreateInvoiceCandidatesResponseItem +public class JsonInvoiceCandidatesResponseItem { @ApiModelProperty(position = 10, dataType = "java.lang.String") JsonExternalId externalHeaderId; diff --git a/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonReverseInvoiceResponse.java b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonReverseInvoiceResponse.java new file mode 100644 index 00000000000..06867b56efc --- /dev/null +++ b/backend/de.metas.business.rest-api/src/main/java/de/metas/rest_api/invoicecandidates/response/JsonReverseInvoiceResponse.java @@ -0,0 +1,39 @@ +/* + * #%L + * de.metas.business.rest-api + * %% + * Copyright (C) 2020 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 + * . + * #L% + */ + +package de.metas.rest_api.invoicecandidates.response; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Singular; +import lombok.Value; + +import java.util.List; + +@Value +@Builder +public class JsonReverseInvoiceResponse +{ + @ApiModelProperty(position = 10) + @Singular + List affectedInvoiceCandidates; +} diff --git a/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java b/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java index d9b646cd093..2f36702f4f6 100644 --- a/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java +++ b/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/IInvoiceCandDAO.java @@ -21,31 +21,11 @@ * . * #L% */ -import java.math.BigDecimal; -import java.time.LocalDate; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.adempiere.ad.dao.IQueryBuilder; -import org.adempiere.exceptions.AdempiereException; -import org.adempiere.util.lang.IContextAware; -import org.adempiere.util.lang.impl.TableRecordReference; -import org.compiere.model.IQuery; -import org.compiere.model.I_C_BPartner; -import org.compiere.model.I_C_InvoiceLine; -import org.compiere.model.I_C_InvoiceSchedule; -import org.compiere.model.I_M_InOut; -import org.compiere.model.I_M_InOutLine; import de.metas.adempiere.model.I_C_Invoice; import de.metas.aggregation.model.I_C_Aggregation; import de.metas.bpartner.BPartnerId; +import de.metas.invoice.InvoiceId; import de.metas.invoicecandidate.InvoiceCandidateId; import de.metas.invoicecandidate.model.I_C_InvoiceCandidate_InOutLine; import de.metas.invoicecandidate.model.I_C_Invoice_Candidate; @@ -59,6 +39,26 @@ import de.metas.util.ISingletonService; import lombok.NonNull; import lombok.Value; +import org.adempiere.ad.dao.IQueryBuilder; +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.util.lang.IContextAware; +import org.adempiere.util.lang.impl.TableRecordReference; +import org.compiere.model.IQuery; +import org.compiere.model.I_C_BPartner; +import org.compiere.model.I_C_InvoiceLine; +import org.compiere.model.I_C_InvoiceSchedule; +import org.compiere.model.I_M_InOut; +import org.compiere.model.I_M_InOutLine; + +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; public interface IInvoiceCandDAO extends ISingletonService { @@ -85,6 +85,8 @@ public interface IInvoiceCandDAO extends ISingletonService List retrieveIcForIl(I_C_InvoiceLine invoiceLine); + List retrieveInvoiceCandidates(@NonNull final InvoiceId invoiceId); + /** * Returns those invoice candidates that have been tagged to be recomputed/updated by the given recomputeTag. * diff --git a/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java b/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java index 44c66a7c188..b8973c351da 100644 --- a/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java +++ b/backend/de.metas.swat/de.metas.swat.base/src/main/java/de/metas/invoicecandidate/api/impl/InvoiceCandDAO.java @@ -1,85 +1,9 @@ package de.metas.invoicecandidate.api.impl; -import static org.adempiere.model.InterfaceWrapperHelper.delete; - -/* - * #%L - * de.metas.swat.base - * %% - * Copyright (C) 2015 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 - * . - * #L% - */ - -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.adempiere.ad.dao.ConstantQueryFilter; -import org.adempiere.ad.dao.ICompositeQueryFilter; -import org.adempiere.ad.dao.ICompositeQueryUpdater; -import org.adempiere.ad.dao.IQueryBL; -import org.adempiere.ad.dao.IQueryBuilder; -import org.adempiere.ad.dao.IQueryOrderBy.Direction; -import org.adempiere.ad.dao.IQueryOrderBy.Nulls; -import org.adempiere.ad.dao.IQueryOrderByBuilder; -import org.adempiere.ad.dao.impl.CompareQueryFilter.Operator; -import org.adempiere.ad.dao.impl.ModelColumnNameValue; -import org.adempiere.ad.persistence.ModelDynAttributeAccessor; -import org.adempiere.ad.table.api.IADTableDAO; -import org.adempiere.ad.trx.api.ITrx; -import org.adempiere.ad.trx.api.ITrxListenerManager.TrxEventTiming; -import org.adempiere.ad.trx.api.ITrxManager; -import org.adempiere.exceptions.AdempiereException; -import org.adempiere.exceptions.DBException; -import org.adempiere.model.InterfaceWrapperHelper; -import org.adempiere.service.ClientId; -import org.adempiere.util.lang.IContextAware; -import org.adempiere.util.lang.impl.TableRecordReference; -import org.adempiere.util.proxy.Cached; -import org.compiere.model.IQuery; -import org.compiere.model.I_C_BPartner; -import org.compiere.model.I_C_InvoiceLine; -import org.compiere.model.I_C_InvoiceSchedule; -import org.compiere.model.I_C_OrderLine; -import org.compiere.model.I_M_InOut; -import org.compiere.model.I_M_InOutLine; -import org.compiere.util.DB; -import org.compiere.util.Env; -import org.compiere.util.TimeUtil; -import org.slf4j.Logger; - +import ch.qos.logback.classic.Level; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; - -import ch.qos.logback.classic.Level; +import de.metas.adempiere.model.I_C_Invoice; import de.metas.aggregation.model.I_C_Aggregation; import de.metas.bpartner.BPartnerId; import de.metas.bpartner.service.IBPartnerDAO; @@ -89,6 +13,7 @@ import de.metas.currency.ICurrencyBL; import de.metas.document.engine.DocStatus; import de.metas.inout.IInOutDAO; +import de.metas.invoice.InvoiceId; import de.metas.invoicecandidate.InvoiceCandidateId; import de.metas.invoicecandidate.api.IInvoiceCandBL; import de.metas.invoicecandidate.api.IInvoiceCandDAO; @@ -125,6 +50,81 @@ import de.metas.util.lang.ExternalId; import de.metas.util.time.SystemTime; import lombok.NonNull; +import org.adempiere.ad.dao.ConstantQueryFilter; +import org.adempiere.ad.dao.ICompositeQueryFilter; +import org.adempiere.ad.dao.ICompositeQueryUpdater; +import org.adempiere.ad.dao.IQueryBL; +import org.adempiere.ad.dao.IQueryBuilder; +import org.adempiere.ad.dao.IQueryOrderBy.Direction; +import org.adempiere.ad.dao.IQueryOrderBy.Nulls; +import org.adempiere.ad.dao.IQueryOrderByBuilder; +import org.adempiere.ad.dao.impl.CompareQueryFilter.Operator; +import org.adempiere.ad.dao.impl.ModelColumnNameValue; +import org.adempiere.ad.persistence.ModelDynAttributeAccessor; +import org.adempiere.ad.table.api.IADTableDAO; +import org.adempiere.ad.trx.api.ITrx; +import org.adempiere.ad.trx.api.ITrxListenerManager.TrxEventTiming; +import org.adempiere.ad.trx.api.ITrxManager; +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.DBException; +import org.adempiere.model.InterfaceWrapperHelper; +import org.adempiere.service.ClientId; +import org.adempiere.util.lang.IContextAware; +import org.adempiere.util.lang.impl.TableRecordReference; +import org.adempiere.util.proxy.Cached; +import org.compiere.model.IQuery; +import org.compiere.model.I_C_BPartner; +import org.compiere.model.I_C_InvoiceLine; +import org.compiere.model.I_C_InvoiceSchedule; +import org.compiere.model.I_C_OrderLine; +import org.compiere.model.I_M_InOut; +import org.compiere.model.I_M_InOutLine; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.slf4j.Logger; + +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.Set; + +import static org.adempiere.model.InterfaceWrapperHelper.delete; +import static org.adempiere.model.InterfaceWrapperHelper.load; + +/* + * #%L + * de.metas.swat.base + * %% + * Copyright (C) 2015 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 + * . + * #L% + */ public class InvoiceCandDAO implements IInvoiceCandDAO { @@ -134,6 +134,8 @@ public class InvoiceCandDAO implements IInvoiceCandDAO private static final ModelDynAttributeAccessor DYNATTR_IC_Avoid_Recreate // = new ModelDynAttributeAccessor<>(IInvoiceCandDAO.class.getName() + "Avoid_Recreate", Boolean.class); + + private final IQueryBL queryBL = Services.get(IQueryBL.class); @Override public I_C_Invoice_Candidate getById(@NonNull final InvoiceCandidateId invoiceCandidateId) @@ -159,7 +161,7 @@ public final Iterator retrieveIcForSelection(final Proper // Note that we can't filter by IsError in the where clause, because it wouldn't work with pagination. // Background is that the number of candidates with "IsError=Y" might increase during the run. - final IQueryBuilder queryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, ctx, trxName) .setOnlySelection(pinstanceId); @@ -169,7 +171,7 @@ public final Iterator retrieveIcForSelection(final Proper @Override public final Iterator retrieveNonProcessed(final IContextAware contextAware) { - final IQueryBuilder queryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, contextAware) .addEqualsFilter(I_C_Invoice_Candidate.COLUMN_Processed, false); @@ -228,7 +230,7 @@ public int deleteAllReferencingInvoiceCandidates(@NonNull final Object model) // i could do all this with "stream", but i find "old-school" easier to debug int deleteCount = 0; - final List icRecordsToDelete = Services.get(IQueryBL.class) + final List icRecordsToDelete = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addEqualsFilter(I_C_Invoice_Candidate.COLUMNNAME_AD_Table_ID, tableId) .addEqualsFilter(I_C_Invoice_Candidate.COLUMNNAME_Record_ID, recordId) @@ -319,7 +321,7 @@ public Map retrieveInvoic public I_C_Invoice_Line_Alloc retrieveIlaForIcAndIl(final I_C_Invoice_Candidate invoiceCand, final org.compiere.model.I_C_InvoiceLine invoiceLine) { // @formatter:off - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Line_Alloc.class, invoiceCand) .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMN_C_Invoice_Candidate_ID, invoiceCand.getC_Invoice_Candidate_ID()) .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMN_C_InvoiceLine_ID, invoiceLine.getC_InvoiceLine_ID()) @@ -338,7 +340,6 @@ public List retrieveInOutLinesFo { // FIXME debug to see why c_invoicecandidate_inoutline have duplicates and take the inoutlines from there // for now take it via orderline - final IQueryBL queryBL = Services.get(IQueryBL.class); final IQueryBuilder queryBuilder = queryBL.createQueryBuilder(I_M_InOutLine.class, ic) .addEqualsFilter(I_M_InOutLine.COLUMN_C_OrderLine_ID, ic.getC_OrderLine_ID()) .addOnlyActiveRecordsFilter(); @@ -356,7 +357,7 @@ public List retrieveInOutLinesFo @Override public List retrieveInvoiceCandidatesForOrderLineId(@NonNull final OrderLineId orderLineId) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addEqualsFilter(I_C_Invoice_Candidate.COLUMN_C_OrderLine_ID, orderLineId) .addOnlyActiveRecordsFilter() @@ -370,7 +371,7 @@ public List retrieveInvoiceCandidatesForOrderLineId(@NonN 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) + return queryBL .createQueryBuilder(I_C_InvoiceCandidate_InOutLine.class, ic) .addEqualsFilter(I_C_InvoiceCandidate_InOutLine.COLUMN_C_Invoice_Candidate_ID, ic.getC_Invoice_Candidate_ID()) .addEqualsFilter(I_C_InvoiceCandidate_InOutLine.COLUMN_M_InOutLine_ID, iol.getM_InOutLine_ID()) @@ -397,7 +398,6 @@ public List retrieveICIOLAssociationsExclRE(@Non { // load all I_C_InvoiceCandidate_InOutLine and filter locally. // i think it's safe to assume that there are not 1000s of records to load and this way the code is simpler - final IQueryBL queryBL = Services.get(IQueryBL.class); return queryBL.createQueryBuilder(I_C_InvoiceCandidate_InOutLine.class) .addEqualsFilter(I_C_InvoiceCandidate_InOutLine.COLUMN_C_Invoice_Candidate_ID, invoiceCandidateId) .addOnlyActiveRecordsFilter() @@ -425,7 +425,7 @@ public List retrieveICIOLAssociationsForInOutLin private IQueryBuilder retrieveICIOLAssociationsForInOutLineInclInactiveQuery(final I_M_InOutLine inOutLine) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_InvoiceCandidate_InOutLine.class, inOutLine) .addEqualsFilter(I_C_InvoiceCandidate_InOutLine.COLUMN_M_InOutLine_ID, inOutLine.getM_InOutLine_ID()) // @@ -461,7 +461,6 @@ public final List retrieveInvoiceCandidatesForInOutLine(f public final IQueryBuilder retrieveInvoiceCandidatesForInOutLineQuery( @NonNull final I_M_InOutLine inoutLine) { - final IQueryBL queryBL = Services.get(IQueryBL.class); final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, inoutLine) @@ -539,7 +538,7 @@ public void saveAll(final Collection invoiceCandidates) @Override public int deleteInvoiceDetails(final I_C_Invoice_Candidate ic) { - return Services.get(IQueryBL.class).createQueryBuilder(I_C_Invoice_Detail.class, ic) + return queryBL.createQueryBuilder(I_C_Invoice_Detail.class, ic) .addEqualsFilter(I_C_Invoice_Detail.COLUMN_C_Invoice_Candidate_ID, ic.getC_Invoice_Candidate_ID()) .create() .delete(); @@ -561,7 +560,7 @@ public boolean isAvoidRecreate(final I_C_Invoice_Candidate ic) @Override public List retrieveIcForIl(final I_C_InvoiceLine invoiceLine) { - final IQueryBuilder ilaQueryBuilder = Services.get(IQueryBL.class).createQueryBuilder(I_C_Invoice_Line_Alloc.class, invoiceLine) + final IQueryBuilder ilaQueryBuilder = queryBL.createQueryBuilder(I_C_Invoice_Line_Alloc.class, invoiceLine) .addOnlyActiveRecordsFilter() .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMN_C_InvoiceLine_ID, invoiceLine.getC_InvoiceLine_ID()); @@ -573,6 +572,30 @@ public List retrieveIcForIl(final I_C_InvoiceLine invoice .addColumn(I_C_Invoice_Candidate.COLUMN_C_Invoice_Candidate_ID); return icQueryBuilder + .create() + .list();// + } + + @NonNull + public List retrieveInvoiceCandidates(@NonNull final InvoiceId invoiceId) + { + final I_C_Invoice invoice = load(invoiceId, I_C_Invoice.class); + + final IQuery invoiceLineAllocQuery = + queryBL.createQueryBuilder(I_C_InvoiceLine.class, invoice) + .addEqualsFilter(I_C_InvoiceLine.COLUMNNAME_C_Invoice_ID, invoice.getC_Invoice_ID()) + //collect invoice line alloc + .andCollectChildren(I_C_Invoice_Line_Alloc.COLUMN_C_InvoiceLine_ID) + .addOnlyActiveRecordsFilter() + .create(); + + return queryBL + .createQueryBuilder(I_C_Invoice_Candidate.class, invoice) + .addOnlyActiveRecordsFilter() + .addInSubQueryFilter() + .subQuery(invoiceLineAllocQuery) + .matchingColumnNames(I_C_Invoice_Candidate.COLUMNNAME_C_Invoice_Candidate_ID, I_C_Invoice_Line_Alloc.COLUMNNAME_C_Invoice_Candidate_ID) + .end() .create() .list(); } @@ -590,7 +613,7 @@ public final Iterator retrieveForHeaderAggregationKey(fin private final IQueryBuilder retrieveForHeaderAggregationKeyQuery(final Properties ctx, final String headerAggregationKey, final String trxName) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, ctx, trxName) .addOnlyActiveRecordsFilter() .addOnlyContextClient() @@ -610,7 +633,7 @@ public final List retrieveIlForIc(final I_C_Invoice_Candidate i @Override public final List retrieveIlForIc(@NonNull final InvoiceCandidateId invoiceCandidateId) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Line_Alloc.class) .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMN_C_Invoice_Candidate_ID, invoiceCandidateId) // @@ -630,7 +653,7 @@ public final List retrieveIlForIc(@NonNull final InvoiceCandida @Override public final List retrieveIlaForIc(@NonNull final InvoiceCandidateId invoiceCandidateId) { - final IQueryBuilder ilaQueryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder ilaQueryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Line_Alloc.class) .addOnlyActiveRecordsFilter() .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMNNAME_C_Invoice_Candidate_ID, invoiceCandidateId); @@ -644,7 +667,7 @@ public final List retrieveIlaForIc(@NonNull final Invoic @Override public final List retrieveIlaForIl(final I_C_InvoiceLine il) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Line_Alloc.class, il) .addEqualsFilter(I_C_Invoice_Line_Alloc.COLUMN_C_InvoiceLine_ID, il.getC_InvoiceLine_ID()) .addOnlyActiveRecordsFilter() @@ -675,7 +698,7 @@ public final void invalidateCandsForProductGroup(final I_M_ProductGroup pg) { final String trxName = InterfaceWrapperHelper.getTrxName(pg); final Properties ctx = InterfaceWrapperHelper.getCtx(pg); - final int referingAggregators = Services.get(IQueryBL.class) + final int referingAggregators = queryBL .createQueryBuilder(I_C_Invoice_Candidate_Agg.class, ctx, trxName) .addEqualsFilter(I_C_Invoice_Candidate_Agg.COLUMN_M_ProductGroup_ID, pg.getM_ProductGroup_ID()) .create() @@ -786,7 +809,6 @@ public final void invalidateCandsForAggregationBuilder(final I_C_Aggregation agg final Properties ctx = InterfaceWrapperHelper.getCtx(aggregation); final String trxName = InterfaceWrapperHelper.getTrxName(aggregation); - final IQueryBL queryBL = Services.get(IQueryBL.class); final IQueryBuilder icQueryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, ctx, trxName) // Not already processed @@ -827,8 +849,6 @@ public final void invalidateCandsForBPartnerInvoiceRule(final BPartnerId bpartne @Override public final void invalidateAllCands(final Properties ctx, final String trxName) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final IQuery alreadyInvalidatedICsQuery = queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName) .create(); @@ -847,7 +867,7 @@ public final void invalidateAllCands(final Properties ctx, final String trxName) protected final void invalidateCandsForSelection(final PInstanceId pinstanceId, final String trxName) { final Properties ctx = Env.getCtx(); - final IQueryBuilder icQueryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder icQueryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, ctx, trxName) .setOnlySelection(pinstanceId) // Invalidate no matter if Processed or not @@ -861,7 +881,7 @@ protected final void invalidateCandsForSelection(final PInstanceId pinstanceId, private final IQueryBuilder retrieveInvoiceCandidatesForRecordQuery( @NonNull final TableRecordReference tableRecordReference) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addEqualsFilter(I_C_Invoice_Candidate.COLUMNNAME_AD_Table_ID, tableRecordReference.getAdTableId()) .addEqualsFilter(I_C_Invoice_Candidate.COLUMNNAME_Record_ID, tableRecordReference.getRecord_ID()) @@ -887,7 +907,7 @@ public final Iterator fetchInvalidInvoiceCandidates( @NonNull final InvoiceCandRecomputeTag recomputeTag, final String trxName) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName) .addEqualsFilter(I_C_Invoice_Candidate_Recompute.COLUMN_AD_PInstance_ID, recomputeTag.getPinstanceId()) // @@ -932,7 +952,7 @@ private final IQueryBuilder retrieveInvoiceCand final Properties ctx = tagRequest.getCtx(); final String trxName = tagRequest.getTrxName(); - final IQueryBuilder queryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName); // @@ -1016,7 +1036,7 @@ protected final void deleteRecomputeMarkersAndInvalidateCache( final InvoiceCandRecomputeTag recomputeTag = tagger.getRecomputeTag(); final String trxName = tagger.getTrxName(); - final IQueryBuilder queryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName) .addEqualsFilter(I_C_Invoice_Candidate_Recompute.COLUMN_AD_PInstance_ID, recomputeTag.getPinstanceId()); @@ -1063,7 +1083,7 @@ protected final int untag(@NonNull final InvoiceCandRecomputeTagger tagger) final InvoiceCandRecomputeTag recomputeTag = tagger.getRecomputeTag(); final String trxName = tagger.getTrxName(); - final IQuery query = Services.get(IQueryBL.class) + final IQuery query = queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName) .addEqualsFilter(I_C_Invoice_Candidate_Recompute.COLUMN_AD_PInstance_ID, recomputeTag.getPinstanceId()) .create(); @@ -1087,7 +1107,7 @@ public final boolean hasInvalidInvoiceCandidatesForTag(final InvoiceCandRecomput final PInstanceId pinstanceId = InvoiceCandRecomputeTag.getPinstanceIdOrNull(tag); - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ctx, trxName) .addEqualsFilter(I_C_Invoice_Candidate_Recompute.COLUMN_AD_PInstance_ID, pinstanceId) .create() @@ -1096,7 +1116,7 @@ public final boolean hasInvalidInvoiceCandidatesForTag(final InvoiceCandRecomput private final IQueryBuilder retrieveForBillPartnerQuery(final I_C_BPartner bpartner) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate.class, bpartner) .addOnlyActiveRecordsFilter() .addOnlyContextClient() @@ -1109,8 +1129,6 @@ private final IQueryBuilder retrieveForBillPartnerQuery(f @Override public List retrieveForInvoiceSchedule(final I_C_InvoiceSchedule invoiceSchedule) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final IQuery bpartnersQuery = queryBL.createQueryBuilder(I_C_BPartner.class, invoiceSchedule) .addEqualsFilter(I_C_BPartner.COLUMN_C_InvoiceSchedule_ID, invoiceSchedule.getC_InvoiceSchedule_ID()) .create(); @@ -1193,8 +1211,6 @@ public final void updateApprovalForInvoicingToTrue(@NonNull final PInstanceId se @Override public void updateMissingPaymentTermIds(final PInstanceId selectionId) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final PInstanceId selectionToUpdateId = retrieveIcsToUpdateSelectionId(selectionId); if (selectionToUpdateId == null) { @@ -1225,8 +1241,6 @@ public void updateMissingPaymentTermIds(final PInstanceId selectionId) private PInstanceId retrieveIcsToUpdateSelectionId(final PInstanceId selectionId) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final PInstanceId selectionToUpdateId = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .setOnlySelection(selectionId) @@ -1246,8 +1260,6 @@ private PInstanceId retrieveIcsToUpdateSelectionId(final PInstanceId selectionId private PaymentTermId retrievePaymentTermId(final PInstanceId selectionId) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final ICompositeQueryFilter paymentTermSetFilter = queryBL .createCompositeQueryFilter(I_C_Invoice_Candidate.class) .setJoinOr() @@ -1290,8 +1302,6 @@ private final void updateColumnForSelection( final boolean updateOnlyIfNull, @NonNull final PInstanceId selectionId) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - // // Create the selection which we will need to update final IQueryBuilder selectionQueryBuilder = queryBL @@ -1482,7 +1492,7 @@ public BigDecimal retrieveInvoicableAmount( @Override public final List retrieveInOutLines(final Properties ctx, final int C_OrderLine_ID, final String trxName) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_M_InOutLine.class, ctx, trxName) .addEqualsFilter(I_M_InOutLine.COLUMN_C_OrderLine_ID, C_OrderLine_ID) .create() @@ -1526,7 +1536,7 @@ public final void invalidateCands(@Nullable final List ic } // note: invalidate, no matter if Processed or not - final IQueryBuilder icQueryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder icQueryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addInArrayFilter(I_C_Invoice_Candidate.COLUMN_C_Invoice_Candidate_ID, icIds); @@ -1536,7 +1546,7 @@ public final void invalidateCands(@Nullable final List ic @Override public final boolean isToRecompute(final I_C_Invoice_Candidate ic) { - return Services.get(IQueryBL.class) + return queryBL .createQueryBuilder(I_C_Invoice_Candidate_Recompute.class, ic) .addEqualsFilter(I_C_Invoice_Candidate_Recompute.COLUMN_C_Invoice_Candidate_ID, ic.getC_Invoice_Candidate_ID()) .setLimit(1) @@ -1547,7 +1557,7 @@ public final boolean isToRecompute(final I_C_Invoice_Candidate ic) @Override public List retrieveInvoiceDetails(final I_C_Invoice_Candidate ic) { - return Services.get(IQueryBL.class).createQueryBuilder(I_C_Invoice_Detail.class, ic) + return queryBL.createQueryBuilder(I_C_Invoice_Detail.class, ic) .addOnlyActiveRecordsFilter() .addEqualsFilter(I_C_Invoice_Detail.COLUMN_C_Invoice_Candidate_ID, ic.getC_Invoice_Candidate_ID()) .orderBy() @@ -1647,8 +1657,6 @@ public Set retrieveOrderDocumentNosForIncompleteGroupsFromSelection(fina @Override public InvoiceableInvoiceCandIdResult getFirstInvoiceableInvoiceCandId(@NonNull final OrderId orderId) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final List nonFreightCostICs = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addOnlyActiveRecordsFilter() @@ -1681,7 +1689,7 @@ public InvoiceableInvoiceCandIdResult getFirstInvoiceableInvoiceCandId(@NonNull @Override public void invalidateUninvoicedFreightCostCandidate(@NonNull final OrderId orderId) { - final IQueryBuilder freightCostCandQueryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder freightCostCandQueryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .addEqualsFilter(I_C_Invoice_Candidate.COLUMNNAME_C_Order_ID, orderId) .addEqualsFilter(I_C_Invoice_Candidate.COLUMN_IsFreightCost, true) @@ -1706,7 +1714,7 @@ public int createSelectionByQuery(InvoiceCandidateMultiQuery multiQuery, @NonNul private IQuery convertToIQuery(@NonNull final InvoiceCandidateMultiQuery multiQuery) { - final IQueryBuilder queryBuilder = Services.get(IQueryBL.class) + final IQueryBuilder queryBuilder = queryBL .createQueryBuilder(I_C_Invoice_Candidate.class) .setOption(IQueryBuilder.OPTION_Explode_OR_Joins_To_SQL_Unions, false) /* exploding ORs to unions works only with simple cases, but e.g. currently not if we want to use IQuery.createSelection() down the line */ .setJoinOr(); @@ -1721,8 +1729,6 @@ private IQuery convertToIQuery(@NonNull final InvoiceCand private ICompositeQueryFilter toFilter(@NonNull final InvoiceCandidateQuery query) { - final IQueryBL queryBL = Services.get(IQueryBL.class); - final ICompositeQueryFilter filter = queryBL .createCompositeQueryFilter(I_C_Invoice_Candidate.class) .addOnlyActiveRecordsFilter();