Skip to content

Commit

Permalink
Add Value on Processed Product Computing Method (#17997)
Browse files Browse the repository at this point in the history
* Add Value on Processed Product Computing Method
refs: #17996
  • Loading branch information
dm-ps committed May 14, 2024
1 parent 289fc49 commit 4d7c481
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,20 @@

import de.metas.contracts.FlatrateTermId;
import de.metas.contracts.modular.ComputingMethodType;
import de.metas.contracts.modular.ModularContractProvider;
import de.metas.contracts.modular.computing.ComputingMethodService;
import de.metas.contracts.modular.computing.ComputingRequest;
import de.metas.contracts.modular.computing.ComputingResponse;
import de.metas.contracts.modular.computing.IComputingMethodHandler;
import de.metas.contracts.modular.computing.purchasecontract.sales.processed.ManufacturingFacadeService;
import de.metas.contracts.modular.computing.purchasecontract.sales.processed.ManufacturingOrder;
import de.metas.contracts.modular.computing.purchasecontract.sales.processed.ManufacturingReceipt;
import de.metas.contracts.modular.log.LogEntryContractType;
import de.metas.contracts.modular.log.ModularContractLogEntriesList;
import de.metas.contracts.modular.settings.ModularContractSettings;
import de.metas.product.ProductId;
import de.metas.product.ProductPrice;
import de.metas.uom.UomId;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.adempiere.util.lang.impl.TableRecordReference;
Expand All @@ -37,17 +49,31 @@
@RequiredArgsConstructor
public class AVProcessedComputingMethod implements IComputingMethodHandler
{
@NonNull private final ManufacturingFacadeService manufacturingFacadeService;
@NonNull private final ModularContractProvider contractProvider;
@NonNull private final ComputingMethodService computingMethodService;

@Override
public boolean applies(final @NonNull TableRecordReference recordRef, @NonNull final LogEntryContractType logEntryContractType)
{
return false;
if (!logEntryContractType.isModularContractType())
{
return false;
}

final ManufacturingReceipt manufacturingReceipt = manufacturingFacadeService.getManufacturingReceiptIfApplies(recordRef).orElse(null);
if (manufacturingReceipt == null)
{
return false;
}

return manufacturingFacadeService.isModularOrder(manufacturingReceipt.getManufacturingOrderId());
}

@Override
public @NonNull Stream<FlatrateTermId> streamContractIds(final @NonNull TableRecordReference recordRef)
{
return Stream.empty();
return contractProvider.streamModularPurchaseContractsForPPOrder(ManufacturingFacadeService.getManufacturingReceiptId(recordRef));
}

@Override
Expand All @@ -56,4 +82,36 @@ public boolean applies(final @NonNull TableRecordReference recordRef, @NonNull f
return ComputingMethodType.AddValueOnProcessedProduct;
}

@Override
public boolean isApplicableForSettings(final @NonNull TableRecordReference recordRef, final @NonNull ModularContractSettings settings)
{
if (settings.getProcessedProductId() == null)
{
return false;
}

final ManufacturingReceipt manufacturingReceipt = manufacturingFacadeService.getManufacturingReceipt(recordRef);
final ManufacturingOrder manufacturingOrder = manufacturingFacadeService.getManufacturingOrder(manufacturingReceipt.getManufacturingOrderId());

return ProductId.equals(manufacturingOrder.getProcessedProductId(), settings.getProcessedProductId());
}

@Override
public @NonNull ComputingResponse compute(final @NonNull ComputingRequest request)
{
final ModularContractLogEntriesList logs = computingMethodService.retrieveLogsForCalculation(request);
if (logs.isEmpty())
{
return computingMethodService.toZeroResponse(request);
}

final ProductPrice price = logs.getUniqueProductPriceOrErrorNotNull();
final UomId stockUOMId = productBL.getStockUOMId(request.getProductId());

return ComputingResponse.builder()
.ids(logs.getIds())
.price(computingMethodService.productPriceToUOM(price, stockUOMId))
.qty(computingMethodService.getQtySumInStockUOM(logs))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* #%L
* de.metas.contracts
* %%
* Copyright (C) 2024 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%
*/

package de.metas.contracts.modular.computing.purchasecontract.addedvalue.processedproduct;

import de.metas.contracts.modular.ModularContractService;
import de.metas.contracts.modular.computing.purchasecontract.sales.processed.ManufacturingFacadeService;
import de.metas.contracts.modular.computing.purchasecontract.sales.processed.ManufacturingReceipt;
import de.metas.contracts.modular.invgroup.interceptor.ModCntrInvoicingGroupRepository;
import de.metas.contracts.modular.workpackage.IModularContractLogHandler;
import de.metas.contracts.modular.workpackage.impl.AbstractManufacturingOrderLogHandler;
import de.metas.product.ProductId;
import lombok.NonNull;
import org.springframework.stereotype.Component;

@Component
public class AVProcessedManufacturingOrderLog extends AbstractManufacturingOrderLogHandler
{
public AVProcessedManufacturingOrderLog(
@NonNull final ModCntrInvoicingGroupRepository modCntrInvoicingGroupRepository,
@NonNull final ModularContractService modularContractService,
@NonNull final ManufacturingFacadeService manufacturingFacadeService,
@NonNull final AVProcessedComputingMethod computingMethod)
{
super(modCntrInvoicingGroupRepository, modularContractService, manufacturingFacadeService, computingMethod);
}

@Override
public boolean applies(@NonNull final CreateLogRequest request)
{
return manufacturingFacadeService.getManufacturingReceiptIfApplies(request.getRecordRef()).isPresent();
}

@NonNull
@Override
protected ProductId extractProductIdToLog(
@NonNull final IModularContractLogHandler.CreateLogRequest request,
@NonNull final ManufacturingReceipt manufacturingReceipt)
{
return request.getProductId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Service used to hide behind all manufacturing BLs & models and present the manufacturing in modular contracts ubiquitous language
*/
@Service
class ManufacturingFacadeService
public class ManufacturingFacadeService
{
@NonNull private final IPPOrderBL ppOrderBL = Services.get(IPPOrderBL.class);
@NonNull private final IPPCostCollectorBL ppCostCollectorBL = Services.get(IPPCostCollectorBL.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
@Value
@Builder
class ManufacturingOrder
public class ManufacturingOrder
{
@NonNull PPOrderId id;
@NonNull ProductId processedProductId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
@Value
@Builder
class ManufacturingReceipt
public class ManufacturingReceipt
{
@NonNull PPCostCollectorId id;
@NonNull PPOrderId manufacturingOrderId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,122 +22,40 @@

package de.metas.contracts.modular.computing.purchasecontract.sales.processed;

import de.metas.bpartner.BPartnerId;
import de.metas.contracts.FlatrateTermId;
import de.metas.contracts.IFlatrateDAO;
import de.metas.contracts.model.I_C_Flatrate_Term;
import de.metas.contracts.modular.ModularContractService;
import de.metas.contracts.modular.invgroup.InvoicingGroupId;
import de.metas.contracts.modular.invgroup.interceptor.ModCntrInvoicingGroupRepository;
import de.metas.contracts.modular.log.LogEntryCreateRequest;
import de.metas.contracts.modular.log.LogEntryDeleteRequest;
import de.metas.contracts.modular.log.LogEntryDocumentType;
import de.metas.contracts.modular.log.LogEntryReverseRequest;
import de.metas.contracts.modular.log.LogSubEntryId;
import de.metas.contracts.modular.workpackage.IModularContractLogHandler;
import de.metas.i18n.AdMessageKey;
import de.metas.i18n.ExplainedOptional;
import de.metas.i18n.IMsgBL;
import de.metas.lang.SOTrx;
import de.metas.organization.IOrgDAO;
import de.metas.organization.InstantAndOrgId;
import de.metas.product.IProductBL;
import de.metas.contracts.modular.workpackage.impl.AbstractManufacturingOrderLogHandler;
import de.metas.product.ProductId;
import de.metas.product.ProductPrice;
import de.metas.quantity.Quantity;
import de.metas.uom.IUOMConversionBL;
import de.metas.util.Services;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.eevolution.model.I_PP_Cost_Collector;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ProcessedSalesManufacturingOrderLog implements IModularContractLogHandler
public class ProcessedSalesManufacturingOrderLog extends AbstractManufacturingOrderLogHandler
{
private static final AdMessageKey MSG_DESCRIPTION_RECEIPT = AdMessageKey.of("de.metas.contracts.modular.impl.IssueReceiptModularContractHandler.Description.Receipt");

@NonNull private final IFlatrateDAO flatrateDAO = Services.get(IFlatrateDAO.class);
@NonNull private final IProductBL productBL = Services.get(IProductBL.class);
@NonNull private final IOrgDAO orgDAO = Services.get(IOrgDAO.class);
@NonNull private final IMsgBL msgBL = Services.get(IMsgBL.class);
@NonNull private final IUOMConversionBL uomConversionBL = Services.get(IUOMConversionBL.class);
@NonNull private final ManufacturingFacadeService manufacturingFacadeService;
@NonNull private final ModCntrInvoicingGroupRepository modCntrInvoicingGroupRepository;
@NonNull private final ModularContractService modularContractService;

@Getter @NonNull private final ProcessedSalesComputingMethod computingMethod;
@Getter @NonNull private final String supportedTableName = I_PP_Cost_Collector.Table_Name;
@Getter @NonNull private final LogEntryDocumentType logEntryDocumentType = LogEntryDocumentType.PRODUCTION;
public ProcessedSalesManufacturingOrderLog(
@NonNull final ModCntrInvoicingGroupRepository modCntrInvoicingGroupRepository,
@NonNull final ModularContractService modularContractService,
@NonNull final ManufacturingFacadeService manufacturingFacadeService,
@NonNull final ProcessedSalesComputingMethod computingMethod)
{
super(modCntrInvoicingGroupRepository, modularContractService, manufacturingFacadeService, computingMethod);
}

@Override
public boolean applies(@NonNull final CreateLogRequest request)
{
final ManufacturingReceipt manufacturingReceipt = manufacturingFacadeService.getManufacturingReceiptIfApplies(request.getRecordRef()).orElse(null);
return manufacturingReceipt != null
&& ProductId.equals(manufacturingReceipt.getProductId(), request.getProductId());
}

@Override
public @NonNull ExplainedOptional<LogEntryCreateRequest> createLogEntryCreateRequest(@NonNull final CreateLogRequest createLogRequest)
{
final ManufacturingReceipt manufacturingReceipt = manufacturingFacadeService.getManufacturingReceipt(createLogRequest.getRecordRef());
final ProductId productId = manufacturingReceipt.getProductId();
final InstantAndOrgId transactionDate = manufacturingReceipt.getTransactionDate();
final InvoicingGroupId invoicingGroupId = modCntrInvoicingGroupRepository.getInvoicingGroupIdFor(productId, transactionDate.toInstant()).orElse(null);
final String productName = productBL.getProductValueAndName(productId);
final Quantity qty = manufacturingReceipt.getQtyReceived();
final String description = msgBL.getBaseLanguageMsg(MSG_DESCRIPTION_RECEIPT, qty.abs().toString(), productName);

final FlatrateTermId contractId = createLogRequest.getContractId();
final I_C_Flatrate_Term modularContractRecord = flatrateDAO.getById(contractId);
final BPartnerId invoicingBPartnerId = BPartnerId.ofRepoIdOrNull(modularContractRecord.getBill_BPartner_ID());
final BPartnerId collectionPointBPartnerId = BPartnerId.ofRepoIdOrNull(modularContractRecord.getDropShip_BPartner_ID());
final ProductPrice price = modularContractService.getContractSpecificPrice(createLogRequest.getModularContractModuleId(), contractId);

return ExplainedOptional.of(LogEntryCreateRequest.builder()
.contractId(contractId)
.referencedRecord(manufacturingReceipt.getManufacturingOrderId().toRecordRef())
.subEntryId(LogSubEntryId.ofCostCollectorId(manufacturingReceipt.getId()))
.productId(productId)
.productName(createLogRequest.getProductName())
.invoicingBPartnerId(invoicingBPartnerId)
.warehouseId(manufacturingReceipt.getWarehouseId())
.documentType(getLogEntryDocumentType())
.contractType(getLogEntryContractType())
.soTrx(SOTrx.PURCHASE)
.quantity(qty)
.transactionDate(transactionDate.toLocalDateAndOrgId(orgDAO::getTimeZone))
.year(createLogRequest.getYearId())
.description(description)
.modularContractTypeId(createLogRequest.getTypeId())
.configId(createLogRequest.getConfigId())
.collectionPointBPartnerId(collectionPointBPartnerId)
.invoicingGroupId(invoicingGroupId)
.isBillable(true)
.priceActual(price)
.amount(price.computeAmount(qty, uomConversionBL))
.build());
}

@Override
public @NonNull ExplainedOptional<LogEntryReverseRequest> createLogEntryReverseRequest(@NonNull final CreateLogRequest createLogRequest)
{
throw new UnsupportedOperationException();
}

@Override
@NonNull
public LogEntryDeleteRequest toLogEntryDeleteRequest(@NonNull final HandleLogsRequest handleLogsRequest)
protected ProductId extractProductIdToLog(
@NonNull final IModularContractLogHandler.CreateLogRequest request,
@NonNull final ManufacturingReceipt manufacturingReceipt)
{
final ManufacturingReceipt manufacturingReceipt = manufacturingFacadeService.getManufacturingReceipt(handleLogsRequest.getTableRecordReference());

return LogEntryDeleteRequest.builder()
.referencedModel(manufacturingReceipt.getManufacturingOrderId().toRecordRef())
.subEntryId(LogSubEntryId.ofCostCollectorId(manufacturingReceipt.getId()))
.flatrateTermId(handleLogsRequest.getContractId())
.logEntryContractType(getLogEntryContractType())
.build();
return manufacturingReceipt.getProductId();
}

}
Loading

0 comments on commit 4d7c481

Please sign in to comment.