Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OBPIH-6331 Inferring bin locations in pick import #4675

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

jmiranda
Copy link
Member

@jmiranda jmiranda commented Jun 16, 2024

Rebased version.

Comment on lines +1285 to +1286
String lotNumberName = data.lotNumber ?: g.message(code: "default.noLotNumber.label", default: Constants.DEFAULT_LOT_NUMBER)
String binLocationName = data.binLocation ?: g.message(code: "default.noBinLocation.label", default: Constants.DEFAULT_BIN_LOCATION_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This was probably an issue that came after rebase but it looks like g is not defined in this scope so we need to add

ApplicationTagLib g = grailsApplication.mainContext.getBean(ApplicationTagLib.class)

in the scope or move this same code from the previous if (!availableItem) in a higher block/scope (move it out of the if block)

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 expect you to change this but I'd love for us to have a dto (or whatever) package that we can put our request objects in instead of sticking them alongside the controllers. Something for us to think about in the future

}

// FIXME If location.name is not unique then we need to do some error handling
return locations.find { it.name.equalsIgnoreCase(name) }
Copy link
Collaborator

Choose a reason for hiding this comment

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

if this is an internal location, you don't need to do an isInternalLocation() check?

@@ -38,6 +39,10 @@ class ImportPickCommand implements Validateable {
})
}

boolean getIsDefaultBinLocation() {
return !binLocation || binLocation?.equalsIgnoreCase(Constants.DEFAULT_BIN_LOCATION_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need the ? if you're doing the null check first.

Suggested change
return !binLocation || binLocation?.equalsIgnoreCase(Constants.DEFAULT_BIN_LOCATION_NAME)
return !binLocation || binLocation.equalsIgnoreCase(Constants.DEFAULT_BIN_LOCATION_NAME)


stockMovementService.validatePicklistListImport(stockMovement, pickPageItems, importedLines)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might be a larger discussion but I'll note it here.

What's the advantage of using these command objects vs just passing the objects that a method needs like we had before? What problem is it solving for us?

We used something similar at my previous job (we called them Context objects) but were encouraged to only use them in really complex flows that need to maintain a certain state across classes.

I get that it simplifies the args down to a single object, but if we're not careful I can see a world where we're stuck with dozens of command objects that only do one specific thing.

void validatePicklistListImport(StockMovement stockMovement, List<PickPageItem> pickPageItems, List<ImportPickCommand> picklistItems) {
Map<String, List> picklistItemsGroupedByRequisitionItem = picklistItems.groupBy { it.id }
/**
* This method needs to be broken down into multiple smaller methods.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree 😆

Copy link
Collaborator

@EWaterman EWaterman Jun 17, 2024

Choose a reason for hiding this comment

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

I think you have a comment in the controller class that is alluding to this, but you could have a PicklistImportValidator (that extends some generic ImportValidator) that wraps all this logic and returns a PicklistImportValidationResult object (that extends some generic ValidationResult).

This is a really complex validation step so I don't know exactly what that would look like, but you could break it down further into smaller validators if you really wanted to and just bubble up the ValidationResult.

    PicklistImportValidationResult result = picklistImportValidator.validate()
    if (!result.isValid()) {
        result.errors()....
    }

And in the PicklistImportValidator:

    PicklistImportValidationResult validate() {
       PicklistImportValidationResult result = new()
        ...
        ValidationResult xResult = someMoreSpecificValidator.validate()
        result.addAll(xResult.errors())
    }

Again, this is super complex so I don't know how well that would work, but as is, this feels like it really needs to be broken down somehow. The method is pretty unwieldy.

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.

None yet

4 participants