2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 20:15:44 +00:00

Created by (#8848)

* Add 'created_by' field to order API endpoints

* Add 'created_by' filter

* Allow ordering by 'created_by' field

* Update UI tables

- Show "Created By" column
- Column sorting
- Column filtering

* Cleanup order detail pages

* Bump API version

* Refactor table filters

* Fix BuildOrderTable filters
This commit is contained in:
Oliver
2025-01-08 10:07:38 +11:00
committed by GitHub
parent 296c54a1d7
commit 9138e31e58
12 changed files with 185 additions and 114 deletions

View File

@ -217,6 +217,13 @@ export default function PurchaseOrderDetail() {
icon: 'reference',
copy: true,
hidden: !order.project_code
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];
@ -225,6 +232,7 @@ export default function PurchaseOrderDetail() {
type: 'date',
name: 'creation_date',
label: t`Creation Date`,
copy: true,
icon: 'calendar'
},
{
@ -240,6 +248,7 @@ export default function PurchaseOrderDetail() {
name: 'target_date',
label: t`Target Date`,
icon: 'calendar',
copy: true,
hidden: !order.target_date
},
{
@ -249,13 +258,6 @@ export default function PurchaseOrderDetail() {
label: t`Completion Date`,
copy: true,
hidden: !order.complete_date
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];

View File

@ -187,6 +187,13 @@ export default function ReturnOrderDetail() {
icon: 'reference',
copy: true,
hidden: !order.project_code
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];
@ -221,13 +228,6 @@ export default function ReturnOrderDetail() {
label: t`Completion Date`,
copy: true,
hidden: !order.complete_date
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];

View File

@ -199,6 +199,13 @@ export default function SalesOrderDetail() {
icon: 'reference',
copy: true,
hidden: !order.project_code
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];
@ -231,13 +238,6 @@ export default function SalesOrderDetail() {
label: t`Completion Date`,
hidden: !order.shipment_date,
copy: true
},
{
type: 'text',
name: 'responsible',
label: t`Responsible`,
badge: 'owner',
hidden: !order.responsible
}
];

View File

@ -9,7 +9,7 @@ import { YesNoButton } from '../components/buttons/YesNoButton';
import { Thumbnail } from '../components/images/Thumbnail';
import { ProgressBar } from '../components/items/ProgressBar';
import { TableStatusRenderer } from '../components/render/StatusRenderer';
import { RenderOwner } from '../components/render/User';
import { RenderOwner, RenderUser } from '../components/render/User';
import { formatCurrency, formatDate } from '../defaults/formatters';
import type { ModelType } from '../enums/ModelType';
import { resolveItem } from '../functions/conversion';
@ -202,6 +202,18 @@ export function StatusColumn({
};
}
export function CreatedByColumn(props: TableColumnProps): TableColumn {
return {
accessor: 'created_by',
title: t`Created By`,
sortable: true,
switchable: true,
render: (record: any) =>
record.created_by && RenderUser({ instance: record.created_by }),
...props
};
}
export function ResponsibleColumn(props: TableColumnProps): TableColumn {
return {
accessor: 'responsible',

View File

@ -205,3 +205,47 @@ export function HasProjectCodeFilter(): TableFilter {
description: t`Show orders with an assigned project code`
};
}
export function OrderStatusFilter({
model
}: { model: ModelType }): TableFilter {
return {
name: 'status',
label: t`Status`,
description: t`Filter by order status`,
choiceFunction: StatusFilterOptions(model)
};
}
export function ProjectCodeFilter({
choices
}: { choices: TableFilterChoice[] }): TableFilter {
return {
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
choices: choices
};
}
export function ResponsibleFilter({
choices
}: { choices: TableFilterChoice[] }): TableFilter {
return {
name: 'assigned_to',
label: t`Responsible`,
description: t`Filter by responsible owner`,
choices: choices
};
}
export function CreatedByFilter({
choices
}: { choices: TableFilterChoice[] }): TableFilter {
return {
name: 'created_by',
label: t`Created By`,
description: t`Filter by user who created the order`,
choices: choices
};
}

View File

@ -8,7 +8,11 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { useBuildOrderFields } from '../../forms/BuildForms';
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
import {
useOwnerFilters,
useProjectCodeFilters,
useUserFilters
} from '../../hooks/UseFilter';
import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
@ -32,8 +36,11 @@ import {
HasProjectCodeFilter,
MaxDateFilter,
MinDateFilter,
OrderStatusFilter,
OutstandingFilter,
OverdueFilter,
StatusFilterOptions,
ProjectCodeFilter,
ResponsibleFilter,
type TableFilter,
TargetDateAfterFilter,
TargetDateBeforeFilter
@ -117,21 +124,12 @@ export function BuildOrderTable({
const projectCodeFilters = useProjectCodeFilters();
const ownerFilters = useOwnerFilters();
const userFilters = useUserFilters();
const tableFilters: TableFilter[] = useMemo(() => {
const filters: TableFilter[] = [
{
name: 'outstanding',
type: 'boolean',
label: t`Outstanding`,
description: t`Show outstanding orders`
},
{
name: 'status',
label: t`Status`,
description: t`Filter by order status`,
choiceFunction: StatusFilterOptions(ModelType.build)
},
OutstandingFilter(),
OrderStatusFilter({ model: ModelType.build }),
OverdueFilter(),
AssignedToMeFilter(),
MinDateFilter(),
@ -142,25 +140,15 @@ export function BuildOrderTable({
TargetDateAfterFilter(),
CompletedBeforeFilter(),
CompletedAfterFilter(),
{
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
choices: projectCodeFilters.choices
},
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
HasProjectCodeFilter(),
{
name: 'issued_by',
label: t`Issued By`,
description: t`Filter by user who issued this order`,
choices: ownerFilters.choices
choices: userFilters.choices
},
{
name: 'assigned_to',
label: t`Responsible`,
description: t`Filter by responsible owner`,
choices: ownerFilters.choices
}
ResponsibleFilter({ choices: ownerFilters.choices })
];
// If we are filtering on a specific part, we can include the "include variants" filter
@ -174,7 +162,12 @@ export function BuildOrderTable({
}
return filters;
}, [partId, projectCodeFilters.choices, ownerFilters.choices]);
}, [
partId,
projectCodeFilters.choices,
ownerFilters.choices,
userFilters.choices
]);
const user = useUserState();

View File

@ -8,13 +8,18 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { usePurchaseOrderFields } from '../../forms/PurchaseOrderForms';
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
import {
useOwnerFilters,
useProjectCodeFilters,
useUserFilters
} from '../../hooks/UseFilter';
import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState';
import {
CompletionDateColumn,
CreatedByColumn,
CreationDateColumn,
DescriptionColumn,
LineItemsProgressColumn,
@ -30,12 +35,15 @@ import {
CompletedBeforeFilter,
CreatedAfterFilter,
CreatedBeforeFilter,
CreatedByFilter,
HasProjectCodeFilter,
MaxDateFilter,
MinDateFilter,
OrderStatusFilter,
OutstandingFilter,
OverdueFilter,
StatusFilterOptions,
ProjectCodeFilter,
ResponsibleFilter,
type TableFilter,
TargetDateAfterFilter,
TargetDateBeforeFilter
@ -57,15 +65,11 @@ export function PurchaseOrderTable({
const projectCodeFilters = useProjectCodeFilters();
const responsibleFilters = useOwnerFilters();
const createdByFilters = useUserFilters();
const tableFilters: TableFilter[] = useMemo(() => {
return [
{
name: 'status',
label: t`Status`,
description: t`Filter by order status`,
choiceFunction: StatusFilterOptions(ModelType.purchaseorder)
},
OrderStatusFilter({ model: ModelType.purchaseorder }),
OutstandingFilter(),
OverdueFilter(),
AssignedToMeFilter(),
@ -77,21 +81,16 @@ export function PurchaseOrderTable({
TargetDateAfterFilter(),
CompletedBeforeFilter(),
CompletedAfterFilter(),
{
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
choices: projectCodeFilters.choices
},
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
HasProjectCodeFilter(),
{
name: 'assigned_to',
label: t`Responsible`,
description: t`Filter by responsible owner`,
choices: responsibleFilters.choices
}
ResponsibleFilter({ choices: responsibleFilters.choices }),
CreatedByFilter({ choices: createdByFilters.choices })
];
}, [projectCodeFilters.choices, responsibleFilters.choices]);
}, [
projectCodeFilters.choices,
responsibleFilters.choices,
createdByFilters.choices
]);
const tableColumns = useMemo(() => {
return [
@ -120,6 +119,7 @@ export function PurchaseOrderTable({
StatusColumn({ model: ModelType.purchaseorder }),
ProjectCodeColumn({}),
CreationDateColumn({}),
CreatedByColumn({}),
TargetDateColumn({}),
CompletionDateColumn({
accessor: 'complete_date'

View File

@ -8,13 +8,18 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { useReturnOrderFields } from '../../forms/ReturnOrderForms';
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
import {
useOwnerFilters,
useProjectCodeFilters,
useUserFilters
} from '../../hooks/UseFilter';
import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState';
import {
CompletionDateColumn,
CreatedByColumn,
CreationDateColumn,
DescriptionColumn,
LineItemsProgressColumn,
@ -30,12 +35,15 @@ import {
CompletedBeforeFilter,
CreatedAfterFilter,
CreatedBeforeFilter,
CreatedByFilter,
HasProjectCodeFilter,
MaxDateFilter,
MinDateFilter,
OrderStatusFilter,
OutstandingFilter,
OverdueFilter,
StatusFilterOptions,
ProjectCodeFilter,
ResponsibleFilter,
type TableFilter,
TargetDateAfterFilter,
TargetDateBeforeFilter
@ -54,15 +62,11 @@ export function ReturnOrderTable({
const projectCodeFilters = useProjectCodeFilters();
const responsibleFilters = useOwnerFilters();
const createdByFilters = useUserFilters();
const tableFilters: TableFilter[] = useMemo(() => {
const filters: TableFilter[] = [
{
name: 'status',
label: t`Status`,
description: t`Filter by order status`,
choiceFunction: StatusFilterOptions(ModelType.returnorder)
},
OrderStatusFilter({ model: ModelType.returnorder }),
OutstandingFilter(),
OverdueFilter(),
AssignedToMeFilter(),
@ -74,19 +78,10 @@ export function ReturnOrderTable({
TargetDateAfterFilter(),
CompletedBeforeFilter(),
CompletedAfterFilter(),
{
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
choices: projectCodeFilters.choices
},
HasProjectCodeFilter(),
{
name: 'assigned_to',
label: t`Responsible`,
description: t`Filter by responsible owner`,
choices: responsibleFilters.choices
}
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
ResponsibleFilter({ choices: responsibleFilters.choices }),
CreatedByFilter({ choices: createdByFilters.choices })
];
if (!!partId) {
@ -99,7 +94,12 @@ export function ReturnOrderTable({
}
return filters;
}, [partId, projectCodeFilters.choices, responsibleFilters.choices]);
}, [
partId,
projectCodeFilters.choices,
responsibleFilters.choices,
createdByFilters.choices
]);
const tableColumns = useMemo(() => {
return [
@ -128,6 +128,7 @@ export function ReturnOrderTable({
StatusColumn({ model: ModelType.returnorder }),
ProjectCodeColumn({}),
CreationDateColumn({}),
CreatedByColumn({}),
TargetDateColumn({}),
CompletionDateColumn({
accessor: 'complete_date'

View File

@ -9,12 +9,17 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { useSalesOrderFields } from '../../forms/SalesOrderForms';
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
import {
useOwnerFilters,
useProjectCodeFilters,
useUserFilters
} from '../../hooks/UseFilter';
import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState';
import {
CreatedByColumn,
CreationDateColumn,
DescriptionColumn,
LineItemsProgressColumn,
@ -31,12 +36,15 @@ import {
CompletedBeforeFilter,
CreatedAfterFilter,
CreatedBeforeFilter,
CreatedByFilter,
HasProjectCodeFilter,
MaxDateFilter,
MinDateFilter,
OrderStatusFilter,
OutstandingFilter,
OverdueFilter,
StatusFilterOptions,
ProjectCodeFilter,
ResponsibleFilter,
type TableFilter,
TargetDateAfterFilter,
TargetDateBeforeFilter
@ -55,15 +63,11 @@ export function SalesOrderTable({
const projectCodeFilters = useProjectCodeFilters();
const responsibleFilters = useOwnerFilters();
const createdByFilters = useUserFilters();
const tableFilters: TableFilter[] = useMemo(() => {
const filters: TableFilter[] = [
{
name: 'status',
label: t`Status`,
description: t`Filter by order status`,
choiceFunction: StatusFilterOptions(ModelType.salesorder)
},
OrderStatusFilter({ model: ModelType.salesorder }),
OutstandingFilter(),
OverdueFilter(),
AssignedToMeFilter(),
@ -75,19 +79,10 @@ export function SalesOrderTable({
TargetDateAfterFilter(),
CompletedBeforeFilter(),
CompletedAfterFilter(),
{
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
choices: projectCodeFilters.choices
},
HasProjectCodeFilter(),
{
name: 'assigned_to',
label: t`Responsible`,
description: t`Filter by responsible owner`,
choices: responsibleFilters.choices
}
ProjectCodeFilter({ choices: projectCodeFilters.choices }),
ResponsibleFilter({ choices: responsibleFilters.choices }),
CreatedByFilter({ choices: createdByFilters.choices })
];
if (!!partId) {
@ -100,7 +95,12 @@ export function SalesOrderTable({
}
return filters;
}, [partId, projectCodeFilters.choices, responsibleFilters.choices]);
}, [
partId,
projectCodeFilters.choices,
responsibleFilters.choices,
createdByFilters.choices
]);
const salesOrderFields = useSalesOrderFields({});
@ -165,6 +165,7 @@ export function SalesOrderTable({
StatusColumn({ model: ModelType.salesorder }),
ProjectCodeColumn({}),
CreationDateColumn({}),
CreatedByColumn({}),
TargetDateColumn({}),
ShipmentDateColumn({}),
ResponsibleColumn({}),