-
Notifications
You must be signed in to change notification settings - Fork 568
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
052756a
commit e2e8a81
Showing
4 changed files
with
332 additions
and
0 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
...swat/de.metas.swat.base/src/main/java/de/metas/inoutcandidate/api/IReceiptSchedulePA.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* #%L | ||
* de.metas.swat.base | ||
* %% | ||
* 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 | ||
* <http://www.gnu.org/licenses/gpl-2.0.html>. | ||
* #L% | ||
*/ | ||
|
||
package de.metas.inoutcandidate.api; | ||
|
||
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule; | ||
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 java.util.Properties; | ||
|
||
/** | ||
* Implementers give database access to {@link I_M_ReceiptSchedule} instances (DAO). | ||
* | ||
* @author dp | ||
* | ||
*/ | ||
|
||
public interface IReceiptSchedulePA extends ISingletonService | ||
{ | ||
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); | ||
} |
189 changes: 189 additions & 0 deletions
189
.../de.metas.swat.base/src/main/java/de/metas/inoutcandidate/api/impl/ReceiptSchedulePA.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* | ||
* #%L | ||
* de.metas.swat.base | ||
* %% | ||
* 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 | ||
* <http://www.gnu.org/licenses/gpl-2.0.html>. | ||
* #L% | ||
*/ | ||
|
||
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.inoutcandidate.ReceiptScheduleId; | ||
import de.metas.inoutcandidate.api.IReceiptSchedulePA; | ||
import de.metas.inoutcandidate.exportaudit.APIExportStatus; | ||
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule; | ||
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.impl.ModelColumnNameValue; | ||
import org.adempiere.ad.trx.api.ITrx; | ||
|
||
import java.util.Properties; | ||
|
||
public class ReceiptSchedulePA implements IReceiptSchedulePA | ||
{ | ||
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 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, | ||
false /* invalidate */ | ||
); | ||
} | ||
|
||
/** | ||
* Mass-update a given shipment schedule column. | ||
* | ||
* If there were any changes and the invalidate parameter is on true, those shipment schedules will be invalidated. | ||
* | ||
* @param inoutCandidateColumnName {@link I_M_ShipmentSchedule}'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, | ||
final boolean invalidate) | ||
{ | ||
// | ||
// 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_ShipmentSchedule.Table_Name); | ||
} | ||
|
||
// | ||
// Perform the actual cache invalidation | ||
if (request != null) | ||
{ | ||
CacheMgt.get().resetLocalNowAndBroadcastOnTrxCommit(ITrx.TRXNAME_ThreadInherited, request); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...e/src/main/java/de/metas/inoutcandidate/process/M_ReceiptSchedule_ChangeExportStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* #%L | ||
* de.metas.swat.base | ||
* %% | ||
* 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 | ||
* <http://www.gnu.org/licenses/gpl-2.0.html>. | ||
* #L% | ||
*/ | ||
|
||
package de.metas.inoutcandidate.process; | ||
|
||
import de.metas.i18n.AdMessageKey; | ||
import de.metas.inoutcandidate.api.IReceiptSchedulePA; | ||
import de.metas.inoutcandidate.model.I_M_ReceiptSchedule; | ||
import de.metas.process.IProcessPrecondition; | ||
import de.metas.process.IProcessPreconditionsContext; | ||
import de.metas.process.JavaProcess; | ||
import de.metas.process.PInstanceId; | ||
import de.metas.process.Param; | ||
import de.metas.process.ProcessPreconditionsResolution; | ||
import de.metas.util.Services; | ||
import lombok.NonNull; | ||
import org.adempiere.ad.dao.IQueryBuilder; | ||
import org.adempiere.ad.dao.IQueryFilter; | ||
import org.adempiere.exceptions.AdempiereException; | ||
|
||
public class M_ReceiptSchedule_ChangeExportStatus extends JavaProcess implements IProcessPrecondition | ||
{ | ||
private final IReceiptSchedulePA receiptSchedulePA = Services.get(IReceiptSchedulePA.class); | ||
|
||
private static final AdMessageKey MSG_NO_UNPROCESSED_LINES = AdMessageKey.of("receiptschedule.noUnprocessedLines"); | ||
|
||
private static final String PARAM_ExportStatus = "ExportStatus"; | ||
@Param(parameterName = PARAM_ExportStatus, mandatory = true) | ||
private String exportStatus; | ||
|
||
@Override | ||
public ProcessPreconditionsResolution checkPreconditionsApplicable(@NonNull final IProcessPreconditionsContext context) | ||
{ | ||
if (context.isNoSelection()) | ||
{ | ||
return ProcessPreconditionsResolution.rejectBecauseNoSelection(); | ||
} | ||
|
||
return ProcessPreconditionsResolution.accept(); | ||
} | ||
|
||
@Override | ||
protected void prepare() | ||
{ | ||
final IQueryFilter<I_M_ReceiptSchedule> userSelectionFilter = getProcessInfo().getQueryFilterOrElseFalse(); | ||
final IQueryBuilder<de.metas.inoutcandidate.model.I_M_ReceiptSchedule> queryBuilderForShipmentSchedulesSelection = receiptSchedulePA.createQueryForShipmentScheduleSelection(getCtx(), userSelectionFilter); | ||
|
||
// Create selection and return how many items were added | ||
final int selectionCount = queryBuilderForShipmentSchedulesSelection | ||
.create() | ||
.createSelection(getPinstanceId()); | ||
|
||
if (selectionCount <= 0) | ||
{ | ||
throw new AdempiereException(MSG_NO_UNPROCESSED_LINES) | ||
.markAsUserValidationError(); | ||
} | ||
|
||
} | ||
|
||
@Override | ||
protected String doIt() throws Exception | ||
{ | ||
final PInstanceId pinstanceId = getPinstanceId(); | ||
|
||
// update delivery date | ||
// no invalidation | ||
receiptSchedulePA.updateExportStatus(exportStatus, pinstanceId); | ||
|
||
return MSG_OK; | ||
} | ||
} |