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 #4658

Closed
wants to merge 3 commits into from

Conversation

jmiranda
Copy link
Member

No description provided.

@jmiranda
Copy link
Member Author

Although it's not done, y'all can start to review this one.

Comment on lines +288 to +290
Location getDefaultLocation() {
return null
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there something missing? I can't see any comment here

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, this is awkward at best. I think this was just a quick hack to get it working and I was expecting to get back to it. I am trying to provide a representation of a default location. But the default location is just a Location that is null.

I would love to do this in a better way and open to ideas. A javadoc comment is necessary. And maybe this needs to be a static method, returning a constant?

static Location getDefaultLocation() { 
    return Constants.DEFAULT_LOCATION 
}

or something like this?

final static Location DEFAULT_LOCATION = null;
static Location getDefaultLocation() { 
    return Location.DEFAULT_LOCATION; 
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

The first static method returning a constant looks great

grails-app/domain/org/pih/warehouse/product/Product.groovy Outdated Show resolved Hide resolved
@@ -323,6 +324,10 @@ class AvailableItem {
quantityAvailable(nullable: true)
}

String getBinLocationName() {
binLocation?.name?: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.

Suggested change
binLocation?.name?:Constants.DEFAULT_BIN_LOCATION_NAME
binLocation?.name ?: Constants.DEFAULT_BIN_LOCATION_NAME

@jmiranda jmiranda added the status: ready for review Flags that a pull request is ready to be reviewed label Jun 11, 2024
String binLocationName = data.binLocation ?: g.message(code: "default.noBinLocation.label", default: Constants.DEFAULT_BIN_LOCATION_NAME)
// TODO Do we handle the case where ID is null?
// Group the picklist items from the CSV by requisition item ID
Map<String, List> picklistItemsGroupedByRequisitionItem = command.picklistItems.groupBy { it.id }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the id on the PicklistItemCommand a requisition item's id?

picklistItemsGroupedByRequisitionItem.each { requisitionItemId, picklistItems ->

// Iterate over each separate pick
picklistItems.each { PicklistItemCommand data ->
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does PicklistItemCommand represent already picked item, item to be picked or both cases?

// TODO What happens if ID is null. We should throw an exception if we don't have a good answer.
// skip validation if id is empty since most of the validation relies on an existing requisition id
// skip validation if id is empty since mos tof the validation relies on an existing requisition id
if (!data.id) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks like it cannot be empty because id on PicklistItemCommand has constraints: nullable: false, blank: false

// FIXME this probably shouldn't be necessary, but i was getting
// a validation error on location (possibly when the command object
// was initially bound).
location = AuthService.currentLocation
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it should be a StockMovement's origin location instead current location. What do you think?

// OBPIH-6331 Resolve bin location, if a bin location value was provided. Otherwise,
// if the user-provided bin location is null or ambiguous then we need to apply
// allocation rules
Location internalLocation = command.location.getInternalLocation(data.binLocation)
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 technically possible (now or in the future, through API) that someone will be able to import an outbound not from the "current location"? This is why I am wondering if we should not start using origin instead of current location as a command.location 🤔

Comment on lines +1368 to +1370
boolean isInDefaultLocation = availableItems.every { it.isDefaultLocation }
boolean isInReceivingLocations = availableItems.every { it.isReceivingLocation }
boolean isInBinLocations = availableItems.every { it.isBinLocation && !it.isDefaultLocation }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are these three variables used anywhere

Integer countInBinLocations2 = availableItems?.findAll { it?.isBinLocation }?.size()
log.info "countInBinLocations " + countInBinLocations2
Integer countInVirtualLocations = availableItems?.findAll { it?.isVirtualLocation }?.size()
log.info "countInVirtualLocations " + countInVirtualLocations
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are these required too? Or the scenario above is still to be finished?

// Scenario 4: Any other scenario (stock in “real” bin and virtual bin, stock in multiple real bins)
// TODO If there's not enough available quantity in default + receiving
// locations, then throw an exception
boolean isAllStockInReceivingOrDefault = availableItems.every { it.isReceivingLocation || it.isDefaultLocation }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there an order of precedence for this scenario which is picked first? Plus for this scenario shouldn't we also look at stock in “real” bin looks like you only look at receiving or default

// TODO Need to test this thoroughly as it does not feel like a good idea. For example,
// we don't necessarily want to clear picklist if there's no picklist items to import
// so this might need to go inside a check on !picklistItemsToImport.empty
clearPicklist(pickPageItem.requisitionItem)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I think this might cause unnecessary product availability refresh if there are no existing picklist items at this stage

"binLocation",
"importPickCommand.binLocation.multipleEmpty.error",
[data.lotNumber] as Object[],
"Bin location cannot be empty for multiple rows with the same lot number {0}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I never knew we can treat default message just like the label 🙈

Comment on lines +227 to +228
// Bind user-provided location or current location
command.location = command.location ?: Location.get(session.warehouse.id)
Copy link
Collaborator

Choose a reason for hiding this comment

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

(Just thinking out loud)

I wonder if in case of importing, we will ever need current logged in location 🤔
For example, case with supported activity Allow Overpick I belive we should check this activity not on current logged in location but on origin because the origin location should decide if it supports this activity.

This was just one example but I guess any future validation will involve either the origin or destination locations, the current logged in location will probably be a single case that will not allow importing items if current location != origin.

Do I have a point or am I going off the track?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yup, I agree with you. I also think we should base it on the origin in this case. I brought this up in the PicklistImportDataCommand too.


// FIXME Remove this if it's no longer being used
// Configuration property that allows overpick for a given location
Boolean supportsOverpick = command.location.supports(ActivityCode.ALLOW_OVERPICK)
Copy link
Collaborator

Choose a reason for hiding this comment

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

like I mentioned in the comment before, this should probably be checked for origin location and not current logged-in.

@awalkowiak
Copy link
Collaborator

Closing this one because this is stale branch, and the feature itself was already merged

@awalkowiak awalkowiak closed this Jun 26, 2024
@awalkowiak awalkowiak deleted the OBPIH-6331-part-deux branch June 26, 2024 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: ready for review Flags that a pull request is ready to be reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants