Skip to content

OBPIH-5981 Improve redirect for e-request edit action for a requestor…#4423

Merged
awalkowiak merged 2 commits intofeature/upgrade-to-grails-3.3.10from
OBPIH-5981
Jan 9, 2024
Merged

OBPIH-5981 Improve redirect for e-request edit action for a requestor…#4423
awalkowiak merged 2 commits intofeature/upgrade-to-grails-3.3.10from
OBPIH-5981

Conversation

@kchelstowski
Copy link
Collaborator

… in a ward location (request approval feature) + refactor redirect logic for SM edit action

Since it's targeting the 0.9.1, and I had to touch this code, I decided to refactor this part to improve the readability of the redirect logic which was like this:

if(stockMovement.isReturn) {
    redirect(controller: "stockTransfer", action: "edit", params: params)
} else if (stockMovement?.getStockMovementDirection(currentLocation) == StockMovementDirection.OUTBOUND && stockMovement?.requisition?.sourceType == RequisitionSourceType.ELECTRONIC) {
    redirect(action: "verifyRequest", params: params)
}
else if (stockMovement?.getStockMovementDirection(currentLocation) == StockMovementDirection.INBOUND) {

    if (stockMovement.isFromOrder) {
        redirect(action: "createCombinedShipments", params: params)
    } else if (stockMovement.requisition?.sourceType == RequisitionSourceType.ELECTRONIC) {
        if (stockMovement.requisition?.status == RequisitionStatus.CREATED) {
            redirect(action: "createRequest", params: params)
        } else {
            redirect(action: "verifyRequest", params: params)
        }
    } else {
        redirect(action: "createInbound", params: params)
    }
}
else {
    if (stockMovement.isFromOrder) {
        redirect(action: "createCombinedShipments", params: params)
    }
    redirect(action: "createOutbound", params: params)
}

and after my changes (I paste it since the changes in the github might be difficult to read):

if (stockMovement.isReturn) {
    redirect(controller: "stockTransfer", action: "edit", params: params)
    return
}

StockMovementDirection stockMovementDirection = stockMovement?.getStockMovementDirection(currentLocation)

// Redirect logic for the e-request
if (stockMovement?.electronicType) {
    switch (stockMovementDirection) {
        case StockMovementDirection.OUTBOUND:
            redirect(action: "verifyRequest", params: params)
            break
        case StockMovementDirection.INBOUND:
            User currentUser = AuthService.currentUser
            RequisitionStatus requisitionStatus = stockMovement.requisition?.status
            // If a request's status is created or a user is a requestor logged in, in a location
            // with submit request and without manage inventory, and the request has waiting for approval
            // status, we want to redirect to add items page (OBPIH-5981)
            if (requisitionStatus == RequisitionStatus.CREATED
                || (userService.isUserRequestor(currentUser)
                    && currentLocation.downstreamConsumer
                    && requisitionStatus == RequisitionStatus.PENDING_APPROVAL)) {
                        redirect(action: "createRequest", params: params)
                        return
            }
            redirect(action: "verifyRequest", params: params)
            break
        default:
            break
    }
    return
}

// Redirect logic for the combined shipments feature
if (stockMovement.isFromOrder) {
    redirect(action: "createCombinedShipments", params: params)
    return
}

// Redirect logic for the regular stock movement feature
switch (stockMovementDirection) {
    case StockMovementDirection.OUTBOUND:
        redirect(action: "createOutbound", params: params)
        break
    case StockMovementDirection.INBOUND:
        redirect(action: "createInbound", params: params)
        break
    default:
        break
}

the part that is the scope of the ticket is this:

if (requisitionStatus == RequisitionStatus.CREATED
      || (userService.isUserRequestor(currentUser)
          && currentLocation.downstreamConsumer
          && requisitionStatus == RequisitionStatus.PENDING_APPROVAL)) {
              redirect(action: "createRequest", params: params)
              return
  }

… in a ward location (request approval feature) + refactor redirect logic for SM edit action
@kchelstowski kchelstowski self-assigned this Dec 15, 2023
@kchelstowski kchelstowski added this to the 0.9.1 milestone Dec 15, 2023
Copy link
Collaborator

@drodzewicz drodzewicz left a comment

Choose a reason for hiding this comment

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

Thanks for doing the refactor, I had to dos some mental gymnastics to compare the old and the new versions of this redirect logic and it wasn't easy.

In general I think it looks good and does cover all of the old cases, but please take a look at the empty default cases, I think there should be something in case we land in that default case, as unlikely as it may seem.

Comment on lines 123 to 127
default:
break
}
return
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

something feels off here, I feel like this should have some default redirect

Comment on lines +143 to +144
default:
break
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, I think a default redirect should be present here.
getStockMovementDirection can return a null value and there is no redirect handler at the end, so I think the app would crash because no redirects are specified at the end.

@kchelstowski
Copy link
Collaborator Author

kchelstowski commented Dec 18, 2023

@drodzewicz I've had the same feeling about it and expected someone of you to point that out, because I have not had idea what the default redirect should be, because as far as I'm concerned, the old code did not have a special handling for that case, did it?
I'm open for suggestions about the default redirect.

@drodzewicz
Copy link
Collaborator

Was playing around with rearranging these if statements to avoid any more indentation to make the code more readable at a glance and came to this version.
What do you think @kchelstowski ?

if (stockMovement?.electronicType) {
    switch (stockMovementDirection) {
        case StockMovementDirection.INBOUND:
            User currentUser = AuthService.currentUser
            RequisitionStatus requisitionStatus = stockMovement.requisition?.status
            // If a request's status is created or a user is a requestor logged in, in a location
            // with submit request and without manage inventory, and the request has waiting for approval
            // status, we want to redirect to add items page (OBPIH-5981)
            if (requisitionStatus == RequisitionStatus.CREATED) {
                redirect(action: "createRequest", params: params)
                return
            }
            if (requisitionStatus == RequisitionStatus.PENDING_APPROVAL 
                && userService.isUserRequestor(currentUser)
                && currentLocation.downstreamConsumer
             ) {
                 redirect(action: "createRequest", params: params)
                 return
            }
            break
        case StockMovementDirection.OUTBOUND:
            break
        default:
            break
    }
    redirect(action: "verifyRequest", params: params)
    return
}

@kchelstowski
Copy link
Collaborator Author

kchelstowski commented Dec 18, 2023

@drodzewicz thanks for the proactivity. I agree separating the CREATED/PENDING_APPROVAL statements is more readable even though we repeat the createRequest redirect. I didn't want to repeat the code, since they redirect to the same thing, but we should probably balance readability vs repetition of the code.
I'm fine with the version proposed by you for the CREATED/PENDING_APPROVAL case although I'd say this part feels weird to me:

case StockMovementDirection.OUTBOUND:
            break

at first sight it would mean that we don't care about the OUTBOUND at all even though we do the redirect a few lines below.
Then maybe we could take one more step and get rid of this case at all?

if (stockMovement?.electronicType) {
    switch (stockMovementDirection) {
        case StockMovementDirection.INBOUND:
            User currentUser = AuthService.currentUser
            RequisitionStatus requisitionStatus = stockMovement.requisition?.status
            // If a request's status is created or a user is a requestor logged in, in a location
            // with submit request and without manage inventory, and the request has waiting for approval
            // status, we want to redirect to add items page (OBPIH-5981)
            if (requisitionStatus == RequisitionStatus.CREATED) {
                redirect(action: "createRequest", params: params)
                return
            }
            if (requisitionStatus == RequisitionStatus.PENDING_APPROVAL 
                && userService.isUserRequestor(currentUser)
                && currentLocation.downstreamConsumer
             ) {
                 redirect(action: "createRequest", params: params)
                 return
            }
            redirect(action: "verifyRequest", params: params)
            break
        default:
            redirect(action: "verifyRequest", params: params)
    }
    return
}

Now I've even started to realize if the switch/case makes sense here. What do you think?

it'd look like this:

if (stockMovement?.electronicType) {
    if (stockMovementDirection == StockMovementDirection.INBOUND) {
        User currentUser = AuthService.currentUser
        RequisitionStatus requisitionStatus = stockMovement.requisition?.status
        // If a request's status is created or a user is a requestor logged in, in a location
        // with submit request and without manage inventory, and the request has waiting for approval
        // status, we want to redirect to add items page (OBPIH-5981)
        if (requisitionStatus == RequisitionStatus.CREATED) {
            redirect(action: "createRequest", params: params)
            return
        }
        if (requisitionStatus == RequisitionStatus.PENDING_APPROVAL 
            && userService.isUserRequestor(currentUser)
            && currentLocation.downstreamConsumer
         ) {
             redirect(action: "createRequest", params: params)
             return
        }
     }
     redirect(action: "verifyRequest", params: params)
     return
}

@drodzewicz
Copy link
Collaborator

@kchelstowski looks good, let's proceed with that

@kchelstowski
Copy link
Collaborator Author

@awalkowiak @jmiranda do you also agree with our latest proposition? I want to make sure everyone agrees, before I make the change.

Copy link
Member

@jmiranda jmiranda left a comment

Choose a reason for hiding this comment

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

My first thought when seeing this was "rendering a view should not be this complicated".

Can we reduce the complexity by creating separate URLs for the different types of requests / transfers and not using the stock movement controller as a central hub? If not, is there another way to reduce the complexity.

@kchelstowski
Copy link
Collaborator Author

@jmiranda since for "Edit stock movement" our url is /stockMovement/edit and it's currently handled in the method I've refactored, to do it like you suggested, we would actually have to add a similar in terms of complexity logic in the show.gsp view of the stock movement, to determine what url the "Edit stock movement" should have.

Since the current else-if logic drove us nuts and I had to add one more case there, I decided to refactor it a bit, so it becomes more readable.
Let me know if it's fine for now or if we'd want to have a different approach there.

Copy link
Collaborator

@awalkowiak awalkowiak left a comment

Choose a reason for hiding this comment

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

I am very "pro" these changes. I think this part was getting worse and worse.

@kchelstowski lets finalize the refactoring that you started, if there are any improvements left from Dariusz's review. And please make double check locally on every branch we had previously, that it is still working correctly.

@jmiranda I think that the issue here is that we rather wanted to keep various workflows under one stock movement. And it kept growing and expanding. I think ideally we could think about the separation of the pages or other type of the refactor, but there are to many of "what ifs". For now I would go with this cleanup for 0.9.1, since it is already done, and I think looks good. We can come back to this chunk of code, as tech debt and discuss on the tech huddle. I feel we might run into few use cases from past, where we get some answers why its like that. We need to dig it out a bit from tickets and perhaps test/use cases.

@awalkowiak awalkowiak merged commit b8e11d8 into feature/upgrade-to-grails-3.3.10 Jan 9, 2024
@awalkowiak awalkowiak deleted the OBPIH-5981 branch January 9, 2024 15:29
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.

4 participants