Skip to content

OBPIH-7269 Add import count widget (dropzone on UI, upload endpoint, …#5253

Merged
awalkowiak merged 3 commits intodevelopfrom
OBPIH-7269
May 16, 2025
Merged

OBPIH-7269 Add import count widget (dropzone on UI, upload endpoint, …#5253
awalkowiak merged 3 commits intodevelopfrom
OBPIH-7269

Conversation

@kchelstowski
Copy link
Collaborator

…importer class)

✨ Description of Change

Link to GitHub issue or Jira ticket:

Description:


📷 Screenshots & Recordings (optional)

@kchelstowski kchelstowski self-assigned this May 14, 2025
@github-actions github-actions bot added domain: frontend Changes or discussions relating to the frontend UI domain: backend Changes or discussions relating to the backend server domain: l10n Changes or discussions relating to localization & Internationalization labels May 14, 2025
CYCLE_COUNT_START,
CYCLE_COUNT_SUBMIT_COUNT,
CYCLE_COUNT_SUBMIT_RECOUNT,
CYCLE_COUNT_SUBMIT_RECOUNT, IMPORT_CYCLE_COUNT_ITEMS, IMPORT_PACKING_LIST,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
CYCLE_COUNT_SUBMIT_RECOUNT, IMPORT_CYCLE_COUNT_ITEMS, IMPORT_PACKING_LIST,
CYCLE_COUNT_SUBMIT_RECOUNT,
IMPORT_CYCLE_COUNT_ITEMS,
IMPORT_PACKING_LIST,

try {
show();
const response = await cycleCountApi.importCycleCountItems(importFile, currentLocation?.id);
console.log(response);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it by accident?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, I left it here so that I don't have an eslint error that response is not used. Anyway this will be adjusted in the next ticket, so I guess nothing wrong with leaving it for now.

} finally {
hide();
}
// TODO: Map items to the table
Copy link
Collaborator

Choose a reason for hiding this comment

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

I assume it's for another ticket?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah

Comment on lines 30 to 39
static Map PROPERTY_MAP = [
cycleCountId: ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
productCode: ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"product.name": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"lotNumber": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"expirationDate": ([expectedType: ExpectedPropertyType.DateJavaType, defaultValue: null]),
"binLocation": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"quantityCounted": ([expectedType: ExpectedPropertyType.IntType, defaultValue: null]),
"comment": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know whether it's just GitHub formatting, but the indentations are not aligned

@kchelstowski kchelstowski requested a review from alannadolny May 14, 2025 11:52
@codecov
Copy link

codecov bot commented May 14, 2025

Codecov Report

❌ Patch coverage is 15.00000% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 8.28%. Comparing base (4127d11) to head (5809594).
⚠️ Report is 140 commits behind head on develop.

Files with missing lines Patch % Lines
...house/importer/CycleCountItemsExcelImporter.groovy 0.00% 11 Missing ⚠️
...g/pih/warehouse/api/CycleCountApiController.groovy 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             develop   #5253   +/-   ##
=========================================
  Coverage       8.27%   8.28%           
+ Complexity       980     965   -15     
=========================================
  Files            640     642    +2     
  Lines          43288   43308   +20     
  Branches       10521   10522    +1     
=========================================
+ Hits            3583    3586    +3     
- Misses         39154   39172   +18     
+ Partials         551     550    -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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ewaterman
Copy link
Member

Can you add a screenshot or recording of what the widget looks like? It would be good to be able to review the actual design of it.

cycleCounts.each { CycleCountDto cycleCount ->
cycleCount.cycleCountItems.each { CycleCountItemDto item ->
data << [
"Cycle count id": cycleCount.id,
Copy link
Member

Choose a reason for hiding this comment

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

I'm not a huge fan of needing to put cycle count id in the xls file since I'd rather not expose our internal ids to users. Can the frontend not look up the count by product? If this is the only/best solution, we should discuss with Manon to confirm that it's okay to include it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We will see in the next ticket if there is an easy way to map product codes to cycle count ids. For now it was the easiest solution to just add cycle count id to the export/import sheet (as we also do in the inbound/outbound add items import/export).
I've already discussed it with Manon before adding it, and got an approval for that.

productCode: ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"product.name": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"lotNumber": ([expectedType: ExpectedPropertyType.StringType, defaultValue: null]),
"expirationDate": ([expectedType: ExpectedPropertyType.DateJavaType, defaultValue: null]),
Copy link
Member

Choose a reason for hiding this comment

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

What happens if the date is poorly formatted at this point? Does the import fail? If so we should probably think of a different solution since we eventually want users to be able to resolve bad data in the UI, In a previous tech huddle we discussed potentially making all these fields StringType and letting the frontend handle all the validation. But if the import doesn't fail this is fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I checked that, and if you e.g. provide a random string instead of a date, it is parsed to null, so I believe it's expected.

Copy link
Member

Choose a reason for hiding this comment

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

This is fine for now but we might want to refactor this later to return it to the client as a string so that we can notify the user that they provided an invalid date. Otherwise if we just return null when we have an invalid format we wont be able to distinguish between the case where the lot just doesnt't have an expiry date (because it also returns null)

@kchelstowski
Copy link
Collaborator Author

@ewaterman attaching a screenshot:
Screenshot from 2025-05-15 11-18-12

I have not changed anything in terms of the design, it's the same as in the outbound import.

export const CYCLE_COUNT_SUBMIT_COUNT = (locationId, cycleCountId) => `${CYCLE_COUNT(locationId)}/${cycleCountId}/count`;
export const CYCLE_COUNT_SUBMIT_RECOUNT = (locationId, cycleCountId) => `${CYCLE_COUNT(locationId)}/${cycleCountId}/recount`;
export const CYCLE_COUNT_REFRESH_ITEMS = (locationId, cycleCountId, removeOutOfStockItemsImplicitly) => `${CYCLE_COUNT(locationId)}/${cycleCountId}/refresh${removeOutOfStockItemsImplicitly ? '?removeOutOfStockItemsImplicitly=true' : ''}`;
export const IMPORT_CYCLE_COUNT_ITEMS = (locationId) => `${CYCLE_COUNT(locationId)}/items/upload/count`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

To match this constant with our previous naming for cycle count actions, I would call it CYCLE_COUNT_IMPORT_ITEMS

Copy link
Member

@ewaterman ewaterman left a comment

Choose a reason for hiding this comment

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

I'm approving but I think we should be ready discuss the design with Manon. I was originally expecting the importer to be a popup window (or an expandable section if that's easier).

Having it always be there is a bit awkward since some users will never use it and it takes up so much of the screen so they have to scroll just to see the table fully.

@awalkowiak awalkowiak merged commit 05c516a into develop May 16, 2025
9 checks passed
@awalkowiak awalkowiak deleted the OBPIH-7269 branch May 16, 2025 15:18
@sentry
Copy link

sentry bot commented May 27, 2025

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ NullPointerException: Cannot get property 'originalFilename' on null object POST /openboxes/api/facilities/8a8a9e9665c4f59d... View Issue

Did you find this useful? React with a 👍 or 👎

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: frontend Changes or discussions relating to the frontend UI domain: l10n Changes or discussions relating to localization & Internationalization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants