mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 04:55:44 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into matmair/issue6281
This commit is contained in:
@ -47,6 +47,7 @@ export const getSupportedLanguages = (): Record<string, string> => {
|
||||
ru: t`Russian`,
|
||||
sk: t`Slovak`,
|
||||
sl: t`Slovenian`,
|
||||
sr: t`Serbian`,
|
||||
sv: t`Swedish`,
|
||||
th: t`Thai`,
|
||||
tr: t`Turkish`,
|
||||
|
@ -25,6 +25,8 @@ import {
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { IconCalendarExclamation } from '@tabler/icons-react';
|
||||
import dayjs from 'dayjs';
|
||||
import { api } from '../App';
|
||||
import { ActionButton } from '../components/buttons/ActionButton';
|
||||
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
||||
@ -49,7 +51,7 @@ import {
|
||||
useSerialNumberGenerator
|
||||
} from '../hooks/UseGenerator';
|
||||
import { apiUrl } from '../states/ApiState';
|
||||
|
||||
import { useGlobalSettingsState } from '../states/SettingsState';
|
||||
/*
|
||||
* Construct a set of fields for creating / editing a PurchaseOrderLineItem instance
|
||||
*/
|
||||
@ -246,6 +248,8 @@ function LineItemFormRow({
|
||||
[record]
|
||||
);
|
||||
|
||||
const settings = useGlobalSettingsState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!!record.destination) {
|
||||
props.changeFn(props.idx, 'location', record.destination);
|
||||
@ -298,6 +302,23 @@ function LineItemFormRow({
|
||||
}
|
||||
});
|
||||
|
||||
const [expiryDateOpen, expiryDateHandlers] = useDisclosure(false, {
|
||||
onOpen: () => {
|
||||
// check the default part expiry. Assume expiry is relative to today
|
||||
const defaultExpiry = record.part_detail?.default_expiry;
|
||||
if (defaultExpiry !== undefined && defaultExpiry > 0) {
|
||||
props.changeFn(
|
||||
props.idx,
|
||||
'expiry_date',
|
||||
dayjs().add(defaultExpiry, 'day').format('YYYY-MM-DD')
|
||||
);
|
||||
}
|
||||
},
|
||||
onClose: () => {
|
||||
props.changeFn(props.idx, 'expiry_date', undefined);
|
||||
}
|
||||
});
|
||||
|
||||
// Status value
|
||||
const [statusOpen, statusHandlers] = useDisclosure(false, {
|
||||
onClose: () => props.changeFn(props.idx, 'status', undefined)
|
||||
@ -440,6 +461,16 @@ function LineItemFormRow({
|
||||
tooltipAlignment='top'
|
||||
variant={batchOpen ? 'filled' : 'transparent'}
|
||||
/>
|
||||
{settings.isSet('STOCK_ENABLE_EXPIRY') && (
|
||||
<ActionButton
|
||||
size='sm'
|
||||
onClick={() => expiryDateHandlers.toggle()}
|
||||
icon={<IconCalendarExclamation />}
|
||||
tooltip={t`Set Expiry Date`}
|
||||
tooltipAlignment='top'
|
||||
variant={expiryDateOpen ? 'filled' : 'transparent'}
|
||||
/>
|
||||
)}
|
||||
<ActionButton
|
||||
size='sm'
|
||||
icon={<InvenTreeIcon icon='packaging' />}
|
||||
@ -586,6 +617,21 @@ function LineItemFormRow({
|
||||
}}
|
||||
error={props.rowErrors?.serial_numbers?.message}
|
||||
/>
|
||||
{settings.isSet('STOCK_ENABLE_EXPIRY') && (
|
||||
<TableFieldExtraRow
|
||||
visible={expiryDateOpen}
|
||||
onValueChange={(value) =>
|
||||
props.changeFn(props.idx, 'expiry_date', value)
|
||||
}
|
||||
fieldDefinition={{
|
||||
field_type: 'date',
|
||||
label: t`Expiry Date`,
|
||||
description: t`Enter an expiry date for received items`,
|
||||
value: props.item.expiry_date
|
||||
}}
|
||||
error={props.rowErrors?.expiry_date?.message}
|
||||
/>
|
||||
)}
|
||||
<TableFieldExtraRow
|
||||
visible={packagingOpen}
|
||||
onValueChange={(value) => props.changeFn(props.idx, 'packaging', value)}
|
||||
@ -672,6 +718,7 @@ export function useReceiveLineItems(props: LineItemsForm) {
|
||||
line_item: elem.pk,
|
||||
location: elem.destination ?? elem.destination_detail?.pk ?? null,
|
||||
quantity: elem.quantity - elem.received,
|
||||
expiry_date: null,
|
||||
batch_code: '',
|
||||
serial_numbers: '',
|
||||
status: 10,
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
||||
import { Suspense, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import { api } from '../App';
|
||||
import { ActionButton } from '../components/buttons/ActionButton';
|
||||
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
||||
@ -68,6 +69,8 @@ export function useStockFields({
|
||||
const [nextBatchCode, setNextBatchCode] = useState<string>('');
|
||||
const [nextSerialNumber, setNextSerialNumber] = useState<string>('');
|
||||
|
||||
const [expiryDate, setExpiryDate] = useState<string | null>(null);
|
||||
|
||||
const batchGenerator = useBatchCodeGenerator((value: any) => {
|
||||
if (value) {
|
||||
setNextBatchCode(`${t`Next batch code`}: ${value}`);
|
||||
@ -106,6 +109,14 @@ export function useStockFields({
|
||||
|
||||
// Clear the 'supplier_part' field if the part is changed
|
||||
setSupplierPart(null);
|
||||
|
||||
// Adjust the 'expiry date' for the stock item
|
||||
const expiry_days = record?.default_expiry ?? 0;
|
||||
|
||||
if (expiry_days && expiry_days > 0) {
|
||||
// Adjust the expiry date based on the part default expiry
|
||||
setExpiryDate(dayjs().add(expiry_days, 'days').toISOString());
|
||||
}
|
||||
}
|
||||
},
|
||||
supplier_part: {
|
||||
@ -171,7 +182,11 @@ export function useStockFields({
|
||||
},
|
||||
expiry_date: {
|
||||
icon: <IconCalendarExclamation />,
|
||||
hidden: !globalSettings.isSet('STOCK_ENABLE_EXPIRY')
|
||||
hidden: !globalSettings.isSet('STOCK_ENABLE_EXPIRY'),
|
||||
value: expiryDate,
|
||||
onValueChange: (value) => {
|
||||
setExpiryDate(value);
|
||||
}
|
||||
},
|
||||
purchase_price: {
|
||||
icon: <IconCurrencyDollar />
|
||||
@ -194,9 +209,15 @@ export function useStockFields({
|
||||
// TODO: Handle custom field management based on provided options
|
||||
// TODO: refer to stock.py in original codebase
|
||||
|
||||
// Remove the expiry date field if it is not enabled
|
||||
if (!globalSettings.isSet('STOCK_ENABLE_EXPIRY')) {
|
||||
delete fields.expiry_date;
|
||||
}
|
||||
|
||||
return fields;
|
||||
}, [
|
||||
stockItem,
|
||||
expiryDate,
|
||||
partInstance,
|
||||
partId,
|
||||
globalSettings,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user