mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	PurchaseOrder detail page
This commit is contained in:
		| @@ -1,5 +1,5 @@ | ||||
| import { t } from '@lingui/macro'; | ||||
| import { LoadingOverlay, Stack } from '@mantine/core'; | ||||
| import { Grid, LoadingOverlay, Skeleton, Stack } from '@mantine/core'; | ||||
| import { | ||||
|   IconDots, | ||||
|   IconInfoCircle, | ||||
| @@ -11,6 +11,8 @@ import { | ||||
| import { useMemo } from 'react'; | ||||
| import { useParams } from 'react-router-dom'; | ||||
|  | ||||
| import { DetailsImage } from '../../components/details/DetailsImage'; | ||||
| import { ItemDetailsGrid } from '../../components/details/ItemDetails'; | ||||
| import { | ||||
|   ActionDropdown, | ||||
|   BarcodeActionDropdown, | ||||
| @@ -24,9 +26,14 @@ import { PageDetail } from '../../components/nav/PageDetail'; | ||||
| import { PanelGroup, PanelType } from '../../components/nav/PanelGroup'; | ||||
| import { NotesEditor } from '../../components/widgets/MarkdownEditor'; | ||||
| import { ApiEndpoints } from '../../enums/ApiEndpoints'; | ||||
| import { ModelType } from '../../enums/ModelType'; | ||||
| import { UserRoles } from '../../enums/Roles'; | ||||
| import { purchaseOrderFields } from '../../forms/PurchaseOrderForms'; | ||||
| import { useEditApiFormModal } from '../../hooks/UseForm'; | ||||
| import { useInstance } from '../../hooks/UseInstance'; | ||||
| import { apiUrl } from '../../states/ApiState'; | ||||
| import { useUserState } from '../../states/UserState'; | ||||
| import { DetailsField, DetailsTable } from '../../tables/Details'; | ||||
| import { AttachmentTable } from '../../tables/general/AttachmentTable'; | ||||
| import { PurchaseOrderLineItemTable } from '../../tables/purchasing/PurchaseOrderLineItemTable'; | ||||
| import { StockItemTable } from '../../tables/stock/StockItemTable'; | ||||
| @@ -39,7 +46,11 @@ export default function PurchaseOrderDetail() { | ||||
|  | ||||
|   const user = useUserState(); | ||||
|  | ||||
|   const { instance: order, instanceQuery } = useInstance({ | ||||
|   const { | ||||
|     instance: order, | ||||
|     instanceQuery, | ||||
|     refreshInstance | ||||
|   } = useInstance({ | ||||
|     endpoint: ApiEndpoints.purchase_order_list, | ||||
|     pk: id, | ||||
|     params: { | ||||
| @@ -48,12 +59,167 @@ export default function PurchaseOrderDetail() { | ||||
|     refetchOnMount: true | ||||
|   }); | ||||
|  | ||||
|   const editPurchaseOrder = useEditApiFormModal({ | ||||
|     url: ApiEndpoints.purchase_order_list, | ||||
|     pk: id, | ||||
|     title: t`Edit Purchase Order`, | ||||
|     fields: purchaseOrderFields(), | ||||
|     onFormSuccess: () => { | ||||
|       refreshInstance(); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   const detailsPanel = useMemo(() => { | ||||
|     if (instanceQuery.isFetching) { | ||||
|       return <Skeleton />; | ||||
|     } | ||||
|  | ||||
|     let tl: DetailsField[] = [ | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'reference', | ||||
|         label: t`Reference`, | ||||
|         copy: true | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'supplier_reference', | ||||
|         label: t`Supplier Reference`, | ||||
|         icon: 'reference', | ||||
|         hidden: !order.supplier_reference, | ||||
|         copy: true | ||||
|       }, | ||||
|       { | ||||
|         type: 'link', | ||||
|         name: 'supplier', | ||||
|         icon: 'suppliers', | ||||
|         label: t`Supplier`, | ||||
|         model: ModelType.company | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'description', | ||||
|         label: t`Description`, | ||||
|         copy: true | ||||
|       }, | ||||
|       { | ||||
|         type: 'status', | ||||
|         name: 'status', | ||||
|         label: t`Status`, | ||||
|         model: ModelType.purchaseorder | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     let tr: DetailsField[] = [ | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'line_items', | ||||
|         label: t`Line Items`, | ||||
|         icon: 'list' | ||||
|       }, | ||||
|       { | ||||
|         type: 'progressbar', | ||||
|         name: 'completed', | ||||
|         icon: 'progress', | ||||
|         label: t`Completed Line Items`, | ||||
|         total: order.line_items, | ||||
|         progress: order.completed_lines | ||||
|       }, | ||||
|       { | ||||
|         type: 'progressbar', | ||||
|         name: 'shipments', | ||||
|         icon: 'shipment', | ||||
|         label: t`Completed Shipments`, | ||||
|         total: order.shipments, | ||||
|         progress: order.completed_shipments | ||||
|         // TODO: Fix this progress bar | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'currency', | ||||
|         label: t`Order Currency,` | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'total_cost', | ||||
|         label: t`Total Cost` | ||||
|         // TODO: Implement this! | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     let bl: DetailsField[] = [ | ||||
|       { | ||||
|         type: 'link', | ||||
|         external: true, | ||||
|         name: 'link', | ||||
|         label: t`Link`, | ||||
|         copy: true, | ||||
|         hidden: !order.link | ||||
|       }, | ||||
|       { | ||||
|         type: 'link', | ||||
|         model: ModelType.contact, | ||||
|         link: false, | ||||
|         name: 'contact', | ||||
|         label: t`Contact`, | ||||
|         icon: 'user', | ||||
|         copy: true | ||||
|       } | ||||
|       // TODO: Project code | ||||
|     ]; | ||||
|  | ||||
|     let br: DetailsField[] = [ | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'creation_date', | ||||
|         label: t`Created On`, | ||||
|         icon: 'calendar' | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'target_date', | ||||
|         label: t`Target Date`, | ||||
|         icon: 'calendar', | ||||
|         hidden: !order.target_date | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'responsible', | ||||
|         label: t`Responsible`, | ||||
|         badge: 'owner', | ||||
|         hidden: !order.responsible | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     return ( | ||||
|       <ItemDetailsGrid> | ||||
|         <Grid> | ||||
|           <Grid.Col span={4}> | ||||
|             <DetailsImage | ||||
|               appRole={UserRoles.purchase_order} | ||||
|               apiPath={ApiEndpoints.company_list} | ||||
|               src={order.supplier_detail?.image} | ||||
|               pk={order.supplier} | ||||
|             /> | ||||
|           </Grid.Col> | ||||
|           <Grid.Col span={8}> | ||||
|             <DetailsTable fields={tl} item={order} /> | ||||
|           </Grid.Col> | ||||
|         </Grid> | ||||
|         <DetailsTable fields={tr} item={order} /> | ||||
|         <DetailsTable fields={bl} item={order} /> | ||||
|         <DetailsTable fields={br} item={order} /> | ||||
|       </ItemDetailsGrid> | ||||
|     ); | ||||
|   }, [order, instanceQuery]); | ||||
|  | ||||
|   const orderPanels: PanelType[] = useMemo(() => { | ||||
|     return [ | ||||
|       { | ||||
|         name: 'detail', | ||||
|         label: t`Order Details`, | ||||
|         icon: <IconInfoCircle /> | ||||
|         icon: <IconInfoCircle />, | ||||
|         content: detailsPanel | ||||
|       }, | ||||
|       { | ||||
|         name: 'line-items', | ||||
| @@ -118,13 +284,21 @@ export default function PurchaseOrderDetail() { | ||||
|         key="order-actions" | ||||
|         tooltip={t`Order Actions`} | ||||
|         icon={<IconDots />} | ||||
|         actions={[EditItemAction({}), DeleteItemAction({})]} | ||||
|         actions={[ | ||||
|           EditItemAction({ | ||||
|             onClick: () => { | ||||
|               editPurchaseOrder.open(); | ||||
|             } | ||||
|           }), | ||||
|           DeleteItemAction({}) | ||||
|         ]} | ||||
|       /> | ||||
|     ]; | ||||
|   }, [id, order, user]); | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       {editPurchaseOrder.modal} | ||||
|       <Stack spacing="xs"> | ||||
|         <LoadingOverlay visible={instanceQuery.isFetching} /> | ||||
|         <PageDetail | ||||
|   | ||||
| @@ -48,6 +48,13 @@ export default function ReturnOrderDetail() { | ||||
|         label: t`Reference`, | ||||
|         copy: true | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'customer_reference', | ||||
|         label: t`Customer Reference`, | ||||
|         copy: true, | ||||
|         hidden: !order.customer_reference | ||||
|       }, | ||||
|       { | ||||
|         type: 'link', | ||||
|         name: 'customer', | ||||
| @@ -120,6 +127,7 @@ export default function ReturnOrderDetail() { | ||||
|         model: ModelType.contact, | ||||
|         link: false, | ||||
|         name: 'contact', | ||||
|         label: t`Contact`, | ||||
|         icon: 'user', | ||||
|         copy: true | ||||
|       } | ||||
|   | ||||
| @@ -52,6 +52,13 @@ export default function SalesOrderDetail() { | ||||
|         label: t`Reference`, | ||||
|         copy: true | ||||
|       }, | ||||
|       { | ||||
|         type: 'text', | ||||
|         name: 'customer_reference', | ||||
|         label: t`Customer Reference`, | ||||
|         copy: true, | ||||
|         hidden: !order.customer_reference | ||||
|       }, | ||||
|       { | ||||
|         type: 'link', | ||||
|         name: 'customer', | ||||
| @@ -124,6 +131,7 @@ export default function SalesOrderDetail() { | ||||
|         model: ModelType.contact, | ||||
|         link: false, | ||||
|         name: 'contact', | ||||
|         label: t`Contact`, | ||||
|         icon: 'user', | ||||
|         copy: true | ||||
|       } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user