Skip to content

handled null cheks in pt-calculator - #385

Open
nitish-egov wants to merge 3 commits into
masterfrom
CCSD-676
Open

handled null cheks in pt-calculator#385
nitish-egov wants to merge 3 commits into
masterfrom
CCSD-676

Conversation

@nitish-egov

@nitish-egov nitish-egov commented Aug 21, 2025

Copy link
Copy Markdown

Added multiarch changes

Summary by CodeRabbit

  • Bug Fixes

    • Prevents errors during property tax estimation when some property details are missing.
    • Improves slab selection to handle incomplete data and edge cases more predictably, including area and multi-floor cases.
    • Delivers more consistent results for area-based evaluations.
  • Refactor

    • Hardens estimation logic with safer defaults and null handling for more reliable calculations.
    • Improves diagnostic logging to aid troubleshooting.

@coderabbitai

coderabbitai Bot commented Aug 21, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Internal updates to EstimationService’s slab filtering logic add null-safety, defensive defaults, a null-safe string comparator, revised matching rules for area, property type/subtype, ownership, and updated logging; no public method signatures changed.

Changes

Cohort / File(s) Summary of changes
Slab filtering null-safety and matching logic
property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java
Added null-safe defaults for detail and slab fields; derived plot size from land/build-up area; computed dtlIsMultiFloored defensively; introduced safeEqualsIgnoreCase(String,String); adjusted matching rules for area type, property type/subtype, ownership, and plot-range (special-case for 0.0); aggregated finalResult and added conditional debug logging; no public API changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Caller
  participant ES as EstimationService
  participant D as Property Details
  participant S as Slab Config

  C->>ES: getSlabsFiltered(details)
  ES->>D: Read landArea/buildUpArea, types, ownership, floors
  Note right of ES: Apply null-safe defaults and safeEqualsIgnoreCase<br/>derive dtlAreaType, dtlIsMultiFloored
  ES->>S: Iterate slabs
  loop For each slab
    ES->>S: Read slab fields with null-tolerant defaults
    alt Area type match
      ES-->ES: dtlAreaType empty => match<br/>else match if slabAreaType equals dtlAreaType or "ALL"
    else No match
      ES-->>ES: Skip slab
    end
    alt Property/ownership match
      ES-->ES: Match on type/subtype/ownership or "ALL"/empty detail
    else No match
      ES-->>ES: Skip slab
    end
    ES-->ES: Check plot range (special-case when plotSize == 0.0) and multi-floor flag
    ES-->>ES: finalResult = all matches && plotMatch
    opt Logging
      ES->>ES: Debug log slab when finalResult true or slab id short
    end
    ES-->>ES: Collect matching slab if finalResult
  end
  ES-->>C: Return filtered slabs (with post-filter log)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I hop through slabs with careful cheer,
Guarding nulls both far and near.
If fields are blank, I won’t despair—
I widen paths with bunny flair.
With ALL as friend and floors in view,
I sift the rules—then hop on through. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch CCSD-676

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b3df56a and 55951c0.

📒 Files selected for processing (1)
  • property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java (1 hunks)
🔇 Additional comments (5)
property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java (5)

561-570: LGTM: Null-safe extraction of area type.

The defensive checks around Address → Locality → Area with a safe default ("") are correct and prevent NPEs. This aligns with the downstream wildcard logic.


571-573: LGTM: Robust multi-floor flag computation.

Calculates a definitive boolean for dtlIsMultiFloored with null-guard on noOfFloors; concise and safe.


589-593: LGTM: Area matching honors wildcard and “ALL” sentinel.

The logic correctly considers empty detail as wildcard and recognizes slab “ALL”. This prevents false negatives when area is unavailable.


597-611: LGTM: Wildcard semantics for subtype/ownership are consistent and null-safe.

Empty detail values act as wildcard; slab “ALL” is honored. This mirrors area-type handling and reduces NPE risk during lookups.


555-560: Ensure wildcard matching for propertyType in EstimationService

Currently, in EstimationService (around lines 555–560), dtlPtType is defaulted to "" when detail.getPropertyType() is null, but the subsequent matcher

boolean isPtTypeMatching = !dtlPtType.isEmpty() 
        && slabPropertyType.equalsIgnoreCase(dtlPtType);

will reject all slabs whenever dtlPtType is empty—contrary to the null-tolerant, wildcard behavior applied to other fields.

Please verify and update as follows:

• In EstimationService.java (≈ lines 555–560) replace the existing matcher

-   boolean isPtTypeMatching = !dtlPtType.isEmpty() 
-           && slabPropertyType.equalsIgnoreCase(dtlPtType);
+   boolean isPtTypeMatching = dtlPtType.isEmpty()
+           || slabPropertyType.equalsIgnoreCase(dtlPtType)
+           || slabPropertyType.equalsIgnoreCase(BillingSlabConstants.ALL_PLACEHOLDER_BILLING_SLAB);

• Confirm that the matchers for dtlPtSubType, dtlOwnerShipCat, and dtlSubOwnerShipCat already handle empty detail fields and the "ALL" sentinel consistently (as seen in BillingSlabUtils.java).

• Add focused unit tests to cover:
– Detail’s propertyType null/empty → should not filter out slabs.
– Slab’s propertyType = "ALL" → matches any detail value.

Would you like me to draft these unit tests?

@egovernments egovernments deleted a comment from coderabbitai Bot Aug 21, 2025
@egovernments egovernments deleted a comment from coderabbitai Bot Aug 21, 2025
vinothrallapalli-eGov and others added 2 commits August 21, 2025 15:08
# Conflicts:
#	property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java (2)

621-627: Fix boundary condition: exclude-equal on lower bound causes slab gaps.

Using slabAreaFrom < plotSize excludes properties exactly at fromPlotSize (except the 0.0 special case), creating holes. Use inclusive lower bound consistently. Also, if plot size is unknown, don’t restrict by area at all.

-			boolean isPlotMatching = false;
-
-			if (plotSize == 0.0)
-				isPlotMatching = slabAreaFrom <= plotSize && slabAreaTo >= plotSize;
-			else
-				isPlotMatching = slabAreaFrom < plotSize && slabAreaTo >= plotSize;
+			boolean isPlotMatching;
+			if (!hasPlotSize) {
+				// No plot size provided; don't restrict by area
+				isPlotMatching = true;
+			} else {
+				// Inclusive lower bound to avoid gaps at exact 'from' values
+				isPlotMatching = slabAreaFrom <= plotSize && slabAreaTo >= plotSize;
+			}

551-649: Functional coverage: add tests for boundary and null-safety scenarios in slab filtering.

Please add unit tests that pin the intended behavior:

  • plotSize unknown (both landArea and buildUpArea null) should not filter by area.
  • plotSize exactly equal to fromPlotSize and toPlotSize should match.
  • slab.isPropertyMultiFloored null should match both single- and multi-floor properties (subject to domain confirmation).
  • Case and whitespace differences in propertyType/subType/ownership fields should not affect matching.

I can scaffold a focused test class for getSlabsFiltered with mocked BillingSlabService returning representative slabs (ALL sentinel, null multi-floor, boundary ranges). Want me to draft it?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 55951c0 and 6886975.

📒 Files selected for processing (1)
  • property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java (3 hunks)
🔇 Additional comments (1)
property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java (1)

584-596: Treat null isPropertyMultiFloored as “no restriction” rather than false

The current code defaults a null MDMS value to false, inadvertently excluding slabs that were meant to apply to both single- and multi-floor properties. To align with the “ALL” semantics used elsewhere, a null flag should not constrain the match.

Please confirm with the product/domain team whether a null value for slab.isPropertyMultiFloored in MDMS is intended to mean “apply to all properties,” so we can safely adopt this change.

Key locations:

  • File: property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java
  • Lines: 584–596

Suggested diff:

-   Boolean slabMultiFloored = slab.getIsPropertyMultiFloored() != null ? slab.getIsPropertyMultiFloored() : false;
+   // Treat null as “no restriction” (apply to both single- and multi-floor)
+   Boolean slabMultiFloored = slab.getIsPropertyMultiFloored();
@@
-   boolean isPropertyMultiFloored = slabMultiFloored.equals(dtlIsMultiFloored);
+   // If MDMS flag is null, allow both; otherwise, require exact match
+   boolean isPropertyMultiFloored = (slabMultiFloored == null) 
+       || (slabMultiFloored.booleanValue() == dtlIsMultiFloored);

[tag: verify_review_comment]

Comment on lines +1246 to +1260
/**
* Safe null-aware case-insensitive string comparison
* @param str1 First string to compare (can be null)
* @param str2 Second string to compare (can be null)
* @return true if both strings are equal (ignoring case), false otherwise
*/
private boolean safeEqualsIgnoreCase(String str1, String str2) {
if (str1 == null && str2 == null) {
return true;
}
if (str1 == null || str2 == null) {
return false;
}
return str1.equalsIgnoreCase(str2);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove custom safeEqualsIgnoreCase; use Apache StringUtils.equalsIgnoreCase instead.

You already depend on commons-lang3; avoid duplicating well-tested utilities and reduce surface area.

-	/**
-	 * Safe null-aware case-insensitive string comparison
-	 * @param str1 First string to compare (can be null)
-	 * @param str2 Second string to compare (can be null)
-	 * @return true if both strings are equal (ignoring case), false otherwise
-	 */
-	private boolean safeEqualsIgnoreCase(String str1, String str2) {
-		if (str1 == null && str2 == null) {
-			return true;
-		}
-		if (str1 == null || str2 == null) {
-			return false;
-		}
-		return str1.equalsIgnoreCase(str2);
-	}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
property-tax/pt-calculator-v2/src/main/java/org/egov/pt/calculator/service/EstimationService.java
around lines 1246 to 1260, remove the custom safeEqualsIgnoreCase method and
replace all its call sites with
org.apache.commons.lang3.StringUtils.equalsIgnoreCase(...) from commons-lang3;
add or ensure the import org.apache.commons.lang3.StringUtils; remove the
private method implementation entirely to avoid duplication and rely on the
tested library utility.

@egovernments egovernments deleted a comment from coderabbitai Bot Aug 21, 2025
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.

2 participants