2
0
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:
Matthias Mair
2025-01-12 04:58:35 +01:00
87 changed files with 40208 additions and 40479 deletions

View File

@ -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`,

View File

@ -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,

View File

@ -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