Skip to content

Commit

Permalink
Not all picking slots are released
Browse files Browse the repository at this point in the history
refs: #17813
  • Loading branch information
cp-ps committed Apr 10, 2024
1 parent b2c567c commit 6ac3c47
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.metas.cucumber.stepdefs.picking;

import de.metas.cucumber.stepdefs.C_BPartner_Location_StepDefData;
import de.metas.cucumber.stepdefs.C_BPartner_StepDefData;
import de.metas.cucumber.stepdefs.DataTableRow;
import de.metas.cucumber.stepdefs.DataTableRows;
import de.metas.cucumber.stepdefs.StepDefDataIdentifier;
Expand All @@ -8,12 +10,16 @@
import de.metas.util.Services;
import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.adempiere.model.InterfaceWrapperHelper;
import org.adempiere.warehouse.LocatorId;
import org.adempiere.warehouse.WarehouseId;
import org.adempiere.warehouse.api.IWarehouseBL;
import org.assertj.core.api.SoftAssertions;
import org.compiere.model.I_C_BPartner;
import org.compiere.model.I_C_BPartner_Location;

@RequiredArgsConstructor
public class PickingSlot_StepDef
Expand All @@ -22,13 +28,51 @@ public class PickingSlot_StepDef
@NonNull private final IWarehouseBL warehouseBL = Services.get(IWarehouseBL.class);

@NonNull private final PickingSlot_StepDefData pickingSlotsTable;
@NonNull private final C_BPartner_StepDefData bpartnerTable;
@NonNull private final C_BPartner_Location_StepDefData bpartnerLocationTable;

@Given("metasfresh contains M_PickingSlot:")
public void createPickingSlots(@NonNull final DataTable dataTable)
{
DataTableRows.of(dataTable).forEach(this::createPickingSlot);
}

@Then("validate M_PickingSlot:")
public void validatePickingSlot(@NonNull final DataTable dataTable)
{
DataTableRows.of(dataTable).forEach((tableRow) -> {
final I_M_PickingSlot pickingSlot = tableRow
.getAsIdentifier(I_M_PickingSlot.COLUMNNAME_M_PickingSlot_ID)
.lookupIn(pickingSlotsTable);

final SoftAssertions softAssertions = new SoftAssertions();

tableRow.getAsOptionalIdentifier(I_M_PickingSlot.COLUMNNAME_C_BPartner_ID)
.map(identifier -> identifier.lookupIn(bpartnerTable))
.map(I_C_BPartner::getC_BPartner_ID)
.ifPresent(bpartnerId -> softAssertions.assertThat(pickingSlot.getC_BPartner_ID()).isEqualTo(bpartnerId));

tableRow.getAsOptionalIdentifier(I_M_PickingSlot.COLUMNNAME_C_BPartner_Location_ID)
.map(identifier -> identifier.lookupIn(bpartnerLocationTable))
.map(I_C_BPartner_Location::getC_BPartner_Location_ID)
.ifPresent(bpartnerLocationId -> softAssertions.assertThat(pickingSlot.getC_BPartner_Location_ID()).isEqualTo(bpartnerLocationId));

tableRow.getAsOptionalBoolean("IsAllocated")
.ifPresent(isAllocated -> {
if (isAllocated)
{
softAssertions.assertThat(pickingSlot.getC_BPartner_ID()).isGreaterThan(0);
softAssertions.assertThat(pickingSlot.getC_BPartner_Location_ID()).isGreaterThan(0);
}
else
{
softAssertions.assertThat(pickingSlot.getC_BPartner_ID()).isEqualTo(0);
softAssertions.assertThat(pickingSlot.getC_BPartner_Location_ID()).isEqualTo(0);
}
});
});
}

private void createPickingSlot(@NonNull final DataTableRow row)
{
final String pickingSlotCode = row.getAsName("PickingSlot");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@from:cucumber
@ghActions:run_on_executor7
Feature: Picking workflow - abort not started picking jobs after shipment

Background:
Given infrastructure and metasfresh are running
And the existing user with login 'metasfresh' receives a random a API token for the existing role with name 'WebUI'
And metasfresh has date and time 2022-08-18T13:30:13+01:00[Europe/Berlin]
And set sys config boolean value true for sys config SKIP_WP_PROCESSOR_FOR_AUTOMATION
And metasfresh contains M_PricingSystems
| Identifier | Name | Value | OPT.Description | OPT.IsActive |
| picking_pricing_system_17813 | picking_pricing_system_17813Name | picking_pricing_system_17813Value | picking_pricing_system_17813Description | true |
And metasfresh contains M_PriceLists
| Identifier | M_PricingSystem_ID.Identifier | OPT.C_Country.CountryCode | C_Currency.ISO_Code | Name | OPT.Description | SOTrx | IsTaxIncluded | PricePrecision | OPT.IsActive |
| picking_picelist_17813 | picking_pricing_system_17813 | DE | EUR | picking_pricelist_17813 | null | true | false | 2 | true |
And metasfresh contains M_PriceList_Versions
| Identifier | M_PriceList_ID.Identifier | Name | ValidFrom |
| picking_pricelistversion_17813 | picking_picelist_17813 | picking_pricelistversion_17813Name | 2021-04-01 |
And metasfresh contains M_Products:
| Identifier | Name |
| picking_product_17813 | picking_product_17813 |
And metasfresh contains M_ProductPrices
| Identifier | M_PriceList_Version_ID.Identifier | M_Product_ID.Identifier | PriceStd | C_UOM_ID.X12DE355 | C_TaxCategory_ID.InternalName |
| workflowProductPrice | picking_pricelistversion_17813 | picking_product_17813 | 5.0 | PCE | Normal |

And set mobile UI picking profile
| IsAllowPickingAnyHU | CreateShipmentPolicy |
| Y | CREATE_AND_COMPLETE |
And metasfresh contains C_BPartners without locations:
| Identifier | Name | OPT.IsVendor | OPT.IsCustomer | M_PricingSystem_ID.Identifier |
| pickingCustomer_17813 | pickingCustomer_17813 | N | Y | picking_pricing_system_17813 |
And metasfresh contains C_BPartner_Locations:
| Identifier | GLN | C_BPartner_ID.Identifier | OPT.IsBillToDefault | OPT.IsShipTo |
| pickingCustomer_17813Location | picking_GLN_17813 | pickingCustomer_17813 | true | true |

And metasfresh contains C_Orders:
| Identifier | IsSOTrx | C_BPartner_ID.Identifier | DateOrdered |
| salesOrder_17813 | true | pickingCustomer_17813 | 2021-04-15 |
And metasfresh contains C_OrderLines:
| Identifier | C_Order_ID.Identifier | M_Product_ID.Identifier | QtyEntered |
| salesOrder_17813Line | salesOrder_17813 | picking_product_17813 | 10 |

And the order identified by salesOrder_17813 is completed

And after not more than 60s, M_ShipmentSchedules are found:
| Identifier | C_OrderLine_ID.Identifier | IsToRecompute |
| pickingShipmentSchedule | salesOrder_17813Line | N |


@from:cucumber
Scenario: Abort not started picking jobs after shipment
Given start picking job for sales order identified by salesOrder_17813
And metasfresh contains M_PickingSlot:
| Identifier | PickingSlot | IsDynamic |
| 300.0 | 300.0 | Y |
And scan picking slot identified by 300.0
And validate M_PickingSlot:
| M_PickingSlot_ID.Identifier | C_BPartner_ID.Identifier | C_BPartner_Location_ID.Identifier |
| 300.0 | pickingCustomer_17813 | pickingCustomer_17813Location |
When 'generate shipments' process is invoked
| M_ShipmentSchedule_ID.Identifier | QuantityType | IsCompleteShipments | IsShipToday |
| pickingShipmentSchedule | D | true | false |
Then validate M_PickingSlot:
| M_PickingSlot_ID.Identifier | IsAllocated |
| 300.0 | N |

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* #%L
* de.metas.handlingunits.base
* %%
* 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.handlingunits.picking.interceptor;

import de.metas.handlingunits.picking.job.service.PickingJobService;
import de.metas.inoutcandidate.api.IShipmentScheduleAllocDAO;
import de.metas.util.Services;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.adempiere.ad.modelvalidator.annotations.DocValidate;
import org.adempiere.ad.modelvalidator.annotations.Interceptor;
import org.compiere.model.I_M_InOut;
import org.compiere.model.ModelValidator;
import org.springframework.stereotype.Component;

@Interceptor(I_M_InOut.class)
@Component
@RequiredArgsConstructor
public class M_InOut
{
private final IShipmentScheduleAllocDAO shipmentScheduleAllocDAO = Services.get(IShipmentScheduleAllocDAO.class);

private final PickingJobService pickingJobService;

@DocValidate(timings = ModelValidator.TIMING_AFTER_COMPLETE)
public void afterComplete(@NonNull final I_M_InOut shipment)
{
shipmentScheduleAllocDAO.retrieveOrderIds(shipment).forEach(pickingJobService::abortNotStartedForSalesOrderId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ public void abortForSalesOrderId(@NonNull final OrderId salesOrderId)
.ifPresent(this::abort);
}

public void abortNotStartedForSalesOrderId(@NonNull final OrderId salesOrderId)
{
pickingJobRepository
.getDraftBySalesOrderId(salesOrderId, pickingJobLoaderSupportingServicesFactory.createLoaderSupportingServices())
.filter(PickingJob::isNothingPicked)
.ifPresent(this::abort);
}

@NonNull
public Stream<PickingJobReference> streamDraftPickingJobReferences(@NonNull final PickingJobReferenceQuery query)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import de.metas.inout.model.I_M_InOut;
import de.metas.inoutcandidate.model.I_M_ShipmentSchedule;
import de.metas.inoutcandidate.model.I_M_ShipmentSchedule_QtyPicked;
import de.metas.order.OrderId;
import de.metas.util.ISingletonService;
import lombok.NonNull;
import org.adempiere.ad.dao.IQueryBuilder;
Expand Down Expand Up @@ -125,4 +126,7 @@ <T extends I_M_ShipmentSchedule_QtyPicked> ImmutableListMultimap<ShipmentSchedul
ImmutableListMultimap<ShipmentScheduleId, I_M_ShipmentSchedule_QtyPicked> retrieveOnShipmentLineRecordsByScheduleIds(Set<ShipmentScheduleId> scheduleIds);

<T extends I_M_ShipmentSchedule_QtyPicked> List<T> retrievePickedOnTheFlyAndNotDelivered(ShipmentScheduleId shipmentScheduleId, Class<T> modelClass);

@NonNull
Set<OrderId> retrieveOrderIds(@NonNull org.compiere.model.I_M_InOut inOut);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.metas.inoutcandidate.api.impl;

import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import de.metas.inout.InOutLineId;
import de.metas.inout.ShipmentScheduleId;
import de.metas.inout.model.I_M_InOut;
Expand All @@ -9,6 +10,7 @@
import de.metas.inoutcandidate.model.I_M_ShipmentSchedule;
import de.metas.inoutcandidate.model.I_M_ShipmentSchedule_QtyPicked;
import de.metas.logging.LogManager;
import de.metas.order.OrderId;
import de.metas.util.Services;
import lombok.NonNull;
import org.adempiere.ad.dao.ICompositeQueryFilter;
Expand Down Expand Up @@ -386,4 +388,20 @@ public <T extends I_M_ShipmentSchedule_QtyPicked> List<T> retrievePickedOnTheFly
.create()
.list(modelClass);
}

@Override
@NonNull
public Set<OrderId> retrieveOrderIds(@NonNull final org.compiere.model.I_M_InOut inOut)
{
return queryBL.createQueryBuilder(I_M_InOutLine.class, inOut)
.addEqualsFilter(I_M_InOutLine.COLUMN_M_InOut_ID, inOut.getM_InOut_ID())
.andCollectChildren(I_M_ShipmentSchedule_QtyPicked.COLUMN_M_InOutLine_ID, I_M_ShipmentSchedule_QtyPicked.class)
.andCollect(I_M_ShipmentSchedule_QtyPicked.COLUMN_M_ShipmentSchedule_ID)
.andCollect(I_M_ShipmentSchedule.COLUMN_C_Order_ID)
.create()
.listIds()
.stream()
.map(OrderId::ofRepoId)
.collect(ImmutableSet.toImmutableSet());
}
}

0 comments on commit 6ac3c47

Please sign in to comment.