Skip to content

Commit

Permalink
Refactoring / Enhancements (#8307)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
SchrodingersGat authored Oct 20, 2024
1 parent 16d0fb4 commit 29726d8
Show file tree
Hide file tree
Showing 19 changed files with 224 additions and 79 deletions.
5 changes: 4 additions & 1 deletion src/backend/InvenTree/InvenTree/api_version.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""InvenTree API version information."""

# 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."""


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
- Adds "include_variants" filter to the BuildOrder API endpoint
- Adds "include_variants" filter to the SalesOrder API endpoint
Expand Down
5 changes: 2 additions & 3 deletions src/backend/InvenTree/build/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User

from rest_framework.exceptions import ValidationError

from django_filters import rest_framework as rest_filters
from rest_framework.exceptions import ValidationError

from importer.mixins import DataExportViewMixin

Expand Down Expand Up @@ -149,7 +148,7 @@ def filter_issued_by(self, queryset, name, owner):
def filter_responsible(self, queryset, name, 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 len(owners) > 0 and owners[0].label() == 'user':
Expand Down
4 changes: 4 additions & 0 deletions src/backend/InvenTree/build/status_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ class BuildStatusGroups:
BuildStatus.ON_HOLD.value,
BuildStatus.PRODUCTION.value,
]

COMPLETE = [
BuildStatus.COMPLETE.value,
]
2 changes: 2 additions & 0 deletions src/backend/InvenTree/order/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,8 @@ class Meta:
model = order.models.ReturnOrder

fields = AbstractOrderSerializer.order_fields([
'issue_date',
'complete_date',
'customer',
'customer_detail',
'customer_reference',
Expand Down
4 changes: 4 additions & 0 deletions src/backend/InvenTree/order/status_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class PurchaseOrderStatusGroups:
PurchaseOrderStatus.RETURNED.value,
]

COMPLETE = [PurchaseOrderStatus.COMPLETE.value]


class SalesOrderStatus(StatusCode):
"""Defines a set of status codes for a SalesOrder."""
Expand Down Expand Up @@ -91,6 +93,8 @@ class ReturnOrderStatusGroups:
ReturnOrderStatus.IN_PROGRESS.value,
]

COMPLETE = [ReturnOrderStatus.COMPLETE.value]


class ReturnOrderLineStatus(StatusCode):
"""Defines a set of status codes for a ReturnOrderLineItem."""
Expand Down
6 changes: 4 additions & 2 deletions src/frontend/src/enums/ApiEndpoints.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export enum ApiEndpoints {
build_order_auto_allocate = 'build/:id/auto-allocate/',
build_order_allocate = 'build/:id/allocate/',
build_order_deallocate = 'build/:id/unallocate/',

build_line_list = 'build/line/',
build_item_list = 'build/item/',

Expand Down Expand Up @@ -160,11 +161,12 @@ export enum ApiEndpoints {
sales_order_cancel = 'order/so/:id/cancel/',
sales_order_ship = 'order/so/:id/ship/',
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_extra_line_list = 'order/so-extra-line/',
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_complete = 'order/so/shipment/:id/ship/',
Expand Down
10 changes: 10 additions & 0 deletions src/frontend/src/functions/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import {
IconBuildingStore,
IconBusinessplan,
IconCalendar,
IconCalendarCheck,
IconCalendarDot,
IconCalendarStats,
IconCalendarTime,
IconCalendarX,
IconCheck,
IconCircleCheck,
IconCircleMinus,
Expand Down Expand Up @@ -179,8 +182,15 @@ const icons = {
locked: IconLock,

calendar: IconCalendar,
calendar_target: IconCalendarDot,
calendar_cross: IconCalendarX,
calendar_check: IconCalendarCheck,
external: IconExternalLink,
creation_date: IconCalendarTime,
target_date: IconCalendarDot,
date: IconCalendar,
shipment_date: IconCalendarCheck,
complete_date: IconCalendarCheck,
location: IconMapPin,
default_location: IconMapPinHeart,
category_default_location: IconMapPinHeart,
Expand Down
55 changes: 55 additions & 0 deletions src/frontend/src/pages/part/PartAllocationPanel.tsx
Original file line number Diff line number Diff line change
@@ -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>
</>
);
}
70 changes: 19 additions & 51 deletions src/frontend/src/pages/part/PartDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { t } from '@lingui/macro';
import {
Accordion,
Alert,
Center,
Grid,
Expand Down Expand Up @@ -54,7 +53,6 @@ import {
EditItemAction,
OptionsActionDropdown
} from '../../components/items/ActionDropdown';
import { StylishText } from '../../components/items/StylishText';
import InstanceDetail from '../../components/nav/InstanceDetail';
import NavigationTree from '../../components/nav/NavigationTree';
import { PageDetail } from '../../components/nav/PageDetail';
Expand Down Expand Up @@ -89,7 +87,6 @@ import {
import { useUserState } from '../../states/UserState';
import { BomTable } from '../../tables/bom/BomTable';
import { UsedInTable } from '../../tables/bom/UsedInTable';
import BuildAllocatedStockTable from '../../tables/build/BuildAllocatedStockTable';
import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
import { PartParameterTable } from '../../tables/part/PartParameterTable';
import PartPurchaseOrdersTable from '../../tables/part/PartPurchaseOrdersTable';
Expand All @@ -99,10 +96,10 @@ import { RelatedPartTable } from '../../tables/part/RelatedPartTable';
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
import { ReturnOrderTable } from '../../tables/sales/ReturnOrderTable';
import SalesOrderAllocationTable from '../../tables/sales/SalesOrderAllocationTable';
import { SalesOrderTable } from '../../tables/sales/SalesOrderTable';
import { StockItemTable } from '../../tables/stock/StockItemTable';
import { TestStatisticsTable } from '../../tables/stock/TestStatisticsTable';
import PartAllocationPanel from './PartAllocationPanel';
import PartPricingPanel from './PartPricingPanel';
import PartSchedulingDetail from './PartSchedulingDetail';
import PartStocktakeDetail from './PartStocktakeDetail';
Expand Down Expand Up @@ -351,7 +348,7 @@ export default function PartDetail() {
},
{
type: 'boolean',
name: 'saleable',
name: 'salable',
label: t`Saleable Part`
},
{
Expand Down Expand Up @@ -591,45 +588,7 @@ export default function PartDetail() {
label: t`Allocations`,
icon: <IconBookmarks />,
hidden: !part.component && !part.salable,
content: (
<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>
)
content: part.pk ? <PartAllocationPanel part={part} /> : <Skeleton />
},
{
name: 'bom',
Expand All @@ -644,8 +603,8 @@ export default function PartDetail() {
name: 'builds',
label: t`Build Orders`,
icon: <IconTools />,
hidden: !part.assembly || !part.active,
content: part?.pk ? <BuildOrderTable partId={part.pk} /> : <Skeleton />
hidden: !part.assembly || !user.hasViewRole(UserRoles.build),
content: part.pk ? <BuildOrderTable partId={part.pk} /> : <Skeleton />
},
{
name: 'used_in',
Expand Down Expand Up @@ -677,7 +636,8 @@ export default function PartDetail() {
name: 'suppliers',
label: t`Suppliers`,
icon: <IconBuilding />,
hidden: !part.purchaseable,
hidden:
!part.purchaseable || !user.hasViewRole(UserRoles.purchase_order),
content: part.pk && (
<SupplierPartTable
params={{
Expand All @@ -690,21 +650,29 @@ export default function PartDetail() {
name: 'purchase_orders',
label: t`Purchase Orders`,
icon: <IconShoppingCart />,
hidden: !part.purchaseable,
content: <PartPurchaseOrdersTable partId={part.pk} />
hidden:
!part.purchaseable || !user.hasViewRole(UserRoles.purchase_order),
content: part.pk ? (
<PartPurchaseOrdersTable partId={part.pk} />
) : (
<Skeleton />
)
},
{
name: 'sales_orders',
label: t`Sales Orders`,
icon: <IconTruckDelivery />,
hidden: !part.salable,
hidden: !part.salable || !user.hasViewRole(UserRoles.sales_order),
content: part.pk ? <SalesOrderTable partId={part.pk} /> : <Skeleton />
},
{
name: 'return_orders',
label: t`Return Orders`,
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 />
},
{
Expand Down
22 changes: 19 additions & 3 deletions src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,34 @@ export default function PurchaseOrderDetail() {

let br: DetailsField[] = [
{
type: 'text',
type: 'date',
name: 'creation_date',
label: t`Created On`,
label: t`Creation Date`,
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',
label: t`Target Date`,
icon: 'calendar',
hidden: !order.target_date
},
{
type: 'date',
name: 'complete_date',
icon: 'calendar_check',
label: t`Completion Date`,
copy: true,
hidden: !order.complete_date
},
{
type: 'text',
name: 'responsible',
Expand Down
Loading

0 comments on commit 29726d8

Please sign in to comment.