Skip to content

OBPIH-7001 Add “Active” column to Product export/import#5556

Merged
alannadolny merged 4 commits intodevelopfrom
feature/OBPIH-7001
Oct 24, 2025
Merged

OBPIH-7001 Add “Active” column to Product export/import#5556
alannadolny merged 4 commits intodevelopfrom
feature/OBPIH-7001

Conversation

@SebastianLib
Copy link
Collaborator

✨ Description of Change

Link to GitHub issue or Jira ticket:
https://pihemr.atlassian.net/browse/OBPIH-7001

Description:


📷 Screenshots & Recordings (optional)

@github-actions github-actions bot added type: feature A new piece of functionality for the app domain: frontend Changes or discussions relating to the frontend UI domain: backend Changes or discussions relating to the backend server flag: config change Hilights a pull request that contains a change to the app config labels Oct 16, 2025
Comment on lines 630 to 640
Boolean parseCsvBooleanField(String value, int rowCount) {
// If the value is empty we treat it as true
if (!value) {
return true
}
String parsedValue = value.toLowerCase()
Set<String> validValues = ['true', 'false', '1', '0']
if (!(parsedValue in validValues)) {
throw new RuntimeException("Active field has to be either empty or a boolean value (true/false/1/0) at row " + rowCount)
}
return parsedValue in ['true', '1']
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'm wondering if we could do this in a better way 🤔

Copy link
Member

Choose a reason for hiding this comment

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

why not use String.toBoolean()?

This returns:

assert "true".toBoolean() == true
assert "TRUE".toBoolean() == true
assert "  TrUe  ".toBoolean() == true
assert "1".toBoolean() == true
assert "y".toBoolean() == true
assert "yes".toBoolean() == true

and is false otherwise. Then all you need to do is:

return value == null ? true : value.toBolean()

But if you're not using it because you want to throw an error in case of invalid input, then a few suggestions:

  • make the method static and put it in a util class that we can re-use
  • do String parsedValue = value.trim().toLowerCase() (whitespace shouldn't matter)
  • add the following static constants:
    Set<String> validBooleanValues = ['t', 'f', 'true', 'false', '1', '0', 'y', 'n', 'yes', 'no']
    Set<String> trueBooleanValues = ['t, 'true', '1', 'y', 'yes']
    

@codecov
Copy link

codecov bot commented Oct 16, 2025

Codecov Report

❌ Patch coverage is 2.70270% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 8.54%. Comparing base (1bb7314) to head (63e1936).
⚠️ Report is 153 commits behind head on develop.

Files with missing lines Patch % Lines
...es/org/pih/warehouse/product/ProductService.groovy 0.00% 27 Missing ⚠️
.../groovy/org/pih/warehouse/importer/CSVUtils.groovy 0.00% 9 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             develop   #5556      +/-   ##
============================================
- Coverage       9.12%   8.54%   -0.59%     
+ Complexity      1170    1113      -57     
============================================
  Files            701     702       +1     
  Lines          45281   45346      +65     
  Branches       10851   10869      +18     
============================================
- Hits            4131    3873     -258     
- Misses         40497   40895     +398     
+ Partials         653     578      -75     

☔ 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.

// FIXME make relation to Constants.EXPORT_PRODUCT_COLUMNS explicit
def row = [
Id : product?.id,
Active : product.active ?: Boolean.FALSE,
Copy link
Member

Choose a reason for hiding this comment

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

parseCsvBooleanField defaults to true. Why is this default different?

Comment on lines 630 to 640
Boolean parseCsvBooleanField(String value, int rowCount) {
// If the value is empty we treat it as true
if (!value) {
return true
}
String parsedValue = value.toLowerCase()
Set<String> validValues = ['true', 'false', '1', '0']
if (!(parsedValue in validValues)) {
throw new RuntimeException("Active field has to be either empty or a boolean value (true/false/1/0) at row " + rowCount)
}
return parsedValue in ['true', '1']
Copy link
Member

Choose a reason for hiding this comment

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

why not use String.toBoolean()?

This returns:

assert "true".toBoolean() == true
assert "TRUE".toBoolean() == true
assert "  TrUe  ".toBoolean() == true
assert "1".toBoolean() == true
assert "y".toBoolean() == true
assert "yes".toBoolean() == true

and is false otherwise. Then all you need to do is:

return value == null ? true : value.toBolean()

But if you're not using it because you want to throw an error in case of invalid input, then a few suggestions:

  • make the method static and put it in a util class that we can re-use
  • do String parsedValue = value.trim().toLowerCase() (whitespace shouldn't matter)
  • add the following static constants:
    Set<String> validBooleanValues = ['t', 'f', 'true', 'false', '1', '0', 'y', 'n', 'yes', 'no']
    Set<String> trueBooleanValues = ['t, 'true', '1', 'y', 'yes']
    

*/
static Boolean parseCsvBooleanField(String value, int rowCount) {
if (!value) {
return true
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: it would probably be best for this to be a param so that it's configurable. You also might want to use StringUtils so that " " is also considered falsey:

static Boolean parseCsvBooleanField(String value, int rowCount, Boolean defaultValue) {
    if (StringUtils.isBlank(value)) {
        return defaultValue
    }
    ....

String parsedValue = value.trim().toLowerCase()

if (!(parsedValue in validBooleanValues)) {
throw new RuntimeException("Active field has to be either empty or a boolean value (${validBooleanValues.join(', ')}) at row ${rowCount}")
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: I think you can just do ${validBooleanValues} because the Set.toString() method will output properly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, I didn’t know that 😄 I thought it worked like in JavaScript and that you had to add .join().

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe it’s better to stick with .join(", "), because without it we display [t, f, true, false, 1, 0, y, n, yes, no], and we probably don’t want to display the square brackets. 🤔

image

Copy link
Member

Choose a reason for hiding this comment

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

What's wrong with the square brackets? Your error message adds round brackets so you could just remove those and let it use the square ones instead:

"Active field has to be either empty or a boolean value ${validBooleanValues} at row ${rowCount}"


class CsvUtil {
static final Set<String> validBooleanValues = ['t', 'f', 'true', 'false', '1', '0', 'y', 'n', 'yes', 'no']
static final Set<String> trueBooleanValues = ['t', 'true', '1', 'y', 'yes']
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: please use all caps for constants: VALID_BOOLEAN_VALUES, TRUE_BOOLEAN_VALUES

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Initially, that’s what I wanted to do, but when I noticed that you wrote it in camelCase in previous comment, I decided to do the same. I will change it.

@alannadolny alannadolny merged commit 6783694 into develop Oct 24, 2025
7 checks passed
@alannadolny alannadolny deleted the feature/OBPIH-7001 branch October 24, 2025 08:45
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 flag: config change Hilights a pull request that contains a change to the app config type: feature A new piece of functionality for the app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants