mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-03 13:58:47 +00:00
Refactoring / Enhancements (#8307)
* Create simply PartSalesPanel component * Updates * Add API endpoint for SalesHistory - And serializers - Basic, needs lots of work still * Fix for PartDetail page * SalesOrder page updates * More page updates * Update API endpoint * Backend improvements * add API endpoint * Front-end rendering * Make frontend generic * Fix for CompanyTable * Make back-end API more generic * More API improvements * Implement history for purchasing * API / UI fixes * Remove debug statements * Support file download * Add endpoint for build order history * Implement UI for build order history * Revert backend * Revert frontend * Remove unsed imports * Cleanup permission checks * Bump API version * Improve token management code - Do not request token if other cookies are unavailable - Do not fetch user data if token is unavailable - Prevents connection error logs * Fix for CompanyTable - onRowClick
This commit is contained in:
parent
16d0fb4798
commit
29726d8d0d
@ -1,13 +1,16 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 269
|
INVENTREE_API_VERSION = 270
|
||||||
|
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
|
||||||
|
v270 - 2024-10-19 : https://github.com/inventree/InvenTree/pull/8307
|
||||||
|
- Adds missing date fields from order API endpoint(s)
|
||||||
|
|
||||||
v269 - 2024-10-16 : https://github.com/inventree/InvenTree/pull/8295
|
v269 - 2024-10-16 : https://github.com/inventree/InvenTree/pull/8295
|
||||||
- Adds "include_variants" filter to the BuildOrder API endpoint
|
- Adds "include_variants" filter to the BuildOrder API endpoint
|
||||||
- Adds "include_variants" filter to the SalesOrder API endpoint
|
- Adds "include_variants" filter to the SalesOrder API endpoint
|
||||||
|
@ -6,9 +6,8 @@ from django.urls import include, path
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from rest_framework.exceptions import ValidationError
|
|
||||||
|
|
||||||
from django_filters import rest_framework as rest_filters
|
from django_filters import rest_framework as rest_filters
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
|
|
||||||
from importer.mixins import DataExportViewMixin
|
from importer.mixins import DataExportViewMixin
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ class BuildFilter(rest_filters.FilterSet):
|
|||||||
def filter_responsible(self, queryset, name, owner):
|
def filter_responsible(self, queryset, name, owner):
|
||||||
"""Filter by orders which are assigned to the specified owner."""
|
"""Filter by orders which are assigned to the specified owner."""
|
||||||
|
|
||||||
owners = list(Owner.objects.filter(pk=value))
|
owners = list(Owner.objects.filter(pk=owner))
|
||||||
|
|
||||||
# if we query by a user, also find all ownerships through group memberships
|
# if we query by a user, also find all ownerships through group memberships
|
||||||
if len(owners) > 0 and owners[0].label() == 'user':
|
if len(owners) > 0 and owners[0].label() == 'user':
|
||||||
|
@ -23,3 +23,7 @@ class BuildStatusGroups:
|
|||||||
BuildStatus.ON_HOLD.value,
|
BuildStatus.ON_HOLD.value,
|
||||||
BuildStatus.PRODUCTION.value,
|
BuildStatus.PRODUCTION.value,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
COMPLETE = [
|
||||||
|
BuildStatus.COMPLETE.value,
|
||||||
|
]
|
||||||
|
@ -1773,6 +1773,8 @@ class ReturnOrderSerializer(
|
|||||||
model = order.models.ReturnOrder
|
model = order.models.ReturnOrder
|
||||||
|
|
||||||
fields = AbstractOrderSerializer.order_fields([
|
fields = AbstractOrderSerializer.order_fields([
|
||||||
|
'issue_date',
|
||||||
|
'complete_date',
|
||||||
'customer',
|
'customer',
|
||||||
'customer_detail',
|
'customer_detail',
|
||||||
'customer_reference',
|
'customer_reference',
|
||||||
|
@ -35,6 +35,8 @@ class PurchaseOrderStatusGroups:
|
|||||||
PurchaseOrderStatus.RETURNED.value,
|
PurchaseOrderStatus.RETURNED.value,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
COMPLETE = [PurchaseOrderStatus.COMPLETE.value]
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderStatus(StatusCode):
|
class SalesOrderStatus(StatusCode):
|
||||||
"""Defines a set of status codes for a SalesOrder."""
|
"""Defines a set of status codes for a SalesOrder."""
|
||||||
@ -91,6 +93,8 @@ class ReturnOrderStatusGroups:
|
|||||||
ReturnOrderStatus.IN_PROGRESS.value,
|
ReturnOrderStatus.IN_PROGRESS.value,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
COMPLETE = [ReturnOrderStatus.COMPLETE.value]
|
||||||
|
|
||||||
|
|
||||||
class ReturnOrderLineStatus(StatusCode):
|
class ReturnOrderLineStatus(StatusCode):
|
||||||
"""Defines a set of status codes for a ReturnOrderLineItem."""
|
"""Defines a set of status codes for a ReturnOrderLineItem."""
|
||||||
|
@ -81,6 +81,7 @@ export enum ApiEndpoints {
|
|||||||
build_order_auto_allocate = 'build/:id/auto-allocate/',
|
build_order_auto_allocate = 'build/:id/auto-allocate/',
|
||||||
build_order_allocate = 'build/:id/allocate/',
|
build_order_allocate = 'build/:id/allocate/',
|
||||||
build_order_deallocate = 'build/:id/unallocate/',
|
build_order_deallocate = 'build/:id/unallocate/',
|
||||||
|
|
||||||
build_line_list = 'build/line/',
|
build_line_list = 'build/line/',
|
||||||
build_item_list = 'build/item/',
|
build_item_list = 'build/item/',
|
||||||
|
|
||||||
@ -160,11 +161,12 @@ export enum ApiEndpoints {
|
|||||||
sales_order_cancel = 'order/so/:id/cancel/',
|
sales_order_cancel = 'order/so/:id/cancel/',
|
||||||
sales_order_ship = 'order/so/:id/ship/',
|
sales_order_ship = 'order/so/:id/ship/',
|
||||||
sales_order_complete = 'order/so/:id/complete/',
|
sales_order_complete = 'order/so/:id/complete/',
|
||||||
|
sales_order_allocate = 'order/so/:id/allocate/',
|
||||||
|
sales_order_allocate_serials = 'order/so/:id/allocate-serials/',
|
||||||
|
|
||||||
sales_order_line_list = 'order/so-line/',
|
sales_order_line_list = 'order/so-line/',
|
||||||
sales_order_extra_line_list = 'order/so-extra-line/',
|
sales_order_extra_line_list = 'order/so-extra-line/',
|
||||||
sales_order_allocation_list = 'order/so-allocation/',
|
sales_order_allocation_list = 'order/so-allocation/',
|
||||||
sales_order_allocate = 'order/so/:id/allocate/',
|
|
||||||
sales_order_allocate_serials = 'order/so/:id/allocate-serials/',
|
|
||||||
|
|
||||||
sales_order_shipment_list = 'order/so/shipment/',
|
sales_order_shipment_list = 'order/so/shipment/',
|
||||||
sales_order_shipment_complete = 'order/so/shipment/:id/ship/',
|
sales_order_shipment_complete = 'order/so/shipment/:id/ship/',
|
||||||
|
@ -13,8 +13,11 @@ import {
|
|||||||
IconBuildingStore,
|
IconBuildingStore,
|
||||||
IconBusinessplan,
|
IconBusinessplan,
|
||||||
IconCalendar,
|
IconCalendar,
|
||||||
|
IconCalendarCheck,
|
||||||
|
IconCalendarDot,
|
||||||
IconCalendarStats,
|
IconCalendarStats,
|
||||||
IconCalendarTime,
|
IconCalendarTime,
|
||||||
|
IconCalendarX,
|
||||||
IconCheck,
|
IconCheck,
|
||||||
IconCircleCheck,
|
IconCircleCheck,
|
||||||
IconCircleMinus,
|
IconCircleMinus,
|
||||||
@ -179,8 +182,15 @@ const icons = {
|
|||||||
locked: IconLock,
|
locked: IconLock,
|
||||||
|
|
||||||
calendar: IconCalendar,
|
calendar: IconCalendar,
|
||||||
|
calendar_target: IconCalendarDot,
|
||||||
|
calendar_cross: IconCalendarX,
|
||||||
|
calendar_check: IconCalendarCheck,
|
||||||
external: IconExternalLink,
|
external: IconExternalLink,
|
||||||
creation_date: IconCalendarTime,
|
creation_date: IconCalendarTime,
|
||||||
|
target_date: IconCalendarDot,
|
||||||
|
date: IconCalendar,
|
||||||
|
shipment_date: IconCalendarCheck,
|
||||||
|
complete_date: IconCalendarCheck,
|
||||||
location: IconMapPin,
|
location: IconMapPin,
|
||||||
default_location: IconMapPinHeart,
|
default_location: IconMapPinHeart,
|
||||||
category_default_location: IconMapPinHeart,
|
category_default_location: IconMapPinHeart,
|
||||||
|
55
src/frontend/src/pages/part/PartAllocationPanel.tsx
Normal file
55
src/frontend/src/pages/part/PartAllocationPanel.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Accordion } from '@mantine/core';
|
||||||
|
|
||||||
|
import { StylishText } from '../../components/items/StylishText';
|
||||||
|
import { ModelType } from '../../enums/ModelType';
|
||||||
|
import { UserRoles } from '../../enums/Roles';
|
||||||
|
import { useUserState } from '../../states/UserState';
|
||||||
|
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
|
||||||
|
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
|
||||||
|
|
||||||
|
export default function PartAllocationPanel({ part }: { part: any }) {
|
||||||
|
const user = useUserState();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Accordion
|
||||||
|
multiple={true}
|
||||||
|
defaultValue={['buildallocations', 'salesallocations']}
|
||||||
|
>
|
||||||
|
{part.component && user.hasViewRole(UserRoles.build) && (
|
||||||
|
<Accordion.Item value="buildallocations" key="buildallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Build Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<BuildAllocatedStockTable
|
||||||
|
partId={part.pk}
|
||||||
|
modelField="build"
|
||||||
|
modelTarget={ModelType.build}
|
||||||
|
showBuildInfo
|
||||||
|
showPartInfo
|
||||||
|
allowEdit
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
{part.salable && user.hasViewRole(UserRoles.sales_order) && (
|
||||||
|
<Accordion.Item value="salesallocations" key="salesallocations">
|
||||||
|
<Accordion.Control>
|
||||||
|
<StylishText size="lg">{t`Sales Order Allocations`}</StylishText>
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>
|
||||||
|
<SalesOrderAllocationTable
|
||||||
|
partId={part.pk}
|
||||||
|
modelField="order"
|
||||||
|
modelTarget={ModelType.salesorder}
|
||||||
|
showOrderInfo
|
||||||
|
/>
|
||||||
|
</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
)}
|
||||||
|
</Accordion>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import {
|
import {
|
||||||
Accordion,
|
|
||||||
Alert,
|
Alert,
|
||||||
Center,
|
Center,
|
||||||
Grid,
|
Grid,
|
||||||
@ -54,7 +53,6 @@ import {
|
|||||||
EditItemAction,
|
EditItemAction,
|
||||||
OptionsActionDropdown
|
OptionsActionDropdown
|
||||||
} from '../../components/items/ActionDropdown';
|
} from '../../components/items/ActionDropdown';
|
||||||
import { StylishText } from '../../components/items/StylishText';
|
|
||||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||||
import NavigationTree from '../../components/nav/NavigationTree';
|
import NavigationTree from '../../components/nav/NavigationTree';
|
||||||
import { PageDetail } from '../../components/nav/PageDetail';
|
import { PageDetail } from '../../components/nav/PageDetail';
|
||||||
@ -89,7 +87,6 @@ import {
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { BomTable } from '../../tables/bom/BomTable';
|
import { BomTable } from '../../tables/bom/BomTable';
|
||||||
import { UsedInTable } from '../../tables/bom/UsedInTable';
|
import { UsedInTable } from '../../tables/bom/UsedInTable';
|
||||||
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
|
|
||||||
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
|
||||||
import { PartParameterTable } from '../../tables/part/PartParameterTable';
|
import { PartParameterTable } from '../../tables/part/PartParameterTable';
|
||||||
import PartPurchaseOrdersTable from '../../tables/part/PartPurchaseOrdersTable';
|
import PartPurchaseOrdersTable from '../../tables/part/PartPurchaseOrdersTable';
|
||||||
@ -99,10 +96,10 @@ import { RelatedPartTable } from '../../tables/part/RelatedPartTable';
|
|||||||
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
||||||
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
||||||
import { ReturnOrderTable } from '../../tables/sales/ReturnOrderTable';
|
import { ReturnOrderTable } from '../../tables/sales/ReturnOrderTable';
|
||||||
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
|
|
||||||
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
|
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
|
||||||
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
import { StockItemTable } from '../../tables/stock/StockItemTable';
|
||||||
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
|
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
|
||||||
|
import PartAllocationPanel from './PartAllocationPanel';
|
||||||
import PartPricingPanel from './PartPricingPanel';
|
import PartPricingPanel from './PartPricingPanel';
|
||||||
import PartSchedulingDetail from './PartSchedulingDetail';
|
import PartSchedulingDetail from './PartSchedulingDetail';
|
||||||
import PartStocktakeDetail from './PartStocktakeDetail';
|
import PartStocktakeDetail from './PartStocktakeDetail';
|
||||||
@ -351,7 +348,7 @@ export default function PartDetail() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
name: 'saleable',
|
name: 'salable',
|
||||||
label: t`Saleable Part`
|
label: t`Saleable Part`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -591,45 +588,7 @@ export default function PartDetail() {
|
|||||||
label: t`Allocations`,
|
label: t`Allocations`,
|
||||||
icon: <IconBookmarks />,
|
icon: <IconBookmarks />,
|
||||||
hidden: !part.component && !part.salable,
|
hidden: !part.component && !part.salable,
|
||||||
content: (
|
content: part.pk ? <PartAllocationPanel part={part} /> : <Skeleton />
|
||||||
<Accordion
|
|
||||||
multiple={true}
|
|
||||||
defaultValue={['buildallocations', 'salesallocations']}
|
|
||||||
>
|
|
||||||
{part.component && (
|
|
||||||
<Accordion.Item value="buildallocations" key="buildallocations">
|
|
||||||
<Accordion.Control>
|
|
||||||
<StylishText size="lg">{t`Build Order Allocations`}</StylishText>
|
|
||||||
</Accordion.Control>
|
|
||||||
<Accordion.Panel>
|
|
||||||
<BuildAllocatedStockTable
|
|
||||||
partId={part.pk}
|
|
||||||
modelField="build"
|
|
||||||
modelTarget={ModelType.build}
|
|
||||||
showBuildInfo
|
|
||||||
showPartInfo
|
|
||||||
allowEdit
|
|
||||||
/>
|
|
||||||
</Accordion.Panel>
|
|
||||||
</Accordion.Item>
|
|
||||||
)}
|
|
||||||
{part.salable && (
|
|
||||||
<Accordion.Item value="salesallocations" key="salesallocations">
|
|
||||||
<Accordion.Control>
|
|
||||||
<StylishText size="lg">{t`Sales Order Allocations`}</StylishText>
|
|
||||||
</Accordion.Control>
|
|
||||||
<Accordion.Panel>
|
|
||||||
<SalesOrderAllocationTable
|
|
||||||
partId={part.pk}
|
|
||||||
modelField="order"
|
|
||||||
modelTarget={ModelType.salesorder}
|
|
||||||
showOrderInfo
|
|
||||||
/>
|
|
||||||
</Accordion.Panel>
|
|
||||||
</Accordion.Item>
|
|
||||||
)}
|
|
||||||
</Accordion>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'bom',
|
name: 'bom',
|
||||||
@ -644,8 +603,8 @@ export default function PartDetail() {
|
|||||||
name: 'builds',
|
name: 'builds',
|
||||||
label: t`Build Orders`,
|
label: t`Build Orders`,
|
||||||
icon: <IconTools />,
|
icon: <IconTools />,
|
||||||
hidden: !part.assembly || !part.active,
|
hidden: !part.assembly || !user.hasViewRole(UserRoles.build),
|
||||||
content: part?.pk ? <BuildOrderTable partId={part.pk} /> : <Skeleton />
|
content: part.pk ? <BuildOrderTable partId={part.pk} /> : <Skeleton />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'used_in',
|
name: 'used_in',
|
||||||
@ -677,7 +636,8 @@ export default function PartDetail() {
|
|||||||
name: 'suppliers',
|
name: 'suppliers',
|
||||||
label: t`Suppliers`,
|
label: t`Suppliers`,
|
||||||
icon: <IconBuilding />,
|
icon: <IconBuilding />,
|
||||||
hidden: !part.purchaseable,
|
hidden:
|
||||||
|
!part.purchaseable || !user.hasViewRole(UserRoles.purchase_order),
|
||||||
content: part.pk && (
|
content: part.pk && (
|
||||||
<SupplierPartTable
|
<SupplierPartTable
|
||||||
params={{
|
params={{
|
||||||
@ -690,21 +650,29 @@ export default function PartDetail() {
|
|||||||
name: 'purchase_orders',
|
name: 'purchase_orders',
|
||||||
label: t`Purchase Orders`,
|
label: t`Purchase Orders`,
|
||||||
icon: <IconShoppingCart />,
|
icon: <IconShoppingCart />,
|
||||||
hidden: !part.purchaseable,
|
hidden:
|
||||||
content: <PartPurchaseOrdersTable partId={part.pk} />
|
!part.purchaseable || !user.hasViewRole(UserRoles.purchase_order),
|
||||||
|
content: part.pk ? (
|
||||||
|
<PartPurchaseOrdersTable partId={part.pk} />
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'sales_orders',
|
name: 'sales_orders',
|
||||||
label: t`Sales Orders`,
|
label: t`Sales Orders`,
|
||||||
icon: <IconTruckDelivery />,
|
icon: <IconTruckDelivery />,
|
||||||
hidden: !part.salable,
|
hidden: !part.salable || !user.hasViewRole(UserRoles.sales_order),
|
||||||
content: part.pk ? <SalesOrderTable partId={part.pk} /> : <Skeleton />
|
content: part.pk ? <SalesOrderTable partId={part.pk} /> : <Skeleton />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'return_orders',
|
name: 'return_orders',
|
||||||
label: t`Return Orders`,
|
label: t`Return Orders`,
|
||||||
icon: <IconTruckReturn />,
|
icon: <IconTruckReturn />,
|
||||||
hidden: !part.salable || !globalSettings.isSet('RETURNORDER_ENABLED'),
|
hidden:
|
||||||
|
!part.salable ||
|
||||||
|
!user.hasViewRole(UserRoles.return_order) ||
|
||||||
|
!globalSettings.isSet('RETURNORDER_ENABLED'),
|
||||||
content: part.pk ? <ReturnOrderTable partId={part.pk} /> : <Skeleton />
|
content: part.pk ? <ReturnOrderTable partId={part.pk} /> : <Skeleton />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -196,18 +196,34 @@ export default function PurchaseOrderDetail() {
|
|||||||
|
|
||||||
let br: DetailsField[] = [
|
let br: DetailsField[] = [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
name: 'creation_date',
|
name: 'creation_date',
|
||||||
label: t`Created On`,
|
label: t`Creation Date`,
|
||||||
icon: 'calendar'
|
icon: 'calendar'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
|
name: 'issue_date',
|
||||||
|
label: t`Issue Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.issue_date
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
label: t`Target Date`,
|
label: t`Target Date`,
|
||||||
icon: 'calendar',
|
icon: 'calendar',
|
||||||
hidden: !order.target_date
|
hidden: !order.target_date
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'complete_date',
|
||||||
|
icon: 'calendar_check',
|
||||||
|
label: t`Completion Date`,
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.complete_date
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'responsible',
|
name: 'responsible',
|
||||||
|
@ -173,18 +173,36 @@ export default function ReturnOrderDetail() {
|
|||||||
|
|
||||||
let br: DetailsField[] = [
|
let br: DetailsField[] = [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
name: 'creation_date',
|
name: 'creation_date',
|
||||||
label: t`Created On`,
|
label: t`Creation Date`,
|
||||||
icon: 'calendar'
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.creation_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
|
name: 'issue_date',
|
||||||
|
label: t`Issue Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.issue_date
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
label: t`Target Date`,
|
label: t`Target Date`,
|
||||||
icon: 'calendar',
|
copy: true,
|
||||||
hidden: !order.target_date
|
hidden: !order.target_date
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'complete_date',
|
||||||
|
icon: 'calendar_check',
|
||||||
|
label: t`Completion Date`,
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.complete_date
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'responsible',
|
name: 'responsible',
|
||||||
|
@ -100,6 +100,7 @@ export default function SalesOrderDetail() {
|
|||||||
name: 'customer_reference',
|
name: 'customer_reference',
|
||||||
label: t`Customer Reference`,
|
label: t`Customer Reference`,
|
||||||
copy: true,
|
copy: true,
|
||||||
|
icon: 'reference',
|
||||||
hidden: !order.customer_reference
|
hidden: !order.customer_reference
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -184,17 +185,33 @@ export default function SalesOrderDetail() {
|
|||||||
|
|
||||||
let br: DetailsField[] = [
|
let br: DetailsField[] = [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
name: 'creation_date',
|
name: 'creation_date',
|
||||||
label: t`Created On`,
|
label: t`Creation Date`,
|
||||||
icon: 'calendar'
|
copy: true,
|
||||||
|
hidden: !order.creation_date
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'date',
|
||||||
|
name: 'issue_date',
|
||||||
|
label: t`Issue Date`,
|
||||||
|
icon: 'calendar',
|
||||||
|
copy: true,
|
||||||
|
hidden: !order.issue_date
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
name: 'target_date',
|
name: 'target_date',
|
||||||
label: t`Target Date`,
|
label: t`Target Date`,
|
||||||
icon: 'calendar',
|
hidden: !order.target_date,
|
||||||
hidden: !order.target_date
|
copy: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
name: 'shipment_date',
|
||||||
|
label: t`Completion Date`,
|
||||||
|
hidden: !order.shipment_date,
|
||||||
|
copy: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
@ -67,6 +67,15 @@ export const useUserState = create<UserStateProps>((set, get) => ({
|
|||||||
setApiDefaults();
|
setApiDefaults();
|
||||||
},
|
},
|
||||||
fetchUserToken: async () => {
|
fetchUserToken: async () => {
|
||||||
|
// If neither the csrf or session cookies are available, we cannot fetch a token
|
||||||
|
if (
|
||||||
|
!document.cookie.includes('csrftoken') &&
|
||||||
|
!document.cookie.includes('sessionid')
|
||||||
|
) {
|
||||||
|
get().clearToken();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await api
|
await api
|
||||||
.get(apiUrl(ApiEndpoints.user_token))
|
.get(apiUrl(ApiEndpoints.user_token))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@ -85,6 +94,12 @@ export const useUserState = create<UserStateProps>((set, get) => ({
|
|||||||
await get().fetchUserToken();
|
await get().fetchUserToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we still don't have a token, clear the user state and return
|
||||||
|
if (!get().token) {
|
||||||
|
get().clearUserState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch user data
|
// Fetch user data
|
||||||
await api
|
await api
|
||||||
.get(apiUrl(ApiEndpoints.user_me), {
|
.get(apiUrl(ApiEndpoints.user_me), {
|
||||||
|
@ -95,6 +95,7 @@ export function BuildOrderTable({
|
|||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
DateColumn({
|
DateColumn({
|
||||||
accessor: 'completion_date',
|
accessor: 'completion_date',
|
||||||
|
title: t`Completion Date`,
|
||||||
sortable: true
|
sortable: true
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { companyFields } from '../../forms/CompanyForms';
|
import { companyFields } from '../../forms/CompanyForms';
|
||||||
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
import {
|
import {
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
useEditApiFormModal
|
useEditApiFormModal
|
||||||
@ -157,16 +158,17 @@ export function CompanyTable({
|
|||||||
params: {
|
params: {
|
||||||
...params
|
...params
|
||||||
},
|
},
|
||||||
|
onRowClick: (record: any, index: number, event: any) => {
|
||||||
|
if (record.pk) {
|
||||||
|
let base = path ?? 'company';
|
||||||
|
navigateToLink(`/${base}/${record.pk}`, navigate, event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modelType: ModelType.company,
|
||||||
tableFilters: tableFilters,
|
tableFilters: tableFilters,
|
||||||
tableActions: tableActions,
|
tableActions: tableActions,
|
||||||
enableDownload: true,
|
enableDownload: true,
|
||||||
rowActions: rowActions,
|
rowActions: rowActions
|
||||||
onRowClick: (row: any) => {
|
|
||||||
if (row.pk) {
|
|
||||||
let base = path ?? 'company';
|
|
||||||
navigate(`/${base}/${row.pk}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -92,6 +92,10 @@ export default function PartPurchaseOrdersTable({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
DateColumn({
|
||||||
|
accessor: 'order_detail.complete_date',
|
||||||
|
title: t`Order Completed Date`
|
||||||
|
}),
|
||||||
DateColumn({
|
DateColumn({
|
||||||
accessor: 'target_date',
|
accessor: 'target_date',
|
||||||
title: t`Target Date`
|
title: t`Target Date`
|
||||||
|
@ -15,6 +15,7 @@ import { apiUrl } from '../../states/ApiState';
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import {
|
import {
|
||||||
CreationDateColumn,
|
CreationDateColumn,
|
||||||
|
DateColumn,
|
||||||
DescriptionColumn,
|
DescriptionColumn,
|
||||||
LineItemsProgressColumn,
|
LineItemsProgressColumn,
|
||||||
ProjectCodeColumn,
|
ProjectCodeColumn,
|
||||||
@ -116,6 +117,10 @@ export function ReturnOrderTable({
|
|||||||
ProjectCodeColumn({}),
|
ProjectCodeColumn({}),
|
||||||
CreationDateColumn({}),
|
CreationDateColumn({}),
|
||||||
TargetDateColumn({}),
|
TargetDateColumn({}),
|
||||||
|
DateColumn({
|
||||||
|
accessor: 'complete_date',
|
||||||
|
title: t`Completion Date`
|
||||||
|
}),
|
||||||
ResponsibleColumn({}),
|
ResponsibleColumn({}),
|
||||||
{
|
{
|
||||||
accessor: 'total_price',
|
accessor: 'total_price',
|
||||||
|
@ -16,6 +16,7 @@ import { apiUrl } from '../../states/ApiState';
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import {
|
import {
|
||||||
|
DateColumn,
|
||||||
LocationColumn,
|
LocationColumn,
|
||||||
PartColumn,
|
PartColumn,
|
||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
@ -136,6 +137,12 @@ export default function SalesOrderAllocationTable({
|
|||||||
switchable: true,
|
switchable: true,
|
||||||
sortable: false
|
sortable: false
|
||||||
},
|
},
|
||||||
|
DateColumn({
|
||||||
|
accessor: 'shipment_detail.shipment_date',
|
||||||
|
title: t`Shipment Date`,
|
||||||
|
switchable: true,
|
||||||
|
sortable: false
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
accessor: 'shipment_date',
|
accessor: 'shipment_date',
|
||||||
title: t`Shipped`,
|
title: t`Shipped`,
|
||||||
|
@ -4,6 +4,7 @@ import { useCallback, useMemo, useState } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||||
|
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
@ -23,7 +24,12 @@ import { useTable } from '../../hooks/UseTable';
|
|||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { DateColumn, LinkColumn, NoteColumn } from '../ColumnRenderers';
|
import {
|
||||||
|
BooleanColumn,
|
||||||
|
DateColumn,
|
||||||
|
LinkColumn,
|
||||||
|
NoteColumn
|
||||||
|
} from '../ColumnRenderers';
|
||||||
import { TableFilter } from '../Filter';
|
import { TableFilter } from '../Filter';
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
import { RowAction, RowCancelAction, RowEditAction } from '../RowActions';
|
import { RowAction, RowCancelAction, RowEditAction } from '../RowActions';
|
||||||
@ -97,6 +103,13 @@ export default function SalesOrderShipmentTable({
|
|||||||
switchable: false,
|
switchable: false,
|
||||||
title: t`Items`
|
title: t`Items`
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessor: 'shipped',
|
||||||
|
title: t`Shipped`,
|
||||||
|
switchable: true,
|
||||||
|
sortable: false,
|
||||||
|
render: (record: any) => <YesNoButton value={!!record.shipment_date} />
|
||||||
|
},
|
||||||
DateColumn({
|
DateColumn({
|
||||||
accessor: 'shipment_date',
|
accessor: 'shipment_date',
|
||||||
title: t`Shipment Date`
|
title: t`Shipment Date`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user