Skip to content

Add DTO-based optimization for Category Day End Report#18384

Open
buddhika75 wants to merge 3 commits intodevelopmentfrom
18380-category-day-end-report-dto
Open

Add DTO-based optimization for Category Day End Report#18384
buddhika75 wants to merge 3 commits intodevelopmentfrom
18380-category-day-end-report-dto

Conversation

@buddhika75
Copy link
Member

@buddhika75 buddhika75 commented Feb 3, 2026

Summary

This PR resolves performance issues and timeouts in the By Category Day End Report by implementing DTO-based database queries instead of entity-based queries.

Closes #18380

Changes

  • Created CategoryDayEndReportDto class for optimized data transfer
  • Added createCashCategoryWithProDayDto() method in BookKeepingSummery controller with DTO-based query methods
  • Created new JSF page report_cash_category_with_pro_day_dto.xhtml for the optimized report
  • Added green button in navigation (report_own.xhtml) to access the new DTO-optimized report
  • Kept old entity-based methods intact for backward compatibility and comparison

Technical Details

The DTO approach uses aggregated JPQL queries that:

  • Fetch only necessary data instead of loading full entity objects
  • Significantly reduce memory usage and execution time
  • Prevent timeout issues with SUM, COUNT, GROUP BY operations

Testing

  • Old entity-based report remains available for comparison
  • New green button labeled "By Category Day End (DTO Optimized)" provides access to optimized version
  • Both versions can be run side-by-side to verify accuracy

Files Changed

  • src/main/java/com/divudi/core/data/dto/CategoryDayEndReportDto.java (new)
  • src/main/java/com/divudi/bean/report/BookKeepingSummery.java (modified)
  • src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml (new)
  • src/main/webapp/reportInstitution/report_own.xhtml (modified)

Related PRs

Summary by CodeRabbit

  • New Features
    • Added a DTO-optimized Category Day End report for improved performance.
    • New report view with date range selection, institution selector, and detailed category breakdowns (OPD cash/credit, pharmacy, wholesale, channel, inward, agents, collecting centres).
    • Report supports printing and Excel export, plus a quick-access button in the Book Keeping Summary menu.

This commit resolves performance issues and timeouts in the By Category
Day End Report by implementing DTO-based database queries instead of
entity-based queries.

Changes:
- Created CategoryDayEndReportDto class for optimized data transfer
- Added createCashCategoryWithProDayDto() method in BookKeepingSummery
  controller with DTO-based query methods
- Created new JSF page report_cash_category_with_pro_day_dto.xhtml
  for the optimized report
- Added green button in navigation (report_own.xhtml) to access the
  new DTO-optimized report
- Kept old entity-based methods intact for backward compatibility
  and comparison

The DTO approach uses aggregated JPQL queries that fetch only
necessary data, significantly reducing memory usage and execution
time compared to loading full entity objects.

Closes #18380

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 2026

Walkthrough

Adds a DTO-based Category Day End reporting path: new DTO class, new DTO-driven workflow and helpers in the BookKeepingSummery bean, a DTO-optimized JSF view, and a navigation button; preserves existing entity-based reporting for compatibility.

Changes

Cohort / File(s) Summary
DTO Class
src/main/java/com/divudi/core/data/dto/CategoryDayEndReportDto.java
New serializable DTO for category day-end rows with fields (categoryName, subCategoryName, cashValue, creditValue, totalValue, billType, paymentMethod, billCount) and specialized constructors.
Reporting Bean (DTO additions)
src/main/java/com/divudi/bean/report/BookKeepingSummery.java
Added createCashCategoryWithProDayDto() workflow, DTO list fields (opdCashDtoList, opdCreditDtoList, pharmacySalesDtoList, pharmacyWholeSalesDtoList, inwardCollectionsDtoList, channelBillsDtoList), total fields, helper fetch/calculation methods, and getters/setters. Entity-based sections retained.
JSF views and navigation
src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml, src/main/webapp/reportInstitution/report_own.xhtml
New DTO-optimized report view (date range, institution selector, process/print/Excel/export, tables per collection type, grand summary). Added a green "By Category Day End (DTO Optimized)" button to report_own.xhtml linking the new view.

Sequence Diagram(s)

sequenceDiagram
    participant User as User/UI
    participant Bean as BookKeepingSummery
    participant DB as Database/Query Layer
    participant View as JSF View

    User->>Bean: invoke createCashCategoryWithProDayDto()
    activate Bean
    Bean->>Bean: initialize DTO lists & validate dates
    Bean->>DB: fetchOpdCollectionsByPaymentMethodDto(...)
    DB-->>Bean: OPD DTO lists
    Bean->>DB: fetchPharmacyCollectionsDto(...)
    DB-->>Bean: Pharmacy DTO lists
    Bean->>DB: fetchChannelCollectionsDto(...)
    DB-->>Bean: Channel DTO lists
    Bean->>DB: fetchInwardCollectionsDto(...)
    DB-->>Bean: Inward DTO lists
    Bean->>Bean: calculateDtoTotal() per cohort & grandDtoTotal
    deactivate Bean
    User->>View: request/render DTO-optimized report
    View->>Bean: read DTO lists & totals
    View-->>User: render tables and grand summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (135 files):

⚔️ .github/workflows/branch_merge_validation.yml (content)
⚔️ .github/workflows/development_pr_validation.yml (content)
⚔️ .github/workflows/hims_qa3_ci_cd.yml (content)
⚔️ CLAUDE.md (content)
⚔️ developer_docs/API_Documentation_For_AI_Agents.md (content)
⚔️ developer_docs/github/wiki-publishing.md (content)
⚔️ developer_docs/ui/comprehensive-ui-guidelines.md (content)
⚔️ pom.xml (content)
⚔️ src/main/java/com/divudi/bean/common/ApplicationController.java (content)
⚔️ src/main/java/com/divudi/bean/common/BillBeanController.java (content)
⚔️ src/main/java/com/divudi/bean/common/BillPackageController.java (content)
⚔️ src/main/java/com/divudi/bean/common/CollectingCentrePaymentController.java (content)
⚔️ src/main/java/com/divudi/bean/common/DataAdministrationController.java (content)
⚔️ src/main/java/com/divudi/bean/common/DepartmentController.java (content)
⚔️ src/main/java/com/divudi/bean/common/EnumController.java (content)
⚔️ src/main/java/com/divudi/bean/common/InstitutionController.java (content)
⚔️ src/main/java/com/divudi/bean/common/ItemController.java (content)
⚔️ src/main/java/com/divudi/bean/common/OpdBatchBillCancellationController.java (content)
⚔️ src/main/java/com/divudi/bean/common/PatientController.java (content)
⚔️ src/main/java/com/divudi/bean/common/SearchController.java (content)
⚔️ src/main/java/com/divudi/bean/common/SessionController.java (content)
⚔️ src/main/java/com/divudi/bean/common/StaffPaymentBillController.java (content)
⚔️ src/main/java/com/divudi/bean/common/UserIconController.java (content)
⚔️ src/main/java/com/divudi/bean/common/UserSettingsController.java (content)
⚔️ src/main/java/com/divudi/bean/common/WebUserController.java (content)
⚔️ src/main/java/com/divudi/bean/common/WebUserRoleController.java (content)
⚔️ src/main/java/com/divudi/bean/inward/AdmissionController.java (content)
⚔️ src/main/java/com/divudi/bean/inward/BhtEditController.java (content)
⚔️ src/main/java/com/divudi/bean/inward/InwardBeanController.java (content)
⚔️ src/main/java/com/divudi/bean/inward/InwardProfessionalBillController.java (content)
⚔️ src/main/java/com/divudi/bean/inward/InwardReportController.java (content)
⚔️ src/main/java/com/divudi/bean/lab/LabAmpController.java (content)
⚔️ src/main/java/com/divudi/bean/opd/OpdReportController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/AmpController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/AmppController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/AtmController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/PharmacyBillSearch.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/PharmacyConfigController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/PharmacyController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/PharmacyIssueController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/PurchaseOrderRequestController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/ReportsStock.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/TransferRequestController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/VmpController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/VmppController.java (content)
⚔️ src/main/java/com/divudi/bean/pharmacy/VtmController.java (content)
⚔️ src/main/java/com/divudi/bean/report/BookKeepingSummery.java (content)
⚔️ src/main/java/com/divudi/bean/report/PharmacyReportController.java (content)
⚔️ src/main/java/com/divudi/bean/report/ReportController.java (content)
⚔️ src/main/java/com/divudi/bean/store/StoreAmpController.java (content)
⚔️ src/main/java/com/divudi/core/data/DepartmentType.java (content)
⚔️ src/main/java/com/divudi/core/data/Icon.java (content)
⚔️ src/main/java/com/divudi/core/data/IncomeBundle.java (content)
⚔️ src/main/java/com/divudi/core/data/PharmacyRow.java (content)
⚔️ src/main/java/com/divudi/core/data/dataStructure/SearchKeyword.java (content)
⚔️ src/main/java/com/divudi/core/data/dto/BillItemReportDTO.java (content)
⚔️ src/main/java/com/divudi/core/data/dto/ExpiryItemListDto.java (content)
⚔️ src/main/java/com/divudi/core/data/dto/ExpiryItemStockListDto.java (content)
⚔️ src/main/java/com/divudi/core/data/dto/StockDTO.java (content)
⚔️ src/main/java/com/divudi/core/data/reports/InventoryReports.java (content)
⚔️ src/main/java/com/divudi/core/entity/Bill.java (content)
⚔️ src/main/java/com/divudi/core/entity/BillFinanceDetails.java (content)
⚔️ src/main/java/com/divudi/core/entity/Department.java (content)
⚔️ src/main/java/com/divudi/core/entity/Item.java (content)
⚔️ src/main/java/com/divudi/core/entity/PatientEncounter.java (content)
⚔️ src/main/java/com/divudi/core/light/common/BillLight.java (content)
⚔️ src/main/java/com/divudi/service/AuditService.java (content)
⚔️ src/main/java/com/divudi/service/BillService.java (content)
⚔️ src/main/java/com/divudi/service/pharmacy/PharmacyBatchApiService.java (content)
⚔️ src/main/java/com/divudi/ws/common/ApplicationConfig.java (content)
⚔️ src/main/java/com/divudi/ws/pharmacy/PharmacyAdjustmentApi.java (content)
⚔️ src/main/java/com/divudi/ws/pharmacy/PharmacyBatchApi.java (content)
⚔️ src/main/resources/db/migrations/v2.1.10/migration.sql (content)
⚔️ src/main/resources/db/migrations/v2.1.15/migration.sql (content)
⚔️ src/main/webapp/about_software.xhtml (content)
⚔️ src/main/webapp/admin/institutions/department_management.xhtml (content)
⚔️ src/main/webapp/admin/institutions/department_management_all.xhtml (content)
⚔️ src/main/webapp/admin/institutions/departments.xhtml (content)
⚔️ src/main/webapp/admin/institutions/institution_management.xhtml (content)
⚔️ src/main/webapp/admin/institutions/institutions.xhtml (content)
⚔️ src/main/webapp/admin/institutions/site_management.xhtml (content)
⚔️ src/main/webapp/admin/users/user_list.xhtml (content)
⚔️ src/main/webapp/admin/users/user_roles.xhtml (content)
⚔️ src/main/webapp/collecting_centre/sent_payment_to_collecting_centre.xhtml (content)
⚔️ src/main/webapp/home.xhtml (content)
⚔️ src/main/webapp/inward/admission_profile.xhtml (content)
⚔️ src/main/webapp/inward/inward_admission.xhtml (content)
⚔️ src/main/webapp/inward/inward_bill_professional.xhtml (content)
⚔️ src/main/webapp/inward/inward_edit_bht.xhtml (content)
⚔️ src/main/webapp/mf.xhtml (content)
⚔️ src/main/webapp/opd/analytics/summary_reports/bill_item_report.xhtml (content)
⚔️ src/main/webapp/opd/analytics/summary_reports/bill_item_report_print.xhtml (content)
⚔️ src/main/webapp/opd/opd_bill_package.xhtml (content)
⚔️ src/main/webapp/opd/opd_package_batch_bill_cancel.xhtml (content)
⚔️ src/main/webapp/opd/opd_package_batch_bill_print.xhtml (content)
⚔️ src/main/webapp/opd/opd_package_bill_search.xhtml (content)
⚔️ src/main/webapp/opd/patient.xhtml (content)
⚔️ src/main/webapp/opd/patient_edit.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/miscellaneous_bill_report.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/miscellaneous_fee_report.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/miscellaneous_staff_fee.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/opd_search_professional_payment_done.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/opd_search_professional_payment_due.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/payment_bill_reprint.xhtml (content)
⚔️ src/main/webapp/opd/professional_payments/payment_staff_bill.xhtml (content)
⚔️ src/main/webapp/payments/pay_index.xhtml (content)
⚔️ src/main/webapp/pharmacy/admin/amp.xhtml (content)
⚔️ src/main/webapp/pharmacy/admin/ampp.xhtml (content)
⚔️ src/main/webapp/pharmacy/admin/index.xhtml (content)
⚔️ src/main/webapp/pharmacy/admin/vmp.xhtml (content)
⚔️ src/main/webapp/pharmacy/admin/vtm.xhtml (content)
⚔️ src/main/webapp/pharmacy/pharmacy_report_department_stock_by_batch_dto.xhtml (content)
⚔️ src/main/webapp/pharmacy/pharmacy_search_sale_bill.xhtml (content)
⚔️ src/main/webapp/reportInstitution/report_own.xhtml (content)
⚔️ src/main/webapp/reports/index.xhtml (content)
⚔️ src/main/webapp/reports/inpatientReports/ip_unsettled_invoices.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/closing_stock_report.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/consumption.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/expiry_item.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/good_in_transit.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/grn.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/slow_fast_none_movement.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/stock_ledger.xhtml (content)
⚔️ src/main/webapp/reports/inventoryReports/stock_transfer_report.xhtml (content)
⚔️ src/main/webapp/resources/bill/A4PaperCCRepayment.xhtml (content)
⚔️ src/main/webapp/resources/ezcomp/footer.xhtml (content)
⚔️ src/main/webapp/resources/ezcomp/menu.xhtml (content)
⚔️ src/main/webapp/resources/ezcomp/prints/bill_template_of_5x5_C1_package_BatchBill.xhtml (content)
⚔️ src/main/webapp/resources/ezcomp/prints/five_five_paper_coustom_1_package_single.xhtml (content)
⚔️ src/main/webapp/resources/ezcomp/reports/cc_statement.xhtml (content)
⚔️ src/main/webapp/resources/paymentMethod/patientDepositAsRefundPayment.xhtml (content)
⚔️ src/main/webapp/resources/paymentMethod/slip_multiple.xhtml (content)
⚔️ src/main/webapp/resources/pharmacy/grn_with_costing_custom_1.xhtml (content)
⚔️ src/main/webapp/resources/pharmacy/po_custom_3_letter.xhtml (content)
⚔️ src/main/webapp/resources/sql/bills.sql (content)

These conflicts must be resolved before merging into development.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a DTO-based optimization for the Category Day End Report to resolve performance issues.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #18380: implements DTO class, adds createCashCategoryWithProDayDto() method with aggregated JPQL queries, creates new JSF page, adds navigation button, and preserves existing entity-based methods.
Out of Scope Changes check ✅ Passed All changes are directly related to the PR objectives: new DTO class, controller method, JSF view, and navigation button addition are all within scope of implementing the DTO-based Category Day End Report optimization.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 18380-category-day-end-report-dto
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch 18380-category-day-end-report-dto
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Changed from findByJpql to findLightsByJpql with explicit casting
to List<CategoryDayEndReportDto> for all DTO fetch methods to resolve
type incompatibility errors.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/main/java/com/divudi/bean/report/BookKeepingSummery.java`:
- Around line 4531-4544: The JPQL in the jpql variable builds
CategoryDayEndReportDto by joining Bill b to b.billItems bi, which causes
SUM(b.netTotal) and COUNT(b.id) to be inflated; fix by aggregating at the bill
level or using distinct counts: either remove the LEFT JOIN b.billItems bi and
group by bi.item.category via a subquery on Bill (so SUM(b.netTotal) remains
correct), or keep the join but change the aggregates to SUM(b.netTotal) with
COUNT(DISTINCT b.id) (and/or SUM(DISTINCT b.netTotal) if needed) and ensure
GROUP BY uses c.name; update the query that constructs new
com.divudi.core.data.dto.CategoryDayEndReportDto accordingly.

In
`@src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml`:
- Line 69: Replace raw HTML heading tags with JSF output components: find each
occurrence of the <h3> heading text (e.g., the string "OPD Cash Collections
(Cash, Card, Cheque, Slip)" and the other headings referenced) and replace the
<h3> element with an h:outputText (or p:outputLabel) using the same heading text
as the value and, if needed, a styleClass for visual styling (for example:
h:outputText value="OPD Cash Collections (Cash, Card, Cheque, Slip)"
styleClass="section-heading"). Do this for the heading instances mentioned (the
one with the OPD label and the other headings at the noted locations) so XHTML
markup uses JSF components instead of raw <h3> tags.
- Around line 20-34: The labels are not associated with their inputs and
controls lack accessible tooltips; update each h:outputLabel to include
for="frmDate" and for="toDate" (matching the p:calendar ids) and add descriptive
title and aria-label attributes to the p:calendar components (ids frmDate and
toDate) and the p:autoComplete (value #{bookKeepingSummery.institution},
completeMethod #{institutionController.completeCompany}) so screen-readers and
tooltips can announce purpose; ensure forceSelection/requiredMessage remain and
that itemLabel/itemValue are preserved for p:autoComplete.
- Around line 249-260: The p:dataTable with id "summaryTable" is missing
required attributes value and var so it won't render; either bind it to a
one-element list or DTO in the backing bean (e.g., provide List or array on the
bean used by report, and set value="#{bookKeepingSummery.someSummaryList}"
var="summary" and then reference summary.grandDtoTotal) or replace the table
with a non-iterative component such as <p:panelGrid> or plain <h:panelGroup> and
render the value via #{bookKeepingSummery.grandDtoTotal}; also remove or update
any exporter targets that reference "summaryTable" to point to the new component
or include the list-based table.
🧹 Nitpick comments (1)
src/main/java/com/divudi/core/data/dto/CategoryDayEndReportDto.java (1)

13-115: Use Double wrappers for monetary fields in this DTO.

Primitives prevent representing missing aggregates and can throw on unboxing when JPQL returns nulls. Switching to Double preserves null semantics and avoids NPEs.

♻️ Suggested change
-    private double cashValue;
-    private double creditValue;
-    private double totalValue;
+    private Double cashValue;
+    private Double creditValue;
+    private Double totalValue;
@@
-    public CategoryDayEndReportDto(String categoryName, String subCategoryName,
-                                   double cashValue, double creditValue, long billCount) {
+    public CategoryDayEndReportDto(String categoryName, String subCategoryName,
+                                   Double cashValue, Double creditValue, long billCount) {
@@
-        this.totalValue = cashValue + creditValue;
+        this.totalValue = (cashValue == null && creditValue == null)
+                ? null
+                : (cashValue == null ? 0d : cashValue) + (creditValue == null ? 0d : creditValue);

Based on learnings: For DTO/Light classes like BillLight, use Double wrapper types instead of primitive double for monetary fields (ccTotal, hospitalTotal, etc.) to preserve semantic information about missing/undefined values.

Comment on lines 20 to 34
<h:panelGrid columns="2" class="my-2" >
<h:outputLabel value="From Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100" id="frmDate" value="#{bookKeepingSummery.fromDate}" pattern="dd MM yyyy HH:mm:ss" >
</p:calendar>

<h:outputLabel value="To Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100 my-1" id="toDate" value="#{bookKeepingSummery.toDate}" pattern="dd MM yyyy HH:mm:ss" >
</p:calendar>

<h:outputLabel value="Select Institution"/>

<p:autoComplete class="w-100 mx-4" inputStyleClass="w-100" completeMethod="#{institutionController.completeCompany}" required="true"
forceSelection="true"
requiredMessage="Please Select Institution" value="#{bookKeepingSummery.institution}"
var="pta" itemLabel="#{pta.name}" itemValue="#{pta}" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Associate labels with inputs and add tooltips for accessibility.

h:outputLabel should reference the input IDs, and interactive controls should expose titles/aria-labels.

🧭 Suggested fix
-    <h:outputLabel value="From Date"/>
+    <h:outputLabel for="frmDate" value="From Date"/>
@@
-    <p:calendar class="w-100 mx-4" inputStyleClass="w-100" id="frmDate" value="#{bookKeepingSummery.fromDate}" pattern="dd MM yyyy HH:mm:ss" >
+    <p:calendar class="w-100 mx-4" inputStyleClass="w-100" id="frmDate" value="#{bookKeepingSummery.fromDate}" pattern="dd MM yyyy HH:mm:ss"
+                ariaLabel="From Date">

As per coding guidelines: Implement accessibility with proper tooltips and labeling.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<h:panelGrid columns="2" class="my-2" >
<h:outputLabel value="From Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100" id="frmDate" value="#{bookKeepingSummery.fromDate}" pattern="dd MM yyyy HH:mm:ss" >
</p:calendar>
<h:outputLabel value="To Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100 my-1" id="toDate" value="#{bookKeepingSummery.toDate}" pattern="dd MM yyyy HH:mm:ss" >
</p:calendar>
<h:outputLabel value="Select Institution"/>
<p:autoComplete class="w-100 mx-4" inputStyleClass="w-100" completeMethod="#{institutionController.completeCompany}" required="true"
forceSelection="true"
requiredMessage="Please Select Institution" value="#{bookKeepingSummery.institution}"
var="pta" itemLabel="#{pta.name}" itemValue="#{pta}" />
<h:panelGrid columns="2" class="my-2" >
<h:outputLabel for="frmDate" value="From Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100" id="frmDate" value="#{bookKeepingSummery.fromDate}" pattern="dd MM yyyy HH:mm:ss"
ariaLabel="From Date">
</p:calendar>
<h:outputLabel value="To Date"/>
<p:calendar class="w-100 mx-4" inputStyleClass="w-100 my-1" id="toDate" value="#{bookKeepingSummery.toDate}" pattern="dd MM yyyy HH:mm:ss" >
</p:calendar>
<h:outputLabel value="Select Institution"/>
<p:autoComplete class="w-100 mx-4" inputStyleClass="w-100" completeMethod="#{institutionController.completeCompany}" required="true"
forceSelection="true"
requiredMessage="Please Select Institution" value="#{bookKeepingSummery.institution}"
var="pta" itemLabel="#{pta.name}" itemValue="#{pta}" />
🤖 Prompt for AI Agents
In
`@src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml`
around lines 20 - 34, The labels are not associated with their inputs and
controls lack accessible tooltips; update each h:outputLabel to include
for="frmDate" and for="toDate" (matching the p:calendar ids) and add descriptive
title and aria-label attributes to the p:calendar components (ids frmDate and
toDate) and the p:autoComplete (value #{bookKeepingSummery.institution},
completeMethod #{institutionController.completeCompany}) so screen-readers and
tooltips can announce purpose; ensure forceSelection/requiredMessage remain and
that itemLabel/itemValue are preserved for p:autoComplete.

- Fix channel query overcounting: use SUM(bi.netValue) and COUNT(DISTINCT b.id)
  instead of SUM(b.netTotal) and COUNT(b.id) which were inflated by bill items join
- Replace empty p:dataTable (summaryTable) with p:panelGrid since it has no
  value/var and won't render; remove from dataExporter targets
- Replace raw <h3> HTML tags with h:outputText JSF components for consistency
- Add for attributes to h:outputLabel for form accessibility

Closes #18380

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/main/java/com/divudi/bean/report/BookKeepingSummery.java`:
- Around line 4454-4577: The DTO JPQL queries in
fetchOpdCollectionsByPaymentMethodDto, fetchPharmacyCollectionsDto,
fetchChannelCollectionsDto, and fetchInwardCollectionsDto omit filtering retired
BillItem rows, causing inflated sums/counts; update each JPQL string to include
"AND bi.retired = false" in the WHERE clause (alongside the existing b.retired =
false) so retired bill items are excluded, then run tests/compare with legacy
report results to verify counts match.

In
`@src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml`:
- Around line 39-55: The report action buttons (p:commandButton invoking
bookKeepingSummery.createCashCategoryWithProDayDto and the Print/Excel/Compare
buttons) lack UI privilege guards; wrap each actionable button with a rendered
(or disabled) attribute that calls webUserController.hasPrivilege(...) using the
same privilege keys used by other report pages (e.g., the pattern "REPORT_*" or
the specific privilege used for the comparable report page) so only authorized
users see/activate them; apply this to the Process button (action
bookKeepingSummery.createCashCategoryWithProDayDto), the Print (p:printer
target="panelPrint"), Excel (p:dataExporter target=...), and Compare
(action="report_cash_category_with_pro_day") controls, mirroring the existing
pages' use of webUserController.hasPrivilege() for rendered/disabled.

Comment on lines +4454 to +4577
private List<CategoryDayEndReportDto> fetchOpdCollectionsByPaymentMethodDto(List<PaymentMethod> paymentMethods) {
List<CategoryDayEndReportDto> dtoList = new ArrayList<>();

if (institution == null || fromDate == null || toDate == null) {
return dtoList;
}

String jpql = "SELECT NEW com.divudi.core.data.dto.CategoryDayEndReportDto("
+ "COALESCE(c.name, 'No Category'), "
+ "SUM(bi.netValue), "
+ "COUNT(DISTINCT b.id)) "
+ "FROM BillItem bi JOIN bi.bill b "
+ "LEFT JOIN bi.item.category c "
+ "WHERE b.billType IN :billTypes "
+ "AND b.institution = :ins "
+ "AND b.createdAt BETWEEN :fd AND :td "
+ "AND b.paymentMethod IN :pm "
+ "AND b.retired = false "
+ "GROUP BY c.name "
+ "ORDER BY c.name";

Map<String, Object> params = new HashMap<>();
params.put("billTypes", Arrays.asList(BillType.OpdBill));
params.put("ins", institution);
params.put("fd", fromDate);
params.put("td", toDate);
params.put("pm", paymentMethods);

dtoList = (List<CategoryDayEndReportDto>) billFacade.findLightsByJpql(jpql, params, TemporalType.TIMESTAMP);

return dtoList == null ? new ArrayList<>() : dtoList;
}

/**
* Fetch pharmacy collections grouped by category using DTO
*/
private List<CategoryDayEndReportDto> fetchPharmacyCollectionsDto(BillType billType) {
List<CategoryDayEndReportDto> dtoList = new ArrayList<>();

if (institution == null || fromDate == null || toDate == null) {
return dtoList;
}

String jpql = "SELECT NEW com.divudi.core.data.dto.CategoryDayEndReportDto("
+ "COALESCE(c.name, 'No Category'), "
+ "SUM(bi.netValue), "
+ "COUNT(DISTINCT b.id)) "
+ "FROM BillItem bi JOIN bi.bill b "
+ "LEFT JOIN bi.item.category c "
+ "WHERE b.billType = :bt "
+ "AND b.institution = :ins "
+ "AND b.createdAt BETWEEN :fd AND :td "
+ "AND b.retired = false "
+ "GROUP BY c.name "
+ "ORDER BY c.name";

Map<String, Object> params = new HashMap<>();
params.put("bt", billType);
params.put("ins", institution);
params.put("fd", fromDate);
params.put("td", toDate);

dtoList = (List<CategoryDayEndReportDto>) billFacade.findLightsByJpql(jpql, params, TemporalType.TIMESTAMP);

return dtoList == null ? new ArrayList<>() : dtoList;
}

/**
* Fetch channel collections grouped by category using DTO
*/
private List<CategoryDayEndReportDto> fetchChannelCollectionsDto() {
List<CategoryDayEndReportDto> dtoList = new ArrayList<>();

if (institution == null || fromDate == null || toDate == null) {
return dtoList;
}

String jpql = "SELECT NEW com.divudi.core.data.dto.CategoryDayEndReportDto("
+ "COALESCE(c.name, 'Channel'), "
+ "SUM(bi.netValue), "
+ "COUNT(DISTINCT b.id)) "
+ "FROM BillItem bi JOIN bi.bill b "
+ "LEFT JOIN bi.item.category c "
+ "WHERE b.billType IN :billTypes "
+ "AND b.institution = :ins "
+ "AND b.createdAt BETWEEN :fd AND :td "
+ "AND b.retired = false "
+ "GROUP BY c.name "
+ "ORDER BY c.name";

Map<String, Object> params = new HashMap<>();
params.put("billTypes", Arrays.asList(BillType.ChannelCash, BillType.ChannelAgent, BillType.ChannelPaid));
params.put("ins", institution);
params.put("fd", fromDate);
params.put("td", toDate);

dtoList = (List<CategoryDayEndReportDto>) billFacade.findLightsByJpql(jpql, params, TemporalType.TIMESTAMP);

return dtoList == null ? new ArrayList<>() : dtoList;
}

/**
* Fetch inward collections grouped by category using DTO
*/
private List<CategoryDayEndReportDto> fetchInwardCollectionsDto() {
List<CategoryDayEndReportDto> dtoList = new ArrayList<>();

if (institution == null || fromDate == null || toDate == null) {
return dtoList;
}

String jpql = "SELECT NEW com.divudi.core.data.dto.CategoryDayEndReportDto("
+ "COALESCE(c.name, 'Inward'), "
+ "SUM(bi.netValue), "
+ "COUNT(DISTINCT b.id)) "
+ "FROM BillItem bi JOIN bi.bill b "
+ "LEFT JOIN bi.item.category c "
+ "WHERE b.billType IN :billTypes "
+ "AND b.institution = :ins "
+ "AND b.createdAt BETWEEN :fd AND :td "
+ "AND b.retired = false "
+ "GROUP BY c.name "
+ "ORDER BY c.name";

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Exclude retired BillItems in DTO aggregations.
The DTO queries filter b.retired but not bi.retired, so retired bill items can still be counted. This can inflate totals and bill counts versus the legacy report queries that exclude retired items. Add AND bi.retired = false to all DTO JPQL strings (OPD, pharmacy, channel, inward).

🔧 Example fix (apply to all DTO JPQL builders)
-                + "AND b.retired = false "
+                + "AND b.retired = false "
+                + "AND bi.retired = false "
🤖 Prompt for AI Agents
In `@src/main/java/com/divudi/bean/report/BookKeepingSummery.java` around lines
4454 - 4577, The DTO JPQL queries in fetchOpdCollectionsByPaymentMethodDto,
fetchPharmacyCollectionsDto, fetchChannelCollectionsDto, and
fetchInwardCollectionsDto omit filtering retired BillItem rows, causing inflated
sums/counts; update each JPQL string to include "AND bi.retired = false" in the
WHERE clause (alongside the existing b.retired = false) so retired bill items
are excluded, then run tests/compare with legacy report results to verify counts
match.

Comment on lines +39 to +55
<p:commandButton value="Process" ajax="false" class="ui-button-warning" icon="fas fa-cogs"
action="#{bookKeepingSummery.createCashCategoryWithProDayDto}"/>
<p:commandButton ajax="false" value="Print" class="ui-button-info mx-2" icon="fas fa-print" >
<p:printer target="panelPrint" />
</p:commandButton>
<p:commandButton value="Excel" ajax="false" class="ui-button-success" icon="fas fa-file-excel" >
<p:dataExporter type="xlsx" target="opdCashTable,
opdCreditTable,
pharmacySalesTable,
pharmacyWholeSalesTable,
channelTable,
inwardTable"
fileName="Book_Keeping_Summery_with_pro_day_dto"
/>
</p:commandButton>
<p:commandButton value="Compare with Old Version" ajax="false" class="ui-button-secondary" icon="fas fa-balance-scale"
action="report_cash_category_with_pro_day"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Gate report actions with privilege checks.
The new report actions are exposed without webUserController.hasPrivilege() checks. Please align with existing report pages and add privilege-based rendered/disabled guards for these actions.

As per coding guidelines, Use webUserController.hasPrivilege() for UI privilege integration.

🤖 Prompt for AI Agents
In
`@src/main/webapp/reportInstitution/report_cash_category_with_pro_day_dto.xhtml`
around lines 39 - 55, The report action buttons (p:commandButton invoking
bookKeepingSummery.createCashCategoryWithProDayDto and the Print/Excel/Compare
buttons) lack UI privilege guards; wrap each actionable button with a rendered
(or disabled) attribute that calls webUserController.hasPrivilege(...) using the
same privilege keys used by other report pages (e.g., the pattern "REPORT_*" or
the specific privilege used for the comparable report page) so only authorized
users see/activate them; apply this to the Process button (action
bookKeepingSummery.createCashCategoryWithProDayDto), the Print (p:printer
target="panelPrint"), Excel (p:dataExporter target=...), and Compare
(action="report_cash_category_with_pro_day") controls, mirroring the existing
pages' use of webUserController.hasPrivilege() for rendered/disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

By Category Day End Report is not working

1 participant