diff --git a/.github/workflows/check_translations.yaml b/.github/workflows/check_translations.yaml
index d16bff66f3..e41cc7befe 100644
--- a/.github/workflows/check_translations.yaml
+++ b/.github/workflows/check_translations.yaml
@@ -31,7 +31,7 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml
index 166246ba65..9e839da766 100644
--- a/.github/workflows/docker.yaml
+++ b/.github/workflows/docker.yaml
@@ -39,7 +39,7 @@ jobs:
docker: ${{ steps.filter.outputs.docker }}
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2
@@ -67,7 +67,7 @@ jobs:
steps:
- name: Check out repo
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Test Docker Image
@@ -129,7 +129,7 @@ jobs:
steps:
- name: Check out repo
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Run Migration Tests
@@ -153,7 +153,7 @@ jobs:
steps:
- name: Check out repo
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Set Up Python ${{ env.python_version }}
diff --git a/.github/workflows/qc_checks.yaml b/.github/workflows/qc_checks.yaml
index 5c499d1b3b..a31940943f 100644
--- a/.github/workflows/qc_checks.yaml
+++ b/.github/workflows/qc_checks.yaml
@@ -41,7 +41,7 @@ jobs:
requirements: ${{ steps.filter.outputs.requirements }}
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2
@@ -82,7 +82,7 @@ jobs:
if: needs.paths-filter.outputs.cicd == 'true' || needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.requirements == 'true' || needs.paths-filter.outputs.force == 'true'
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Set up Python ${{ env.python_version }}
@@ -104,7 +104,7 @@ jobs:
if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.requirements == 'true' || needs.paths-filter.outputs.force == 'true'
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -126,7 +126,7 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Set up Python ${{ env.python_version }}
@@ -164,7 +164,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -249,7 +249,7 @@ jobs:
version: ${{ needs.schema.outputs.version }}
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
name: Checkout Code
with:
repository: inventree/schema
@@ -302,7 +302,7 @@ jobs:
INVENTREE_LOG_LEVEL: WARNING
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: true
- name: Environment Setup
@@ -346,7 +346,7 @@ jobs:
python_version: ${{ matrix.python_version }}
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -410,7 +410,7 @@ jobs:
- 6379:6379
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -458,7 +458,7 @@ jobs:
- 3306:3306
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -500,7 +500,7 @@ jobs:
- 5432:5432
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -534,7 +534,7 @@ jobs:
INVENTREE_PLUGINS_ENABLED: false
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
name: Checkout Code
@@ -613,7 +613,7 @@ jobs:
VITE_COVERAGE_BUILD: true
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -663,7 +663,7 @@ jobs:
timeout-minutes: 60
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -696,7 +696,7 @@ jobs:
security-events: write
steps:
- name: Checkout repository
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- uses: hynek/setup-cached-uv@757bedc3f972eb7227a1aa657651f15a8527c817 # pin@v2
@@ -705,7 +705,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
- uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # pin@v3
+ uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # pin@v3
with:
sarif_file: results.sarif
category: zizmor
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 00f20bb4a1..fb8161dc80 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -20,7 +20,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout Code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Version Check
@@ -43,7 +43,7 @@ jobs:
contents: write
attestations: write
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -55,7 +55,7 @@ jobs:
- name: Build frontend
run: cd src/frontend && npm run compile && npm run build
- name: Create SBOM for frontend
- uses: anchore/sbom-action@8e94d75ddd33f69f691467e42275782e4bfefe84 # pin@v0
+ uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # pin@v0
with:
artifact-name: frontend-build.spdx
path: src/frontend
@@ -76,7 +76,7 @@ jobs:
subject-path: "${{ github.workspace }}/src/backend/InvenTree/web/static/frontend-build.zip"
- name: Upload frontend
- uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # pin@2.11.2
+ uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: src/backend/InvenTree/web/static/frontend-build.zip
@@ -84,7 +84,7 @@ jobs:
tag: ${{ github.ref }}
overwrite: true
- name: Upload Attestation
- uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # pin@2.11.2
+ uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
asset_name: frontend-build.intoto.jsonl
@@ -107,7 +107,7 @@ jobs:
INVENTREE_DEBUG: true
steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: false
- name: Environment Setup
@@ -127,7 +127,7 @@ jobs:
cd docs/site
zip -r docs-html.zip *
- name: Publish documentation
- uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # pin@2.11.2
+ uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: docs/site/docs-html.zip
diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml
index 8925802f8f..ddfb5c3f3e 100644
--- a/.github/workflows/scorecard.yaml
+++ b/.github/workflows/scorecard.yaml
@@ -32,7 +32,7 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
@@ -67,6 +67,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
+ uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5
with:
sarif_file: results.sarif
diff --git a/.github/workflows/translations.yaml b/.github/workflows/translations.yaml
index f27dc5932c..2da438acd6 100644
--- a/.github/workflows/translations.yaml
+++ b/.github/workflows/translations.yaml
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # pin@v5.0.0
+ uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # pin@v6.0.0
with:
persist-credentials: true
- name: Environment Setup
diff --git a/src/backend/InvenTree/InvenTree/api.py b/src/backend/InvenTree/InvenTree/api.py
index 195972ff20..cd57fb1cc2 100644
--- a/src/backend/InvenTree/InvenTree/api.py
+++ b/src/backend/InvenTree/InvenTree/api.py
@@ -603,8 +603,6 @@ class BulkUpdateMixin(BulkOperationMixin):
class ParameterListMixin:
"""Mixin class which supports filtering against parametric fields."""
- parameter_model_class = None
-
def filter_queryset(self, queryset):
"""Perform filtering against parametric fields."""
import common.filters
@@ -616,11 +614,15 @@ class ParameterListMixin:
queryset, self.request.query_params
)
+ serializer_class = (
+ getattr(self, 'serializer_class', None) or self.get_serializer_class()
+ )
+
+ model_class = serializer_class.Meta.model
+
# Apply ordering based on query parameter
queryset = common.filters.order_by_parameter(
- queryset,
- self.parameter_model_class,
- self.request.query_params.get('ordering', None),
+ queryset, model_class, self.request.query_params.get('ordering', None)
)
return queryset
diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py
index 8805377140..5e1901f58a 100644
--- a/src/backend/InvenTree/build/api.py
+++ b/src/backend/InvenTree/build/api.py
@@ -349,7 +349,6 @@ class BuildList(
- POST: Create a new Build object
"""
- parameter_model_class = Build
output_options = BuildListOutputOptions
filterset_class = BuildFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py
index 0c3fe8878a..7ee07f7175 100644
--- a/src/backend/InvenTree/common/models.py
+++ b/src/backend/InvenTree/common/models.py
@@ -2442,7 +2442,7 @@ class ParameterTemplate(
choice_set.add(choice)
def validate_unique(self, exclude=None):
- """Ensure that PartParameterTemplates cannot be created with the same name.
+ """Ensure that ParameterTemplates cannot be created with the same name.
This test should be case-insensitive (which the unique caveat does not cover).
"""
diff --git a/src/backend/InvenTree/company/api.py b/src/backend/InvenTree/company/api.py
index f1ca50f439..15406ca71a 100644
--- a/src/backend/InvenTree/company/api.py
+++ b/src/backend/InvenTree/company/api.py
@@ -60,7 +60,6 @@ class CompanyList(CompanyMixin, ParameterListMixin, DataExportViewMixin, ListCre
- POST: Create a new Company object
"""
- parameter_model_class = Company
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
@@ -201,7 +200,6 @@ class ManufacturerPartList(
- POST: Create a new ManufacturerPart object
"""
- parameter_model_class = ManufacturerPart
filterset_class = ManufacturerPartFilter
filter_backends = SEARCH_ORDER_FILTER
output_options = ManufacturerOutputOptions
@@ -352,7 +350,6 @@ class SupplierPartList(
- POST: Create a new SupplierPart object
"""
- parameter_model_class = SupplierPart
filterset_class = SupplierPartFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = SupplierPartOutputOptions
diff --git a/src/backend/InvenTree/order/api.py b/src/backend/InvenTree/order/api.py
index 0609ab365a..ee2fa7a4c9 100644
--- a/src/backend/InvenTree/order/api.py
+++ b/src/backend/InvenTree/order/api.py
@@ -392,7 +392,6 @@ class PurchaseOrderList(
- POST: Create a new PurchaseOrder object
"""
- parameter_model_class = models.PurchaseOrder
filterset_class = PurchaseOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = PurchaseOrderOutputOptions
@@ -863,7 +862,6 @@ class SalesOrderList(
- POST: Create a new SalesOrder
"""
- parameter_model_class = models.SalesOrder
filterset_class = SalesOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = SalesOrderOutputOptions
@@ -1537,7 +1535,6 @@ class ReturnOrderList(
):
"""API endpoint for accessing a list of ReturnOrder objects."""
- parameter_model_class = models.ReturnOrder
filterset_class = ReturnOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
diff --git a/src/backend/InvenTree/part/api.py b/src/backend/InvenTree/part/api.py
index b161e0114c..57fcc7cb85 100644
--- a/src/backend/InvenTree/part/api.py
+++ b/src/backend/InvenTree/part/api.py
@@ -1076,7 +1076,6 @@ class PartList(
):
"""API endpoint for accessing a list of Part objects, or creating a new Part instance."""
- parameter_model_class = Part
output_options = PartOutputOptions
filterset_class = PartFilter
is_create = True
diff --git a/src/backend/InvenTree/users/ruleset.py b/src/backend/InvenTree/users/ruleset.py
index 3995dc2383..7beb4f1eec 100644
--- a/src/backend/InvenTree/users/ruleset.py
+++ b/src/backend/InvenTree/users/ruleset.py
@@ -40,7 +40,7 @@ RULESET_NAMES = [choice[0] for choice in RULESET_CHOICES]
# Permission types available for each ruleset.
RULESET_PERMISSIONS = ['view', 'add', 'change', 'delete']
-RULESET_CHANGE_INHERIT = [('part', 'partparameter'), ('part', 'bomitem')]
+RULESET_CHANGE_INHERIT = [('part', 'bomitem')]
def get_ruleset_models() -> dict:
diff --git a/src/backend/requirements.txt b/src/backend/requirements.txt
index 9d26df6989..bfaeac6648 100644
--- a/src/backend/requirements.txt
+++ b/src/backend/requirements.txt
@@ -1482,9 +1482,9 @@ pynacl==1.6.0 \
--hash=sha256:f46386c24a65383a9081d68e9c2de909b1834ec74ff3013271f1bca9c2d233eb \
--hash=sha256:f4b3824920e206b4f52abd7de621ea7a44fd3cb5c8daceb7c3612345dfc54f2e
# via paramiko
-pypdf==6.3.0 \
- --hash=sha256:2d5f9741e851e378908692d571374b3cbd94582fdd1c740fcf7c029ec35ac0e6 \
- --hash=sha256:d066a2fdf8195e1811ae5a9d5a2f97f5bed0e1e7954297295eadee6357e76c5d
+pypdf==6.4.0 \
+ --hash=sha256:4769d471f8ddc3341193ecc5d6560fa44cf8cd0abfabf21af4e195cc0c224072 \
+ --hash=sha256:55ab9837ed97fd7fcc5c131d52fcc2223bc5c6b8a1488bbf7c0e27f1f0023a79
# via -r src/backend/requirements.in
pyphen==0.17.2 \
--hash=sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd \
diff --git a/src/frontend/src/forms/SalesOrderForms.tsx b/src/frontend/src/forms/SalesOrderForms.tsx
index 36a0963e7f..7550534dc0 100644
--- a/src/frontend/src/forms/SalesOrderForms.tsx
+++ b/src/frontend/src/forms/SalesOrderForms.tsx
@@ -1,8 +1,10 @@
import { t } from '@lingui/core/macro';
-import { Table } from '@mantine/core';
+import { Alert, Table, Text } from '@mantine/core';
import {
IconAddressBook,
IconCalendar,
+ IconCircleCheck,
+ IconCircleX,
IconCoins,
IconUser,
IconUsers
@@ -23,8 +25,9 @@ import type {
ApiFormFieldType
} from '@lib/types/Forms';
import type { TableFieldRowProps } from '../components/forms/fields/TableField';
-import { useCreateApiFormModal } from '../hooks/UseForm';
+import { useCreateApiFormModal, useEditApiFormModal } from '../hooks/UseForm';
import { useGlobalSettingsState } from '../states/SettingsStates';
+import { useUserState } from '../states/UserState';
import { RenderPartColumn } from '../tables/ColumnRenderers';
export function useSalesOrderFields({
@@ -190,6 +193,64 @@ export function useSalesOrderLineItemFields({
}, [salePrice, partCurrency, orderId, create]);
}
+export function useCheckShipmentForm({
+ shipmentId,
+ onSuccess
+}: {
+ shipmentId: number;
+ onSuccess: (response: any) => void;
+}) {
+ const user = useUserState();
+
+ return useEditApiFormModal({
+ url: ApiEndpoints.sales_order_shipment_list,
+ pk: shipmentId,
+ title: t`Check Shipment`,
+ preFormContent: (
+ } title={t`Check Shipment`}>
+ {t`Marking the shipment as checked indicates that you have verified that all items included in this shipment are correct`}
+
+ ),
+ fetchInitialData: false,
+ fields: {
+ checked_by: {
+ hidden: true,
+ value: user.getUser()?.pk
+ }
+ },
+ successMessage: t`Shipment marked as checked`,
+ onFormSuccess: onSuccess
+ });
+}
+
+export function useUncheckShipmentForm({
+ shipmentId,
+ onSuccess
+}: {
+ shipmentId: number;
+ onSuccess: (response: any) => void;
+}) {
+ return useEditApiFormModal({
+ url: ApiEndpoints.sales_order_shipment_list,
+ pk: shipmentId,
+ title: t`Uncheck Shipment`,
+ preFormContent: (
+ } title={t`Uncheck Shipment`}>
+ {t`Marking the shipment as unchecked indicates that the shipment requires further verification`}
+
+ ),
+ fetchInitialData: false,
+ fields: {
+ checked_by: {
+ hidden: true,
+ value: null
+ }
+ },
+ successMessage: t`Shipment marked as unchecked`,
+ onFormSuccess: onSuccess
+ });
+}
+
function SalesOrderAllocateLineRow({
props,
record,
diff --git a/src/frontend/src/pages/build/BuildIndex.tsx b/src/frontend/src/pages/build/BuildIndex.tsx
index 7ad932d08b..2b8f4e681c 100644
--- a/src/frontend/src/pages/build/BuildIndex.tsx
+++ b/src/frontend/src/pages/build/BuildIndex.tsx
@@ -1,6 +1,11 @@
import { t } from '@lingui/core/macro';
import { Stack } from '@mantine/core';
-import { IconCalendar, IconTable, IconTools } from '@tabler/icons-react';
+import {
+ IconCalendar,
+ IconListDetails,
+ IconTable,
+ IconTools
+} from '@tabler/icons-react';
import { useMemo } from 'react';
import { ModelType } from '@lib/enums/ModelType';
@@ -16,6 +21,7 @@ import SegmentedControlPanel from '../../components/panels/SegmentedControlPanel
import { useGlobalSettingsState } from '../../states/SettingsStates';
import { useUserState } from '../../states/UserState';
import { PartCategoryFilter } from '../../tables/Filter';
+import BuildOrderParametricTable from '../../tables/build/BuildOrderParametricTable';
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
function BuildOrderCalendar() {
@@ -74,6 +80,12 @@ export default function BuildIndex() {
label: t`Calendar View`,
icon: ,
content:
+ },
+ {
+ value: 'parametric',
+ label: t`Parametric View`,
+ icon: ,
+ content:
}
]
})
diff --git a/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx b/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
index 3353b44278..153933dac9 100644
--- a/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
+++ b/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
@@ -1,5 +1,5 @@
import { t } from '@lingui/core/macro';
-import { Alert, Grid, Skeleton, Stack, Text } from '@mantine/core';
+import { Grid, Skeleton, Stack, Text } from '@mantine/core';
import {
IconBookmark,
IconCircleCheck,
@@ -39,8 +39,10 @@ import { RenderAddress } from '../../components/render/Company';
import { RenderUser } from '../../components/render/User';
import { formatDate } from '../../defaults/formatters';
import {
+ useCheckShipmentForm,
useSalesOrderShipmentCompleteFields,
- useSalesOrderShipmentFields
+ useSalesOrderShipmentFields,
+ useUncheckShipmentForm
} from '../../forms/SalesOrderForms';
import {
useCreateApiFormModal,
@@ -320,44 +322,14 @@ export default function SalesOrderShipmentDetail() {
onFormSuccess: refreshShipment
});
- const checkShipment = useEditApiFormModal({
- url: ApiEndpoints.sales_order_shipment_list,
- pk: shipment.pk,
- title: t`Check Shipment`,
- preFormContent: (
- } title={t`Check Shipment`}>
- {t`Marking the shipment as checked indicates that you have verified that all items included in this shipment are correct`}
-
- ),
- fetchInitialData: false,
- fields: {
- checked_by: {
- hidden: true,
- value: userId
- }
- },
- successMessage: t`Shipment marked as checked`,
- onFormSuccess: refreshShipment
+ const checkShipment = useCheckShipmentForm({
+ shipmentId: shipment.pk,
+ onSuccess: refreshShipment
});
- const uncheckShipment = useEditApiFormModal({
- url: ApiEndpoints.sales_order_shipment_list,
- pk: shipment.pk,
- title: t`Uncheck Shipment`,
- preFormContent: (
- } title={t`Uncheck Shipment`}>
- {t`Marking the shipment as unchecked indicates that the shipment requires further verification`}
-
- ),
- fetchInitialData: false,
- fields: {
- checked_by: {
- hidden: true,
- value: null
- }
- },
- successMessage: t`Shipment marked as unchecked`,
- onFormSuccess: refreshShipment
+ const uncheckShipment = useUncheckShipmentForm({
+ shipmentId: shipment.pk,
+ onSuccess: refreshShipment
});
const shipmentBadges = useMemo(() => {
diff --git a/src/frontend/src/tables/build/BuildOrderParametricTable.tsx b/src/frontend/src/tables/build/BuildOrderParametricTable.tsx
new file mode 100644
index 0000000000..d9f85cb295
--- /dev/null
+++ b/src/frontend/src/tables/build/BuildOrderParametricTable.tsx
@@ -0,0 +1,40 @@
+import { ApiEndpoints, ModelType } from '@lib/index';
+import type { TableFilter } from '@lib/types/Filters';
+import type { TableColumn } from '@lib/types/Tables';
+import { type ReactNode, useMemo } from 'react';
+import { DescriptionColumn, ReferenceColumn } from '../ColumnRenderers';
+import { OrderStatusFilter, OutstandingFilter } from '../Filter';
+import ParametricDataTable from '../general/ParametricDataTable';
+
+export default function BuildOrderParametricTable({
+ queryParams
+}: {
+ queryParams?: Record;
+}): ReactNode {
+ const customColumns: TableColumn[] = useMemo(() => {
+ return [
+ ReferenceColumn({
+ switchable: false
+ }),
+ DescriptionColumn({
+ accessor: 'title'
+ })
+ ];
+ }, []);
+
+ const customFilters: TableFilter[] = useMemo(() => {
+ return [OutstandingFilter(), OrderStatusFilter({ model: ModelType.build })];
+ }, []);
+
+ return (
+
+ );
+}
diff --git a/src/frontend/src/tables/purchasing/PurchaseOrderParametricTable.tsx b/src/frontend/src/tables/purchasing/PurchaseOrderParametricTable.tsx
index 0beaef6072..10ae5d00c3 100644
--- a/src/frontend/src/tables/purchasing/PurchaseOrderParametricTable.tsx
+++ b/src/frontend/src/tables/purchasing/PurchaseOrderParametricTable.tsx
@@ -4,7 +4,11 @@ import type { TableFilter } from '@lib/types/Filters';
import type { TableColumn } from '@lib/types/Tables';
import { t } from '@lingui/core/macro';
import { type ReactNode, useMemo } from 'react';
-import { CompanyColumn, ReferenceColumn } from '../ColumnRenderers';
+import {
+ CompanyColumn,
+ DescriptionColumn,
+ ReferenceColumn
+} from '../ColumnRenderers';
import {
AssignedToMeFilter,
OrderStatusFilter,
@@ -22,7 +26,9 @@ export default function PurchaseOrderParametricTable({
}): ReactNode {
const customColumns: TableColumn[] = useMemo(() => {
return [
- ReferenceColumn({}),
+ ReferenceColumn({
+ switchable: false
+ }),
{
accessor: 'supplier__name',
title: t`Supplier`,
@@ -30,7 +36,8 @@ export default function PurchaseOrderParametricTable({
render: (record: any) => (
)
- }
+ },
+ DescriptionColumn({})
];
}, []);
diff --git a/src/frontend/src/tables/sales/ReturnOrderParametricTable.tsx b/src/frontend/src/tables/sales/ReturnOrderParametricTable.tsx
index eef91d201e..d69d88c545 100644
--- a/src/frontend/src/tables/sales/ReturnOrderParametricTable.tsx
+++ b/src/frontend/src/tables/sales/ReturnOrderParametricTable.tsx
@@ -4,7 +4,11 @@ import type { TableFilter } from '@lib/types/Filters';
import type { TableColumn } from '@lib/types/Tables';
import { t } from '@lingui/core/macro';
import { type ReactNode, useMemo } from 'react';
-import { CompanyColumn, ReferenceColumn } from '../ColumnRenderers';
+import {
+ CompanyColumn,
+ DescriptionColumn,
+ ReferenceColumn
+} from '../ColumnRenderers';
import {
AssignedToMeFilter,
OrderStatusFilter,
@@ -22,7 +26,7 @@ export default function ReturnOrderParametricTable({
}): ReactNode {
const customColumns: TableColumn[] = useMemo(() => {
return [
- ReferenceColumn({}),
+ ReferenceColumn({ switchable: false }),
{
accessor: 'customer__name',
title: t`Customer`,
@@ -30,7 +34,8 @@ export default function ReturnOrderParametricTable({
render: (record: any) => (
)
- }
+ },
+ DescriptionColumn({})
];
}, []);
diff --git a/src/frontend/src/tables/sales/SalesOrderParametricTable.tsx b/src/frontend/src/tables/sales/SalesOrderParametricTable.tsx
index fce8aadc28..404c037b9c 100644
--- a/src/frontend/src/tables/sales/SalesOrderParametricTable.tsx
+++ b/src/frontend/src/tables/sales/SalesOrderParametricTable.tsx
@@ -4,7 +4,11 @@ import type { TableFilter } from '@lib/types/Filters';
import type { TableColumn } from '@lib/types/Tables';
import { t } from '@lingui/core/macro';
import { type ReactNode, useMemo } from 'react';
-import { CompanyColumn, ReferenceColumn } from '../ColumnRenderers';
+import {
+ CompanyColumn,
+ DescriptionColumn,
+ ReferenceColumn
+} from '../ColumnRenderers';
import {
AssignedToMeFilter,
OrderStatusFilter,
@@ -22,7 +26,7 @@ export default function SalesOrderParametricTable({
}): ReactNode {
const customColumns: TableColumn[] = useMemo(() => {
return [
- ReferenceColumn({}),
+ ReferenceColumn({ switchable: false }),
{
accessor: 'customer__name',
title: t`Customer`,
@@ -30,7 +34,8 @@ export default function SalesOrderParametricTable({
render: (record: any) => (
)
- }
+ },
+ DescriptionColumn({})
];
}, []);
diff --git a/src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx b/src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx
index 7834c79e4c..1727cad418 100644
--- a/src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx
+++ b/src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx
@@ -1,5 +1,9 @@
import { t } from '@lingui/core/macro';
-import { IconTruckDelivery } from '@tabler/icons-react';
+import {
+ IconCircleCheck,
+ IconCircleX,
+ IconTruckDelivery
+} from '@tabler/icons-react';
import { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
@@ -19,8 +23,10 @@ import type { TableFilter } from '@lib/types/Filters';
import type { TableColumn } from '@lib/types/Tables';
import dayjs from 'dayjs';
import {
+ useCheckShipmentForm,
useSalesOrderShipmentCompleteFields,
- useSalesOrderShipmentFields
+ useSalesOrderShipmentFields,
+ useUncheckShipmentForm
} from '../../forms/SalesOrderForms';
import {
useCreateApiFormModal,
@@ -91,6 +97,20 @@ export default function SalesOrderShipmentTable({
table: table
});
+ const checkShipment = useCheckShipmentForm({
+ shipmentId: selectedShipment.pk,
+ onSuccess: () => {
+ table.refreshTable();
+ }
+ });
+
+ const uncheckShipment = useUncheckShipmentForm({
+ shipmentId: selectedShipment.pk,
+ onSuccess: () => {
+ table.refreshTable();
+ }
+ });
+
const completeShipment = useCreateApiFormModal({
url: ApiEndpoints.sales_order_shipment_complete,
pk: selectedShipment.pk,
@@ -188,6 +208,30 @@ export default function SalesOrderShipmentTable({
const shipped: boolean = !!record.shipment_date;
return [
+ {
+ hidden:
+ !!record.checked_by || !user.hasChangeRole(UserRoles.sales_order),
+ title: t`Check Shipment`,
+ color: 'blue',
+ icon: ,
+ onClick: () => {
+ setSelectedShipment(record);
+ checkShipment.open();
+ }
+ },
+ {
+ hidden:
+ shipped ||
+ !record.checked_by ||
+ !user.hasChangeRole(UserRoles.sales_order),
+ title: t`Uncheck Shipment`,
+ color: 'red',
+ icon: ,
+ onClick: () => {
+ setSelectedShipment(record);
+ uncheckShipment.open();
+ }
+ },
{
hidden: shipped || !user.hasChangeRole(UserRoles.sales_order),
title: t`Complete Shipment`,
@@ -271,7 +315,9 @@ export default function SalesOrderShipmentTable({
<>
{newShipment.modal}
{editShipment.modal}
+ {checkShipment.modal}
{deleteShipment.modal}
+ {uncheckShipment.modal}
{completeShipment.modal}