Skip to content

(feat): Payments should be associated with a cashier#155

Open
NethmiRodrigo wants to merge 10 commits intomainfrom
feat/payment-cashier-association
Open

(feat): Payments should be associated with a cashier#155
NethmiRodrigo wants to merge 10 commits intomainfrom
feat/payment-cashier-association

Conversation

@NethmiRodrigo
Copy link
Contributor

This PR adds back the functionality that was introduced in this PR, that we had to revert because it was merged in during the release code freeze. This basically does the same except for getting the cashier from the authenticated user, while previously it needed to be sent from the client.

  • Adds a cashier field to the Payment model (nullable for backwards compatibility with legacy payments)
  • Auto-sets the cashier from the authenticated user at the REST layer — both in PaymentResource
    (sub-resource endpoint) and BillResource (embedded payments on bill create/update)
  • Validates that any new payment being saved has a cashier assigned; existing payments without a cashier
    (legacy data) are allowed
  • Exposes cashier in the payment REST representation

NethmiRodrigo and others added 6 commits March 20, 2026 22:10
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ate auto-flush

Swapped order so validateNewPaymentsHaveCashier runs before
validateLineItemsNotModified. The latter triggers a DB query that causes
Hibernate to auto-flush transient payments, assigning them IDs and making
the id==null check ineffective.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov-commenter
Copy link

codecov-commenter commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 48.14815% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.00%. Comparing base (1778231) to head (bfd4f72).

Files with missing lines Patch % Lines
...ule/billing/web/rest/resource/PaymentResource.java 41.66% 7 Missing ⚠️
...module/billing/web/rest/resource/BillResource.java 0.00% 6 Missing ⚠️
...penmrs/module/billing/validator/BillValidator.java 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #155      +/-   ##
============================================
+ Coverage     26.73%   27.00%   +0.27%     
- Complexity      487      497      +10     
============================================
  Files           190      190              
  Lines          4309     4336      +27     
  Branches        486      492       +6     
============================================
+ Hits           1152     1171      +19     
- Misses         3056     3063       +7     
- Partials        101      102       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ibacher
Copy link
Member

ibacher commented Mar 23, 2026

One thing we need to add is the ability for the client to submit the cashier in case it’s not the current user. It’s fine to use this as a fallback / default though.

@NethmiRodrigo
Copy link
Contributor Author

One thing we need to add is the ability for the client to submit the cashier in case it’s not the current user. It’s fine to use this as a fallback / default though.

Done!

<comment>Add cashier (provider) for each payment to track which cashier processed the payment</comment>
<addColumn tableName="cashier_bill_payment">
<column name="provider_id" type="int"/>
<constraints nullable="true"/>
Copy link
Member

Choose a reason for hiding this comment

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

Constraint should be inside the column tag

  <column name="provider_id" type="int">
      <constraints nullable="true"/>
  </column>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@claude[agent] do this change in this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nvm my session credits are over sigh

BaseRestDataResource.syncCollection(instance.getPayments(), payments);
for (Payment payment : instance.getPayments()) {
if (payment.getId() == null && payment.getCashier() == null) {
Provider cashier = getCurrentCashier();
Copy link
Member

Choose a reason for hiding this comment

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

Can't we use ProviderUtil.getCurrentProvider() here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

getCurrentCashier() method is the same logic:

  • both use Context.getAuthenticatedUser().getPerson()
  • both call ProviderService.getProvidersByPerson(...)
  • both return first provider or null

Copy link
Member

@wikumChamith wikumChamith Mar 25, 2026

Choose a reason for hiding this comment

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

Yeah, why are we duplicating existing functionalities? :)

// attempting to modify line items
assertFalse(errors.hasErrors());
}

Copy link
Member

Choose a reason for hiding this comment

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

It would be great to have some actual tests here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don’t the tests in BillServiceImplTest.java‎ make sure that the validator works too?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah but having some seperate tests for the validator is convenient.

Copy link
Contributor Author

@NethmiRodrigo NethmiRodrigo Mar 25, 2026

Choose a reason for hiding this comment

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

Convenient, how? That would be redundant. Since the validator is already getting tested, having this just means adding another test that tests the same thing. It already takes a while to run tests, why add more if not needed

Copy link
Member

Choose a reason for hiding this comment

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

By that logic, we shouldn't write tests for the DAO layer since the service layer already covers it. The point of unit tests is to test a unit in isolation, so failures are obvious and edge cases are cheap to cover.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wikumChamith I moved the tests to the validator :)

NethmiRodrigo and others added 3 commits March 24, 2026 21:38
…t edge case

Relocates payment-cashier and line-item validation tests from
BillServiceImplTest to BillValidatorTest so each test class covers its
own layer. Adds validate_shouldTolerateVoidedNewPaymentWithNoCashier to
cover the voided-payment branch in BillValidator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…equire cashier in payment test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

4 participants