From 0cb2208820264497a3e03f0b1f76146749ffb68c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 17:46:48 +0000 Subject: [PATCH] Refactor pharmacyCancelBillItemsReduceStock to use batch operations Replaces the N+1 `create` and `edit` calls inside the iteration over `BillItem` with `batchCreate` and `batchEdit` list operations. Also refactors `cancelBillFee` and the `BillFee` select query to prevent N+1 queries. Co-authored-by: manupawickramasinghe <73810867+manupawickramasinghe@users.noreply.github.com> --- .../bean/pharmacy/PharmacyBillSearch.java | 81 ++++++++++++++----- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/divudi/bean/pharmacy/PharmacyBillSearch.java b/src/main/java/com/divudi/bean/pharmacy/PharmacyBillSearch.java index 0c91dcf430..244025ac11 100644 --- a/src/main/java/com/divudi/bean/pharmacy/PharmacyBillSearch.java +++ b/src/main/java/com/divudi/bean/pharmacy/PharmacyBillSearch.java @@ -2085,7 +2085,12 @@ private void pharmacyCancelBillItemsReduceStock(CancelledBill can) { } private void pharmacyCancelBillItemsReduceStock(CancelledBill cancellationBill, Payment p) { + List newItems = new ArrayList<>(); + List origItems = new ArrayList<>(); + List origItemIds = new ArrayList<>(); + for (BillItem originalBillItem : getBill().getBillItems()) { + origItemIds.add(originalBillItem.getId()); BillItem newlyCreatedBillItemForCancelBill = new BillItem(); newlyCreatedBillItemForCancelBill.setBill(cancellationBill); newlyCreatedBillItemForCancelBill.copy(originalBillItem); @@ -2116,41 +2121,68 @@ private void pharmacyCancelBillItemsReduceStock(CancelledBill cancellationBill, ph.setCostValue(-Math.abs(totalQtyInUnits * costRatePerUnit)); ph.setRetailValue(-Math.abs(totalQtyInUnits * retailRatePerUnit)); -// getPharmaceuticalBillItemFacade().create(ph); newlyCreatedBillItemForCancelBill.setPharmaceuticalBillItem(ph); - ph.setBillItem(newlyCreatedBillItemForCancelBill); -// getPharmaceuticalBillItemFacade().edit(ph); - if (newlyCreatedBillItemForCancelBill.getId() == null) { - getBillItemFacade().create(newlyCreatedBillItemForCancelBill); - } else { - getBillItemFacade().edit(newlyCreatedBillItemForCancelBill); + newItems.add(newlyCreatedBillItemForCancelBill); + origItems.add(originalBillItem); + cancellationBill.getBillItems().add(newlyCreatedBillItemForCancelBill); + } + + if (!newItems.isEmpty()) { + getBillItemFacade().batchCreate(newItems); + } + + Map> origItemToFeesMap = new HashMap<>(); + if (!origItemIds.isEmpty()) { + String sql = "Select bf From BillFee bf where bf.retired=false and bf.billItem.id IN :ids"; + Map params = new HashMap<>(); + params.put("ids", origItemIds); + List allFees = getBillFeeFacade().findByJpql(sql, params); + for (BillFee fee : allFees) { + if (fee.getBillItem() != null) { + Long id = fee.getBillItem().getId(); + List feesForId = origItemToFeesMap.get(id); + if (feesForId == null) { + feesForId = new ArrayList<>(); + origItemToFeesMap.put(id, feesForId); + } + feesForId.add(fee); + } } + } + + List itemsToEdit = new ArrayList<>(); + List phItemsToEdit = new ArrayList<>(); + + for (int i = 0; i < newItems.size(); i++) { + BillItem newlyCreatedBillItemForCancelBill = newItems.get(i); + BillItem originalBillItem = origItems.get(i); + PharmaceuticalBillItem ph = newlyCreatedBillItemForCancelBill.getPharmaceuticalBillItem(); - // updateRemainingQty(nB); - // b.setPharmaceuticalBillItem(b.getReferanceBillItem().getPharmaceuticalBillItem()); double qty = ph.getFreeQtyInUnit() + ph.getQtyInUnit(); - //System.err.println("Updating QTY " + qty); boolean returnFlag = getPharmacyBean().deductFromStock(ph.getStock(), Math.abs(qty), ph, getSessionController().getDepartment()); if (!returnFlag) { newlyCreatedBillItemForCancelBill.setTmpQty(0); - getPharmaceuticalBillItemFacade().edit(newlyCreatedBillItemForCancelBill.getPharmaceuticalBillItem()); + phItemsToEdit.add(ph); + } + + List tmp = origItemToFeesMap.get(originalBillItem.getId()); + if (tmp == null) { + tmp = new ArrayList<>(); } - //get billfees from using cancel billItem - String sql = "Select bf From BillFee bf where bf.retired=false and bf.billItem.id=" + originalBillItem.getId(); - List tmp = getBillFeeFacade().findByJpql(sql); cancelBillFee(cancellationBill, newlyCreatedBillItemForCancelBill, tmp); - //create BillFeePayments For cancel - sql = "Select bf From BillFee bf where bf.retired=false and bf.billItem.id=" + newlyCreatedBillItemForCancelBill.getId(); - List tmpC = getBillFeeFacade().findByJpql(sql); -// calculateBillfeePaymentsForCancelRefundBill(tmpC, p); - // - getBillItemFacede().edit(newlyCreatedBillItemForCancelBill); + itemsToEdit.add(newlyCreatedBillItemForCancelBill); + } - cancellationBill.getBillItems().add(newlyCreatedBillItemForCancelBill); + if (!phItemsToEdit.isEmpty()) { + getPharmaceuticalBillItemFacade().batchEdit(phItemsToEdit); + } + + if (!itemsToEdit.isEmpty()) { + getBillItemFacede().batchEdit(itemsToEdit); } getBillFacade().edit(cancellationBill); @@ -2363,6 +2395,8 @@ private void pharmacyCancelBillItems(CancelledBill newlyCreatedCancellingBill, L } private void cancelBillFee(Bill can, BillItem bt, List tmp) { + if (tmp == null || tmp.isEmpty()) return; + List toEdit = new ArrayList<>(); for (BillFee nB : tmp) { BillFee bf = new BillFee(); bf.setFee(nB.getFee()); @@ -2381,7 +2415,10 @@ private void cancelBillFee(Bill can, BillItem bt, List tmp) { bf.setCreatedAt(new Date()); bf.setCreater(getSessionController().getLoggedUser()); - getBillFeeFacade().edit(bf); + toEdit.add(bf); + } + if (!toEdit.isEmpty()) { + getBillFeeFacade().batchEdit(toEdit); } }