diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx index 425b76e1bc..fe209f11c9 100644 --- a/src/frontend/src/forms/StockForms.tsx +++ b/src/frontend/src/forms/StockForms.tsx @@ -1,3 +1,16 @@ +import { ActionButton } from '@lib/components/ActionButton'; +import { StylishText } from '@lib/components/StylishText'; +import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; +import { ModelType } from '@lib/enums/ModelType'; +import { apiUrl } from '@lib/functions/Api'; +import { getDetailUrl } from '@lib/functions/Navigation'; +import type { + ApiFormAdjustFilterType, + ApiFormFieldChoice, + ApiFormFieldSet, + ApiFormModalProps, + StockOperationProps +} from '@lib/types/Forms'; import { t } from '@lingui/core/macro'; import { Alert, @@ -20,27 +33,13 @@ import { IconUsersGroup } from '@tabler/icons-react'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; -import { type JSX, Suspense, useEffect, useMemo, useState } from 'react'; - -import { ActionButton } from '@lib/components/ActionButton'; -import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; -import { ModelType } from '@lib/enums/ModelType'; import dayjs from 'dayjs'; +import { type JSX, Suspense, useEffect, useMemo, useState } from 'react'; +import { useFormContext } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { api } from '../App'; import RemoveRowButton from '../components/buttons/RemoveRowButton'; import { StandaloneField } from '../components/forms/StandaloneField'; - -import { StylishText } from '@lib/components/StylishText'; -import { apiUrl } from '@lib/functions/Api'; -import { getDetailUrl } from '@lib/functions/Navigation'; -import type { - ApiFormAdjustFilterType, - ApiFormFieldChoice, - ApiFormFieldSet, - ApiFormModalProps, - StockOperationProps -} from '@lib/types/Forms'; import { TableFieldExtraRow, type TableFieldRowProps @@ -490,12 +489,31 @@ function StockItemDefaultMove({ function moveToDefault( stockItem: any, value: StockItemQuantity, - refresh: () => void + refresh: () => void, + options?: { + title?: string; + onConfirm?: (location: number) => void; + } ) { + const location = + stockItem.part_detail?.default_location ?? + stockItem.part_detail?.category_default_location; + modals.openConfirmModal({ - title: {t`Confirm Stock Transfer`}, + title: ( + {options?.title ?? t`Confirm Stock Transfer`} + ), children: , onConfirm: () => { + if (!location) { + return; + } + + if (options?.onConfirm) { + options.onConfirm(location); + return; + } + if ( stockItem.location === stockItem.part_detail?.default_location || stockItem.location === stockItem.part_detail?.category_default_location @@ -512,9 +530,7 @@ function moveToDefault( status: stockItem.status } ], - location: - stockItem.part_detail?.default_location ?? - stockItem.part_detail?.category_default_location + location: location }) .then((response) => { refresh(); @@ -548,6 +564,7 @@ function StockOperationsRow({ add = false, setMax = false, merge = false, + returnStock = false, record }: { props: TableFieldRowProps; @@ -556,8 +573,11 @@ function StockOperationsRow({ add?: boolean; setMax?: boolean; merge?: boolean; + returnStock?: boolean; record?: any; }) { + const form = useFormContext(); + const statusOptions: ApiFormFieldChoice[] = useMemo(() => { return ( StatusFilterOptions(ModelType.stockitem)()?.map((choice) => { @@ -676,7 +696,22 @@ function StockOperationsRow({ {transfer && ( - moveToDefault(record, props.item.quantity, removeAndRefresh) + moveToDefault( + record, + props.item.quantity, + removeAndRefresh, + returnStock + ? { + title: t`Confirm Stock Return`, + onConfirm: (location: number) => { + form.setValue('location', location, { + shouldDirty: true, + shouldValidate: true + }); + } + } + : undefined + ) } icon={} tooltip={t`Move to default location`} @@ -840,6 +875,7 @@ function stockReturnFields(items: any[]): ApiFormFieldSet { key={record.pk} record={record} transfer + returnStock changeStatus /> ); @@ -854,12 +890,25 @@ function stockReturnFields(items: any[]): ApiFormFieldSet { ] }, location: { + field_type: 'related field', + api_url: apiUrl(ApiEndpoints.stock_location_list), + model: ModelType.stocklocation, + required: true, filters: { structural: false } }, - merge: {}, - notes: {} + merge: { + field_type: 'boolean', + label: t`Merge into existing stock`, + description: t`Merge returned items into existing stock items if possible`, + value: false + }, + notes: { + field_type: 'string', + label: t`Notes`, + description: t`Stock transaction notes` + } }; return fields; @@ -1593,11 +1642,7 @@ export function useTestResultFields({ /** * Modal form for finding a particular stock item by serial number */ -export function useFindSerialNumberForm({ - partId -}: { - partId: number; -}) { +export function useFindSerialNumberForm({ partId }: { partId: number }) { const navigate = useNavigate(); return useApiFormModal({