Skip to content

Created by #8848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 7, 2025
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
7 changes: 6 additions & 1 deletion src/backend/InvenTree/InvenTree/api_version.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
"""InvenTree API version information."""

# InvenTree API version
INVENTREE_API_VERSION = 297
INVENTREE_API_VERSION = 298

"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""


INVENTREE_API_TEXT = """

v298 - 2025-01-07 - https://github.com/inventree/InvenTree/pull/8848
- Adds 'created_by' field to PurchaseOrder API endpoints
- Adds 'created_by' field to SalesOrder API endpoints
- Adds 'created_by' field to ReturnOrder API endpoints

v297 - 2024-12-29 - https://github.com/inventree/InvenTree/pull/8438
- Adjustments to the CustomUserState API endpoints and serializers

Expand Down
8 changes: 8 additions & 0 deletions src/backend/InvenTree/order/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from django.conf import settings
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from django.db.models import F, Q
from django.http.response import JsonResponse
from django.urls import include, path, re_path
Expand Down Expand Up @@ -168,6 +169,10 @@ def filter_has_project_code(self, queryset, name, value):
queryset=Owner.objects.all(), field_name='responsible', label=_('Responsible')
)

created_by = rest_filters.ModelChoiceFilter(
queryset=User.objects.all(), field_name='created_by', label=_('Created By')
)

created_before = InvenTreeDateFilter(
label=_('Created Before'), field_name='creation_date', lookup_expr='lt'
)
Expand Down Expand Up @@ -328,6 +333,7 @@ def filter_queryset(self, queryset):

ordering_fields = [
'creation_date',
'created_by',
'reference',
'supplier__name',
'target_date',
Expand Down Expand Up @@ -785,6 +791,7 @@ def filter_queryset(self, queryset):

ordering_fields = [
'creation_date',
'created_by',
'reference',
'customer__name',
'customer_reference',
Expand Down Expand Up @@ -1369,6 +1376,7 @@ class ReturnOrderList(

ordering_fields = [
'creation_date',
'created_by',
'reference',
'customer__name',
'customer_reference',
Expand Down
5 changes: 5 additions & 0 deletions src/backend/InvenTree/order/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
InvenTreeModelSerializer,
InvenTreeMoneySerializer,
NotesFieldMixin,
UserSerializer,
)
from order.status_codes import (
PurchaseOrderStatusGroups,
Expand Down Expand Up @@ -158,6 +159,8 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
required=False, allow_null=True, label=_('Creation Date')
)

created_by = UserSerializer(read_only=True)

duplicate = DuplicateOrderSerializer(
label=_('Duplicate Order'),
help_text=_('Specify options for duplicating this order'),
Expand All @@ -174,6 +177,7 @@ def validate_reference(self, reference):
def annotate_queryset(queryset):
"""Add extra information to the queryset."""
queryset = queryset.annotate(line_items=SubqueryCount('lines'))
queryset = queryset.select_related('created_by')

return queryset

Expand All @@ -183,6 +187,7 @@ def order_fields(extra_fields):
return [
'pk',
'creation_date',
'created_by',
'target_date',
'description',
'line_items',
Expand Down
16 changes: 9 additions & 7 deletions src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
];

Expand All @@ -225,6 +232,7 @@ export default function PurchaseOrderDetail() {
type: 'date',
name: 'creation_date',
label: t`Creation Date`,
copy: true,
icon: 'calendar'
},
{
Expand All @@ -240,6 +248,7 @@ export default function PurchaseOrderDetail() {
name: 'target_date',
label: t`Target Date`,
icon: 'calendar',
copy: true,
hidden: !order.target_date
},
{
Expand All @@ -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
}
];

Expand Down
14 changes: 7 additions & 7 deletions src/frontend/src/pages/sales/ReturnOrderDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
];

Expand Down Expand Up @@ -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
}
];

Expand Down
14 changes: 7 additions & 7 deletions src/frontend/src/pages/sales/SalesOrderDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
];

Expand Down Expand Up @@ -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
}
];

Expand Down
14 changes: 13 additions & 1 deletion src/frontend/src/tables/ColumnRenderers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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',
Expand Down
44 changes: 44 additions & 0 deletions src/frontend/src/tables/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}
49 changes: 21 additions & 28 deletions src/frontend/src/tables/build/BuildOrderTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -32,8 +36,11 @@ import {
HasProjectCodeFilter,
MaxDateFilter,
MinDateFilter,
OrderStatusFilter,
OutstandingFilter,
OverdueFilter,
StatusFilterOptions,
ProjectCodeFilter,
ResponsibleFilter,
type TableFilter,
TargetDateAfterFilter,
TargetDateBeforeFilter
Expand Down Expand Up @@ -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(),
Expand All @@ -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
Expand All @@ -174,7 +162,12 @@ export function BuildOrderTable({
}

return filters;
}, [partId, projectCodeFilters.choices, ownerFilters.choices]);
}, [
partId,
projectCodeFilters.choices,
ownerFilters.choices,
userFilters.choices
]);

const user = useUserState();

Expand Down
Loading
Loading