| Line 894... |
Line 894... |
| 894 |
inventoryItems = inventoryItems.stream().filter(x -> !agedSerialNumbers.contains(x.getSerialNumber())).collect(Collectors.toSet());
|
894 |
inventoryItems = inventoryItems.stream().filter(x -> !agedSerialNumbers.contains(x.getSerialNumber())).collect(Collectors.toSet());
|
| 895 |
}
|
895 |
}
|
| 896 |
|
896 |
|
| 897 |
if (inventoryItems.size() == 0) return 0;
|
897 |
if (inventoryItems.size() == 0) return 0;
|
| 898 |
|
898 |
|
| 899 |
// Resolve GRN billing date per inventory item: InventoryItem.purchaseId -> Purchase.purchaseReference -> Order.billingTimestamp.
|
899 |
Map<Integer, List<InventoryItem>> catalogInventoryItemMap = inventoryItems.stream().collect(Collectors.groupingBy(x -> x.getItem().getCatalogItemId()));
|
| 900 |
// Scheme resolution for OUT must use each item's own GRN billing date, not fofoOrder.createTimestamp.
|
900 |
Map<CatalogSummaryModel, List<SchemeSummaryModel>> catalogSchemeSummaryMap = tagListingRepository.getModelSchemesByCatalogIdsAndType(retailerId,
|
| 901 |
Set<Integer> purchaseIds = inventoryItems.stream().map(InventoryItem::getPurchaseId).collect(Collectors.toSet());
|
901 |
partnerType, new ArrayList<>(catalogInventoryItemMap.keySet()), fofoOrder.getCreateTimestamp());
|
| 902 |
Map<Integer, LocalDateTime> purchaseBillingDateMap = new HashMap<>();
|
- |
|
| 903 |
for (Integer purchaseId : purchaseIds) {
|
- |
|
| 904 |
purchaseBillingDateMap.put(purchaseId, purchaseService.getBillingDateOfPurchase(purchaseId));
|
- |
|
| 905 |
}
|
- |
|
| 906 |
|
902 |
|
| 907 |
// Group items by (GRN billingDate -> catalogId -> items). Items with identical GRN billing date share a scheme lookup.
|
- |
|
| 908 |
Map<LocalDateTime, Map<Integer, List<InventoryItem>>> billingDateCatalogItemsMap = inventoryItems.stream()
|
- |
|
| 909 |
.collect(Collectors.groupingBy(
|
- |
|
| 910 |
x -> purchaseBillingDateMap.get(x.getPurchaseId()),
|
903 |
LOGGER.info("catalogSchemeSummaryMap - {}", catalogSchemeSummaryMap);
|
| 911 |
Collectors.groupingBy(x -> x.getItem().getCatalogItemId())));
|
- |
|
| 912 |
|
904 |
|
| 913 |
// N+1 fix: Batch fetch all SchemeInOut records for all inventoryItems at once
|
905 |
// N+1 fix: Batch fetch all SchemeInOut records for all inventoryItems at once
|
| 914 |
Set<Integer> allInventoryItemIds = inventoryItems.stream().map(InventoryItem::getId).collect(Collectors.toSet());
|
906 |
Set<Integer> allInventoryItemIds = inventoryItems.stream().map(InventoryItem::getId).collect(Collectors.toSet());
|
| 915 |
List<SchemeInOut> allSchemeInOuts = schemeInOutRepository.selectByInventoryItemIds(allInventoryItemIds);
|
907 |
List<SchemeInOut> allSchemeInOuts = schemeInOutRepository.selectByInventoryItemIds(allInventoryItemIds);
|
| 916 |
Map<Integer, List<SchemeInOut>> schemeInOutByInventoryItemId = allSchemeInOuts.stream()
|
908 |
Map<Integer, List<SchemeInOut>> schemeInOutByInventoryItemId = allSchemeInOuts.stream()
|
| 917 |
.collect(Collectors.groupingBy(SchemeInOut::getInventoryItemId));
|
909 |
.collect(Collectors.groupingBy(SchemeInOut::getInventoryItemId));
|
| 918 |
|
910 |
|
| 919 |
int count = 0;
|
911 |
int count = 0;
|
| 920 |
for (Map.Entry<LocalDateTime, Map<Integer, List<InventoryItem>>> billingDateEntry : billingDateCatalogItemsMap.entrySet()) {
|
- |
|
| 921 |
LocalDateTime grnBillingDate = billingDateEntry.getKey();
|
- |
|
| 922 |
Map<Integer, List<InventoryItem>> catalogInventoryItemMap = billingDateEntry.getValue();
|
- |
|
| 923 |
Map<CatalogSummaryModel, List<SchemeSummaryModel>> catalogSchemeSummaryMap = tagListingRepository.getModelSchemesByCatalogIdsAndType(retailerId,
|
- |
|
| 924 |
partnerType, new ArrayList<>(catalogInventoryItemMap.keySet()), grnBillingDate);
|
- |
|
| 925 |
|
- |
|
| 926 |
LOGGER.info("catalogSchemeSummaryMap (grnBillingDate={}) - {}", grnBillingDate, catalogSchemeSummaryMap);
|
- |
|
| 927 |
|
- |
|
| 928 |
for (Map.Entry<CatalogSummaryModel, List<SchemeSummaryModel>> catalogSummaryModelListEntry : catalogSchemeSummaryMap.entrySet()) {
|
912 |
for (Map.Entry<CatalogSummaryModel, List<SchemeSummaryModel>> catalogSummaryModelListEntry : catalogSchemeSummaryMap.entrySet()) {
|
| 929 |
CatalogSummaryModel catalogSummaryModel = catalogSummaryModelListEntry.getKey();
|
913 |
CatalogSummaryModel catalogSummaryModel = catalogSummaryModelListEntry.getKey();
|
| 930 |
List<SchemeSummaryModel> schemeSummaryModels = catalogSummaryModelListEntry.getValue().stream().filter(x -> x != null).collect(Collectors.toList());
|
914 |
List<SchemeSummaryModel> schemeSummaryModels = catalogSummaryModelListEntry.getValue().stream().filter(x -> x != null).collect(Collectors.toList());
|
| 931 |
|
915 |
|
| 932 |
schemeSummaryModels.stream().filter(x -> x.getSchemeType().getTransactionType().equals(StockTransactionType.OUT)).forEach(x -> x.setProcess(true));
|
916 |
schemeSummaryModels.stream().filter(x -> x.getSchemeType().getTransactionType().equals(StockTransactionType.OUT)).forEach(x -> x.setProcess(true));
|
| 933 |
if (schemeSummaryModels.stream().filter(x -> x.isProcess()).count() == 0) continue;
|
917 |
if (schemeSummaryModels.stream().filter(x -> x.isProcess()).count() == 0) continue;
|
| 934 |
|
918 |
|
| 935 |
// Create map once per catalog instead of per inventoryItem
|
919 |
// Create map once per catalog instead of per inventoryItem
|
| 936 |
Map<Integer, SchemeSummaryModel> schemeSummaryModelMap = schemeSummaryModels.stream().collect(Collectors.toMap(x -> x.getSchemeId(), x -> x));
|
920 |
Map<Integer, SchemeSummaryModel> schemeSummaryModelMap = schemeSummaryModels.stream().collect(Collectors.toMap(x -> x.getSchemeId(), x -> x));
|
| 937 |
|
921 |
|
| 938 |
List<InventoryItem> modelInventoryItems = catalogInventoryItemMap.get(catalogSummaryModel.getCatalogId());
|
922 |
List<InventoryItem> modelInventoryItems = catalogInventoryItemMap.get(catalogSummaryModel.getCatalogId());
|
| 939 |
for (InventoryItem inventoryItem : modelInventoryItems) {
|
923 |
for (InventoryItem inventoryItem : modelInventoryItems) {
|
| 940 |
// N+1 fix: Use pre-fetched schemeInOut map instead of querying per inventoryItem
|
924 |
// N+1 fix: Use pre-fetched schemeInOut map instead of querying per inventoryItem
|
| 941 |
List<SchemeInOut> sios = schemeInOutByInventoryItemId.getOrDefault(inventoryItem.getId(), Collections.emptyList());
|
925 |
List<SchemeInOut> sios = schemeInOutByInventoryItemId.getOrDefault(inventoryItem.getId(), Collections.emptyList());
|
| 942 |
|
926 |
|
| 943 |
List<Integer> creditedSchemeIds = sios.stream()
|
927 |
List<Integer> creditedSchemeIds = sios.stream()
|
| 944 |
.filter(x -> x.getStatus().equals(SchemePayoutStatus.CREDITED))
|
928 |
.filter(x -> x.getStatus().equals(SchemePayoutStatus.CREDITED))
|
| Line 976... |
Line 960... |
| 976 |
if (inventoryItemCashback > 0 || sioRejectedValue > 0) {
|
960 |
if (inventoryItemCashback > 0 || sioRejectedValue > 0) {
|
| 977 |
count++;
|
961 |
count++;
|
| 978 |
totalCashback += inventoryItemCashback - sioRejectedValue;
|
962 |
totalCashback += inventoryItemCashback - sioRejectedValue;
|
| 979 |
}
|
963 |
}
|
| 980 |
}
|
964 |
}
|
| 981 |
}
|
- |
|
| 982 |
}
|
965 |
}
|
| 983 |
|
966 |
|
| 984 |
if (count > 0) {
|
967 |
if (count > 0) {
|
| 985 |
walletService.addAmountToWallet(
|
968 |
walletService.addAmountToWallet(
|
| 986 |
retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT, "Sales margin for invoice number "
|
969 |
retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT, "Sales margin for invoice number "
|