Skip to content

OBPIH-6896 Implement perform count API#5048

Merged
awalkowiak merged 2 commits intodevelopfrom
OBPIH-6896
Feb 19, 2025
Merged

OBPIH-6896 Implement perform count API#5048
awalkowiak merged 2 commits intodevelopfrom
OBPIH-6896

Conversation

@kchelstowski
Copy link
Collaborator

✨ Description of Change

A concise summary of what is being changed. Please provide enough context for reviewers to be able to understand the change and why it is necessary. If the issue/ticket already provides enough information, you can put "See ticket" as the description.

Link to GitHub issue or Jira ticket:

Description:


📷 Screenshots & Recordings (optional)

If this PR contains a UI change, consider adding one or more screenshots here or link to a screen recording to help reviewers visualize the change. Otherwise, you can remove this section.

@kchelstowski kchelstowski added the warn: do not merge Marks a pull request that is not yet ready to be merged label Feb 14, 2025
@kchelstowski kchelstowski self-assigned this Feb 14, 2025
@github-actions github-actions bot added domain: backend Changes or discussions relating to the backend server flag: schema change Hilights a pull request that contains a change to the database schema domain: l10n Changes or discussions relating to localization & Internationalization labels Feb 14, 2025
@codecov
Copy link

codecov bot commented Feb 14, 2025

Codecov Report

Attention: Patch coverage is 7.27273% with 51 lines in your changes missing coverage. Please review.

Project coverage is 7.84%. Comparing base (db0b3bc) to head (e16a47b).
Report is 200 commits behind head on develop.

Files with missing lines Patch % Lines
...g/pih/warehouse/inventory/CycleCountService.groovy 0.00% 35 Missing ⚠️
...ouse/inventory/CycleCountSubmitCountCommand.groovy 0.00% 11 Missing ⚠️
...g/pih/warehouse/api/CycleCountApiController.groovy 0.00% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             develop   #5048      +/-   ##
============================================
- Coverage       7.84%   7.84%   -0.01%     
  Complexity       876     876              
============================================
  Files            625     626       +1     
  Lines          42813   42868      +55     
  Branches       10376   10384       +8     
============================================
+ Hits            3358    3362       +4     
- Misses         38952   39003      +51     
  Partials         503     503              

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Collaborator Author

@kchelstowski kchelstowski left a comment

Choose a reason for hiding this comment

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

A general comment is that we should revisit the getStatus method from the cycle count. (Now recomputeStatus after @ewaterman 's changes). I believe we have a lot of missing parts there - I mean, some statuses are named differenly in docs, and we ended up with different statuses in the enum.
I also think that there are a few if statements that collide with each other (I can provide examples).

return
}
if (!requireRecountOnDiscrepancy) {
cycleCountItem.status = CycleCountItemStatus.APPROVED
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

in the docs it was said, that the item state should be set to DISCREPANCY_ACCEPTED - we don't have such status for an item, so I assumed it's equivalent to APPROVED?

Copy link
Member

Choose a reason for hiding this comment

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

I think both this if condition and the previous one should have status READY_TO_REVIEW.

When I was originally designing this I was imagining that we wanted a status that meant "there's a discrepancy, but we don't care". But it looks like we don't need to be able to distinguish that case so if !requireRecountOnDiscrepancy, then the item should always get status READY_TO_REVIEW because counting is completed.

return
}
// FIXME: INVESTIGATING = DISCREPANCY_TO_RESOLVE???
cycleCountItem.status = CycleCountItemStatus.INVESTIGATING
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the same case as above - it was meant to be set as DISCREPANCY_TO_RESOLVE, but again - we don't have such a status, so is it equivalent to INVESTIGATING?

Copy link
Member

Choose a reason for hiding this comment

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

I think we want COUNTED. We use COUNTED to mean there is a discrepancy but recounting hasn't been started yet (once the recount starts, the status will be INVESTIGATING).

I'm not the hugest fan of this because to me the word "counted" doesn't imply a discrepancy, but that's what we have currently

CycleCountStatus.COUNTING,
CycleCountStatus.INVESTIGATING,
CycleCountStatus.REQUESTED,
CycleCountStatus.COUNTED,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

quote from docs:

If Cycle Count is not in status ready to count, counting, investigating, or counted, error

  1. is READY_TO_COUNT equivalent to REQUESTED?
  2. should the COUNTED be there? If so, I can spam the requests for the same cycle count and eventually create X transactions for the same cycle count, not really mutating anything (duplicates would be created)

Copy link
Member

Choose a reason for hiding this comment

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

I wrote those statuses before I really knew which ones we were using. Given that if you've started the count you'll be in status COUNTING, and given that we're going to split count and recount into their own APIs, I think we only need COUNTING here actually.

@kchelstowski
Copy link
Collaborator Author

kchelstowski commented Feb 14, 2025

Marked as do not merge as I have to rebase to Evan's approach for statuses (cycle count status as a property) and align my changes with that.
Anyway the review is appreciated

if (refreshQuantityOnHand) {
cycleCountItem.quantityOnHand = currentQuantityOnHand
}
if (failOnOutdatedQuantity && cycleCountItem.quantityOnHand != currentQuantityOnHand) {
Copy link
Member

Choose a reason for hiding this comment

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

this will always be false if refreshQuantityOnHand is true. You'll want to check if currentQuantityOnHand != to cycleCountItem.quantityOnHand BEFORE you've updated it (ie if the old value has changed).

the idea is that if the QoH is changing for the product we want the user to review it again to make sure everything looks as they expected. (This will only technically be true for recounts for us because all our regular counts are blind counts and so don't need to be reviewed, but I chose to be able to support it for regular counts as well.)

transaction.save()
cycleCount.cycleCountItems.each { CycleCountItem cycleCountItem ->
TransactionEntry transactionEntry = new TransactionEntry(
quantity: cycleCountItem.quantityCounted,
Copy link
Member

Choose a reason for hiding this comment

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

This isn't quite right. We want to have multiple transactions here because we want to do two things: take a "snapshot" of the QoH at the moment of submitting the count (that's what the product inventory is for), and then specifically

  1. the product inventory transaction: for every item, quantity == cycleCountItem.quantityOnHand. So it actually doesn't use the counted value at all.
  2. credit transaction: for every item, quantity == cycleCountItem.quantityCounted - cycleCountItem.quantityOnHand if this calculation is positive
  3. debit transaction: for every item, quantity == cycleCountItem.quantityCounted - cycleCountItem.quantityOnHand if this calculation is negative

So 2 and 3 transactions only get created if there's a discrepancy for the item and they represent the quantity difference/adjustment. 1 represents the "quantity at the time of the count".

and they're all connected because they have the same cycle count id.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@ewaterman I am a bit confused. In the docs it was said that:

if all the Cycle Count Items have the COUNTED or DISCREPANCY_ACCEPTED state:
Cycle Count state = COUNTED (aka TO_REVIEW)
save a new “Cycle Count Product Inventory“ transaction using the quantityCounted value as outlined in solution 3 of the inventory transaction design.

and regarding the credit/debit transaction types it was said:

(13 and 14 aren’t relevant now, but will be used once we add the ability to submit the count with discrepancies as a part of the resolve count step so we might as well include them now.)

So I would assume this should be the resolving API responsibility, not perform count.

I was just following docs for the transaction part, so let me know if I misunderstood something or?

Copy link
Member

Choose a reason for hiding this comment

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

yeah the docs aren't especially clear. Until we implement the resolve API, if we reach this point then we know quantityCounted == quantityOnHand. And so we could use quantityCounted and it'd be fine. But once the resolve API is implemented, if there's any sort of discrepancy when we go to create the transactions, they won't be equal, and so since we're going to be inserting adjustment transactions that represent the quantity changes, we want the product inventory transaction to be the quantity at the time of the count, so it would be quantityOnHand. And since the recount and count flows will probably share this logic, it's probably simplest to just always use quantityOnHand for the product inventory transaction here.

And as for credit/debit transactions, yes you're totally right. I was getting ahead of myself. We can worry about that when we do the resolve API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So long story short is that we postpone any change in that code until we work on the resolve API?

Copy link
Member

Choose a reason for hiding this comment

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

yeah that's fine with me

return
}
if (!requireRecountOnDiscrepancy) {
cycleCountItem.status = CycleCountItemStatus.APPROVED
Copy link
Member

Choose a reason for hiding this comment

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

I think both this if condition and the previous one should have status READY_TO_REVIEW.

When I was originally designing this I was imagining that we wanted a status that meant "there's a discrepancy, but we don't care". But it looks like we don't need to be able to distinguish that case so if !requireRecountOnDiscrepancy, then the item should always get status READY_TO_REVIEW because counting is completed.

return
}
// FIXME: INVESTIGATING = DISCREPANCY_TO_RESOLVE???
cycleCountItem.status = CycleCountItemStatus.INVESTIGATING
Copy link
Member

Choose a reason for hiding this comment

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

I think we want COUNTED. We use COUNTED to mean there is a discrepancy but recounting hasn't been started yet (once the recount starts, the status will be INVESTIGATING).

I'm not the hugest fan of this because to me the word "counted" doesn't imply a discrepancy, but that's what we have currently

updateCycleCountItemForSubmit(cycleCountItem, command.refreshQuantityOnHand, command.failOnOutdatedQuantity)
determineCycleCountItemStatus(cycleCountItem, command.requireRecountOnDiscrepancy)
}
if (command.cycleCount.status == CycleCountStatus.COUNTED) {
Copy link
Member

Choose a reason for hiding this comment

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

I think we want READY_TO_REVIEW here, not COUNTED. We use COUNTED to indicate that there is a discrepancy but we haven't started recounting yet.

@kchelstowski kchelstowski force-pushed the OBPIH-6896 branch 2 times, most recently from 21dcd31 to 27bb978 Compare February 18, 2025 11:21
@kchelstowski kchelstowski removed the warn: do not merge Marks a pull request that is not yet ready to be merged label Feb 18, 2025
}

void determineCycleCountItemStatus(CycleCountItem cycleCountItem, boolean requireRecountOnDiscrepancy) {
cycleCountItem.quantityCounted = cycleCountItem.quantityOnHand
Copy link
Member

Choose a reason for hiding this comment

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

Why? This will force the count to always be accurate

Copy link
Collaborator Author

@kchelstowski kchelstowski Feb 18, 2025

Choose a reason for hiding this comment

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

🙈 thanks for catching that. I hardcoded that for testing purposes and forgot to remove it - I had to somehow mimic that we are after the update count, and since we don't have the update count API yet ready, it was the only way to mimic that.

@awalkowiak awalkowiak merged commit 7e82a85 into develop Feb 19, 2025
9 checks passed
@awalkowiak awalkowiak deleted the OBPIH-6896 branch February 19, 2025 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: backend Changes or discussions relating to the backend server domain: l10n Changes or discussions relating to localization & Internationalization flag: schema change Hilights a pull request that contains a change to the database schema

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants