Skip to content

Commit

Permalink
Gh7012 receipt schedule adj (#7047)
Browse files Browse the repository at this point in the history
* extending the json-pojos; about to add tables and stuff

* implement big part of shipment schedule exporting

TODO
* unit tests for ShipmentCandidateExporter and ShipmentScheduleAuditRepository
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinante what's missing

#7012

* add "Export" fields to shipment schedule window

TODO
* unit tests for ShipmentCandidateExporter and ShipmentScheduleAuditRepository
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinante what's missing

#7012

* work on ShipmentCandidateExporterTest

TODO
* unit tests for ShipmentCandidateExporter
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* #7012 New Shipment Disposition Window.

* #7012 Removed script belonging to private repo.

* finish ShipmentCandidateExporterTest and add another export status

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* create filemaker-pojos so we can read&write XML

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* minor fixes

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* minor fixes

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* add additional exportstatus "don't export"

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* add additional exportstatus "don't export"

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* go at another enforcer dependency convergence error

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* `Picking Terminal V2`: Add process for picking and packing in 1 step (#6950)

(cherry picked from commit c03f7d2)

* ProductsToPickViewFactory: Inject the constructor via Spring instead of SpringContextHolder (#6970)

#6949
(cherry picked from commit 9d6fda6)

* Picking Terminal V2: Pick&Pack: Skip rows with qty 0 (#7022)

(cherry picked from commit fd95e03)

* Fixes after cherrypicks

#7021

* work on camel testing

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* Updated ReleaseNotes.md

added issues

* minor fix: don't export scheds with qtyToDeliver<=0

TODO
* MIs, ErrorMessages etc to prevent fiddling with exported shipment schedules
* dev-test;
* also see & coordinate what's missing

#7012

* Update WEBUI_M_HU_ReturnFromCustomer.java (#7028)

* div. improvements

* Use jackson-stuff in our camel route
* Send feedback to metasfresh
* Update audit records using feedback
* convert JSON to XML
* simplify audit records in metasfresh
* Also
  * CacheInvalidateMultiRequest with better support for RepoIdAwares

  #7012

* fixes

  #7012

* fixes

#7012

* attempt to fix criculary error handling + dependency conversion errors

#7012

* minor

#7012

* minor

#7012

* work on fixing tests

#7012

* attempt to fix dependency conversion errors
#7012

* rename/more classes and modules; meekly start with receipt-candidates

#7012

* attempt to fix dependency conversion errors

#7012

* Add ExportStatus and CanBeExportedFrom for M_ReceiptSchedule

#7012

* Starting with Receipt Candidate API

* move ShipmentScheduleId class
* extract common APIExportAudit and APIExportAuditRepository
* start receipt candidate code (similar to shipment candidate, but e.g. different classes)

#7012

* fix module name

#7012

* Starting with Receipt Candidate API

* pom.xml fix typo in exclusion
* start implementing the camel part as well

#7012

* Upgrade lodash due to security advisory (#7031)

Co-authored-by: Petrica Nanca <petrica.nanca@metasfresh.com>

* Add extra checks for clearing the filter (#7032)

Co-authored-by: Petrica Nanca <petrica.nanca@metasfresh.com>

* solve another depdendency conversion error

#7012

* solve after-refactor-error

#7012

* attempt to solve dependency convergence error

#7012

* work on json-XML-mapping for receipt schedules

#7012

* fix docker image name in build descr

#7012

* bunch of finetuning

#7012

* fix NPE

#7012

* improve logging, do a bit of deduplication

#7012

* minor fix

#7012

* improve route-ids

#7012

* minor tweaks

#7012

* minor tweaks

#7012

* fix problem wrt attribute set instance

#7012

* fix(SEPA Export): schemaLocation (#7034)

* add unit test

#7012

* - use included view from `listHandler` if it exists (#7035)

* do not retry in genereal, but only when uploading the result

#7012

* fix feedback-routes

#7012

* hotfix: filter does not work in "return HUs to customer" view (#7033)

* fix API-Export list value

#7012

* Revert "hotfix: filter does not work in "return HUs to customer" view (#7033)"

This reverts commit 0be2b94

* smaller fixes during review

#7012

* finally managing working tests

#7012

* #7012 Initial commit.

* Revert "#7012 Initial commit."

This reverts commit e2e8a81

* #7012 Initial commit.

* #7012 Second commit

* #7012 Receipt Schedule & Purchase Order adjustments.
   - can no longer reactivate or void purchase order with exported receipt schedules.
   - new process to change the export status of receipt schedules.

* #7012 Deleted ReceiptSchedulePA and moved metods to DAO class.

* #7012
- changed usage of deleted PA class to DAO in C_Order.

* Customer return not working bc HUs cannot be selected (#7040)

#6420
(cherry picked from commit 5be1b54)

* Gh7012 shipmentschedule rest api (#7024)

Co-authored-by: Petrica Nanca <petrica.nanca@metasfresh.com>
Co-authored-by: Tobias Schöneberg <tobias.schoeneberg@metasfresh.com>
Co-authored-by: TheBestPessimist <cristian@tbp.land>
Co-authored-by: Kay <kay.kostelnik@metasfresh.com>
Co-authored-by: Teo Sarca <teo.sarca@metasfresh.com>
Co-authored-by: Petrica Nanca <petrica_nanca@yahoo.com>
Co-authored-by: Peter Wyss <peter.wyss@kommunikativ.ch>
Co-authored-by: Kuba Siemiątkowski <kuba@saskla.cz>
Co-authored-by: Tobias Schöneberg <metas-ts@users.noreply.github.com>

* add some documentation

* fix build description for de-metas-camel-shipping

* #7012 merged blonde_monkey_uat. Resolved Conflicts.

* #7012 moved migration scripts to right folder. update wrong script number.

Co-authored-by: Tobias Schöneberg <tobias.schoeneberg@metasfresh.com>
Co-authored-by: TheBestPessimist <cristian@tbp.land>
Co-authored-by: Kay <kay.kostelnik@metasfresh.com>
Co-authored-by: Teo Sarca <teo.sarca@metasfresh.com>
Co-authored-by: Petrica Nanca <petrica_nanca@yahoo.com>
Co-authored-by: Petrica Nanca <petrica.nanca@metasfresh.com>
Co-authored-by: Peter Wyss <peter.wyss@kommunikativ.ch>
Co-authored-by: Kuba Siemiątkowski <kuba@saskla.cz>
Co-authored-by: Tobias Schöneberg <metas-ts@users.noreply.github.com>
  • Loading branch information
10 people committed Jul 23, 2020
1 parent 2b85d67 commit 75cac97
Show file tree
Hide file tree
Showing 8 changed files with 378 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,29 @@
* #L%
*/

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import de.metas.inoutcandidate.model.I_M_ReceiptSchedule;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule_Alloc;
import de.metas.invoicecandidate.model.I_C_Invoice_Candidate;
import de.metas.order.OrderId;
import de.metas.process.PInstanceId;
import de.metas.util.ISingletonService;
import lombok.NonNull;
import org.adempiere.ad.dao.IQueryBuilder;
import org.adempiere.ad.dao.IQueryFilter;
import org.compiere.model.IQuery;
import org.compiere.model.I_M_InOut;
import org.compiere.model.I_M_InOutLine;

import de.metas.inoutcandidate.model.I_M_ReceiptSchedule;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule_Alloc;
import de.metas.invoicecandidate.model.I_C_Invoice_Candidate;
import de.metas.util.ISingletonService;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

public interface IReceiptScheduleDAO extends ISingletonService
{
/**
* Retrieve an iterator over receipt schedules fetched by query.
*
* <p>
* The receipt schedules will be ordered by {@link I_M_ReceiptSchedule#COLUMNNAME_HeaderAggregationKey}.
*
* @param query
Expand Down Expand Up @@ -84,4 +88,10 @@ public interface IReceiptScheduleDAO extends ISingletonService
* @return
*/
Set<I_M_ReceiptSchedule> retrieveForInvoiceCandidate(I_C_Invoice_Candidate candidate);

IQueryBuilder<I_M_ReceiptSchedule> createQueryForShipmentScheduleSelection(Properties ctx, IQueryFilter<I_M_ReceiptSchedule> userSelectionFilter);

boolean existsExportedReceiptScheduleForOrder(@NonNull final OrderId orderId);

void updateExportStatus(final String exportStatus, final PInstanceId pinstanceId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
package de.metas.inoutcandidate.api.impl;

import com.google.common.collect.ImmutableSet;
import de.metas.cache.CacheMgt;
import de.metas.cache.model.CacheInvalidateMultiRequest;
import de.metas.document.engine.IDocument;
import de.metas.inout.model.I_M_InOutLine;
import de.metas.inoutcandidate.ReceiptScheduleId;
import de.metas.inoutcandidate.api.IReceiptScheduleDAO;
import de.metas.inoutcandidate.exportaudit.APIExportStatus;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule_Alloc;
import de.metas.interfaces.I_C_OrderLine;
import de.metas.invoicecandidate.model.I_C_Invoice_Candidate;
import de.metas.order.OrderId;
import de.metas.process.PInstanceId;
import de.metas.util.Services;
import lombok.NonNull;
import org.adempiere.ad.dao.IQueryBL;
import org.adempiere.ad.dao.IQueryBuilder;
import org.adempiere.ad.dao.IQueryFilter;
import org.adempiere.ad.dao.IQueryOrderBy;
import org.adempiere.ad.dao.impl.EqualsQueryFilter;
import org.adempiere.ad.dao.impl.ModelColumnNameValue;
import org.adempiere.ad.table.api.IADTableDAO;
import org.adempiere.ad.trx.api.ITrx;
import org.adempiere.model.InterfaceWrapperHelper;
import org.compiere.model.IQuery;
import org.compiere.model.I_M_InOut;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/*
* #%L
Expand All @@ -24,37 +57,14 @@
* #L%
*/

import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.annotation.Nullable;

import org.adempiere.ad.dao.IQueryBL;
import org.adempiere.ad.dao.IQueryBuilder;
import org.adempiere.ad.dao.IQueryOrderBy;
import org.adempiere.ad.dao.impl.EqualsQueryFilter;
import org.adempiere.ad.table.api.IADTableDAO;
import org.adempiere.model.InterfaceWrapperHelper;
import org.compiere.model.IQuery;
import org.compiere.model.I_M_InOut;

import com.google.common.collect.ImmutableSet;

import de.metas.document.engine.IDocument;
import de.metas.inout.model.I_M_InOutLine;
import de.metas.inoutcandidate.api.IReceiptScheduleDAO;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule;
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule_Alloc;
import de.metas.interfaces.I_C_OrderLine;
import de.metas.invoicecandidate.model.I_C_Invoice_Candidate;
import de.metas.util.Check;
import de.metas.util.Services;
import lombok.NonNull;

public class ReceiptScheduleDAO implements IReceiptScheduleDAO
{
private final IQueryBL queryBL = Services.get(IQueryBL.class);

/**
* When mass cache invalidation, above this threshold we will invalidate ALL shipment schedule records instead of particular IDS
*/
private static final int CACHE_INVALIDATE_ALL_THRESHOLD = 200;

@Override
public Iterator<I_M_ReceiptSchedule> retrieve(final IQuery<I_M_ReceiptSchedule> query)
Expand Down Expand Up @@ -281,4 +291,142 @@ public List<I_M_ReceiptSchedule> retrieveRsForInOutLine(@Nullable final org.comp
.create()
.list();
}

@Override
public IQueryBuilder<I_M_ReceiptSchedule> createQueryForShipmentScheduleSelection(final Properties ctx, final IQueryFilter<I_M_ReceiptSchedule> userSelectionFilter)
{
final IQueryBuilder<I_M_ReceiptSchedule> queryBuilder = queryBL
.createQueryBuilder(I_M_ReceiptSchedule.class, ctx, ITrx.TRXNAME_None)
.filter(userSelectionFilter)
.addEqualsFilter(I_M_ReceiptSchedule.COLUMNNAME_Processed, false)
.addOnlyActiveRecordsFilter()
.addOnlyContextClient();

return queryBuilder;
}

@Override
public boolean existsExportedReceiptScheduleForOrder(final @NonNull OrderId orderId)
{
return queryBL
.createQueryBuilder(I_M_ReceiptSchedule.class)
.addOnlyActiveRecordsFilter()
.addEqualsFilter(I_M_ReceiptSchedule.COLUMNNAME_C_Order_ID, orderId)
.addEqualsFilter(I_M_ReceiptSchedule.COLUMNNAME_Processed, false)
.addInArrayFilter(I_M_ReceiptSchedule.COLUMNNAME_ExportStatus, APIExportStatus.EXPORTED_STATES)
.create()
.anyMatch();
}

@Override
public void updateExportStatus(final String exportStatus, final PInstanceId pinstanceId)
{
updateColumnForSelection(
I_M_ReceiptSchedule.COLUMNNAME_ExportStatus,
exportStatus,
false /* updateOnlyIfNull */,
pinstanceId
);
}

/**
* Mass-update a given shipment schedule column.
* <p>
* If there were any changes and the invalidate parameter is on true, those shipment schedules will be invalidated.
*
* @param inoutCandidateColumnName {@link I_M_ReceiptSchedule}'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 ShipmentSchedule selection (AD_PInstance_ID)
* @param trxName
*/
private final <ValueType> void updateColumnForSelection(
final String inoutCandidateColumnName,
final ValueType value,
final boolean updateOnlyIfNull,
final PInstanceId selectionId
)
{
//
// Create the selection which we will need to update
final IQueryBuilder<I_M_ReceiptSchedule> selectionQueryBuilder = queryBL
.createQueryBuilder(I_M_ReceiptSchedule.class)
.setOnlySelection(selectionId)
.addEqualsFilter(I_M_ReceiptSchedule.COLUMNNAME_Processed, false) // do not touch the processed shipment schedules
;

if (updateOnlyIfNull)
{
selectionQueryBuilder.addEqualsFilter(inoutCandidateColumnName, null);
}
final PInstanceId selectionToUpdateId = selectionQueryBuilder.create().createSelection();
if (selectionToUpdateId == null)
{
// nothing to update
return;
}

//
// Update our new selection
final int countUpdated = queryBL.createQueryBuilder(I_M_ReceiptSchedule.class)
.setOnlySelection(selectionToUpdateId)
.create()
.updateDirectly()
.addSetColumnValue(inoutCandidateColumnName, value)
.execute();

//
// Cache invalidate
// We have to do this even if invalidate=false
cacheInvalidateBySelectionId(selectionToUpdateId, countUpdated);
}

private void cacheInvalidateBySelectionId(
@NonNull final PInstanceId selectionId,
final long estimatedSize)
{
final CacheInvalidateMultiRequest request;
if (estimatedSize < 0)
{
// unknown estimated size
request = CacheInvalidateMultiRequest.allRecordsForTable(I_M_ReceiptSchedule.Table_Name);
}
else if (estimatedSize == 0)
{
// no records
// unknown estimated size
request = null;
}
else if (estimatedSize <= CACHE_INVALIDATE_ALL_THRESHOLD)
{
// relatively small amount of records
// => fetch and reset individually
final ImmutableSet<ReceiptScheduleId> shipmentScheduleIds = queryBL.createQueryBuilder(I_M_ReceiptSchedule.class)
.setOnlySelection(selectionId)
.create()
.listIds(ReceiptScheduleId::ofRepoId);
if (!shipmentScheduleIds.isEmpty())
{
request = CacheInvalidateMultiRequest.rootRecords(I_M_ReceiptSchedule.Table_Name, shipmentScheduleIds);
}
else
{
// no records found => do nothing
request = null;
}
}
else
{
// large amount of records
// => instead of fetching all IDs better invalidate the whole table
request = CacheInvalidateMultiRequest.allRecordsForTable(I_M_ReceiptSchedule.Table_Name);
}

//
// Perform the actual cache invalidation
if (request != null)
{
CacheMgt.get().resetLocalNowAndBroadcastOnTrxCommit(ITrx.TRXNAME_ThreadInherited, request);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import de.metas.inoutcandidate.model.X_M_ShipmentSchedule;
import de.metas.order.InvoiceRule;
import de.metas.util.lang.ReferenceListAwareEnum;
import lombok.Getter;
import lombok.NonNull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.metas.inoutcandidate.modelvalidator;

import de.metas.i18n.AdMessageKey;
import de.metas.inoutcandidate.api.IReceiptScheduleDAO;
import de.metas.inoutcandidate.api.IShipmentConstraintsBL;
import de.metas.inoutcandidate.api.IShipmentSchedulePA;
import de.metas.order.OrderId;
Expand Down Expand Up @@ -36,9 +37,12 @@
@Interceptor(I_C_Order.class)
public class C_Order
{
private final IReceiptScheduleDAO receiptScheduleDAO = Services.get(IReceiptScheduleDAO.class);
private final IShipmentSchedulePA shipmentSchedulePA = Services.get(IShipmentSchedulePA.class);

private static final AdMessageKey MSG_CannotCompleteOrder_DeliveryStop = AdMessageKey.of("CannotCompleteOrder_DeliveryStop");
private static final AdMessageKey MSG_REACTIVATION_VOID_NOT_ALLOWED = AdMessageKey.of("salesorder.shipmentschedule.exported");
private static final AdMessageKey MSG_PO_REACTIVATION_VOID_NOT_ALLOWED = AdMessageKey.of("purchaseorder.shipmentschedule.exported");

@DocValidate(timings = ModelValidator.TIMING_BEFORE_PREPARE)
public void assertNotDeliveryStopped(final I_C_Order order)
Expand All @@ -48,6 +52,7 @@ public void assertNotDeliveryStopped(final I_C_Order order)
{
return;
}

final int billPartnerId = order.getBill_BPartner_ID();
final int deliveryStopShipmentConstraintId = Services.get(IShipmentConstraintsBL.class).getDeliveryStopShipmentConstraintId(billPartnerId);
final boolean isDeliveryStop = deliveryStopShipmentConstraintId > 0;
Expand All @@ -74,4 +79,21 @@ public void assertReActivationAllowed(final I_C_Order order)
.markAsUserValidationError();
}
}

@DocValidate(timings = { ModelValidator.TIMING_BEFORE_REACTIVATE,
ModelValidator.TIMING_BEFORE_REVERSEACCRUAL,
ModelValidator.TIMING_BEFORE_REVERSECORRECT,
ModelValidator.TIMING_BEFORE_VOID })
public void assertPOReActivationAllowed(final I_C_Order order)
{
if (order.isSOTrx())
{
return; // we can spare us the effort
}
if (receiptScheduleDAO.existsExportedReceiptScheduleForOrder(OrderId.ofRepoId(order.getC_Order_ID())))
{
throw new AdempiereException(MSG_PO_REACTIVATION_VOID_NOT_ALLOWED)
.markAsUserValidationError();
}
}
}
Loading

0 comments on commit 75cac97

Please sign in to comment.