Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion src/screens/Picking/PickingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,14 @@ type PickingContextType = {
revalidateTasksForRequisition: (requisitionId: string | undefined, callback?: () => void) => void;
/** Start the pick task (API call) */
startPickTask: (callback: (response: { errorMessage?: string }) => void) => void;
/** Drop the current pick task at the staging location */
/** Drop the current pick task at the system-suggested staging location */
dropCurrentTask: (task: PickTask, callback?: (response: { errorMessage?: string }) => void) => void;
/** Drop the current pick task at the given staging location */
dropCurrentTaskAtStagingLocation: (
task: PickTask,
stagingLocationId: string,
callback?: (response: { errorMessage?: string }) => void
) => void;
/** Revalidates the current pick task details from the server */
revalidateCurrentTask: (callback?: (task: PickTask | undefined) => void) => void;
/** Advances to the next task in the list */
Expand Down Expand Up @@ -216,6 +222,30 @@ export function PickingProvider({ children }: { children: React.ReactNode }) {
dispatch(dropPickTaskAction(task.outboundContainer.id, task.stagingLocation.id, callback));
};

// Like dropCurrentTask but drops at the given (scanned) staging location instead of the pick task's suggested one
const dropCurrentTaskAtStagingLocation = (
task: PickTask,
stagingLocationId: string,
callback?: (response: { errorMessage?: string }) => void
) => {
if (!task) {
Alert.alert('Task Missing', 'No current task to drop.');
return;
}

if (!stagingLocationId) {
Alert.alert('Missing Input', 'Please scan or enter a staging location.');
return;
}

if (!task.outboundContainer?.id) {
Alert.alert('Error', 'Current task does not have a valid Outbound Container.');
return;
}

dispatch(dropPickTaskAction(task.outboundContainer.id, stagingLocationId, callback));
};

const resetSession = () => {
setTasks([]);
setCurrentTaskIndex(0);
Expand All @@ -237,6 +267,7 @@ export function PickingProvider({ children }: { children: React.ReactNode }) {
revalidateTasksForRequisition,
startPickTask,
dropCurrentTask,
dropCurrentTaskAtStagingLocation,
revalidateCurrentTask,
goToNextTask
}}
Expand Down
49 changes: 47 additions & 2 deletions src/screens/Picking/PickingPickStagingLocationScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import { parseFromISODateToLocaleString } from '../../utils/utils';
import { usePickingContext } from './PickingContext';
import styles from './styles';

// Lets the user stage at any scanned location. Set to false to require the scanned location to
// match the one suggested by the pick task.
Comment on lines +15 to +16
const SKIP_STAGING_LOCATION_VALIDATION = true;
Comment thread
awalkowiak marked this conversation as resolved.

export default function PickingPickStagingLocationScreen() {
const { tasks, dropCurrentTask, resetSession, setCurrentTaskIndex } = usePickingContext();
const { tasks, dropCurrentTask, dropCurrentTaskAtStagingLocation, resetSession, setCurrentTaskIndex } =
usePickingContext();
const [stagingLocationNumber, setStagingLocationNumber] = React.useState(EMPTY_STRING);
const [currentUniqueIndex, setCurrentUniqueIndex] = React.useState(0);
const { isSearchOpen, searchButtonProps } = useSearchButton({ onSelect: setStagingLocationNumber });
Expand All @@ -35,6 +40,7 @@ export default function PickingPickStagingLocationScreen() {
}
}, [currentTask, tasks.length, setCurrentTaskIndex, uniqueTasks.length, tasks]);

// Requires the scanned location to match the one suggested by the task. Used when SKIP_STAGING_LOCATION_VALIDATION is false.
function handleScan(locationId: string) {
const expected = currentTask.stagingLocation?.locationNumber;

Expand Down Expand Up @@ -79,6 +85,45 @@ export default function PickingPickStagingLocationScreen() {
});
}

// Drops at whatever location the user scans, without checking it against the task's suggestion.
// Used when SKIP_STAGING_LOCATION_VALIDATION is true.
function handleScanWithoutValidation(locationId: string) {
if (!locationId) {
return;
}

dropCurrentTaskAtStagingLocation(currentTask, locationId, (response) => {
if (response.errorMessage) {
Comment thread
awalkowiak marked this conversation as resolved.
Alert.alert('Error', response.errorMessage);
setStagingLocationNumber(EMPTY_STRING);
return;
}

const nextIndex = currentUniqueIndex + 1;
if (nextIndex < uniqueTasks.length) {
Alert.alert('Success', 'Staging Location confirmed. Proceeding to the next container.', [
{
text: 'OK',
onPress: () => {
setCurrentUniqueIndex(nextIndex);
setStagingLocationNumber(EMPTY_STRING);
}
}
]);
} else {
Alert.alert('Picking Session Complete', 'You have completed all staging confirmations.', [
{
text: 'OK',
onPress: () => {
resetSession();
resetToRoutes([{ name: 'Drawer', params: { screen: 'Dashboard' } }, { name: 'PickingPickType' }]);
}
}
]);
}
});
}

// If no task is selected yet, return null to avoid rendering
// ProductDetails with undefined data while useEffect runs
if (!currentTask) {
Expand Down Expand Up @@ -150,7 +195,7 @@ export default function PickingPickStagingLocationScreen() {
value={stagingLocationNumber}
isEnabled={!isSearchOpen}
onChange={setStagingLocationNumber}
onSubmit={handleScan}
onSubmit={SKIP_STAGING_LOCATION_VALIDATION ? handleScanWithoutValidation : handleScan}
/>
<SearchButton searchType="location" {...searchButtonProps} />
</View>
Expand Down