mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
refactor(FE-208): refactor PurchaseOrderDetail to integrate Purchase data and update Goods Receipt structure
This commit is contained in:
@@ -11,168 +11,173 @@ import Table from '@/components/Table';
|
|||||||
import { BaseGroupedApproval } from '@/types/api/api-general';
|
import { BaseGroupedApproval } from '@/types/api/api-general';
|
||||||
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
|
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
|
import { Purchase, PurchaseItem } from '@/types/api/purchase/purchase';
|
||||||
|
import {
|
||||||
|
createdUser,
|
||||||
|
dummyAreas,
|
||||||
|
dummyLocations,
|
||||||
|
dummyProductWarehouses,
|
||||||
|
dummyWarehouses,
|
||||||
|
} from '@/dummy/marketing.dummy';
|
||||||
|
|
||||||
interface PurchaseOrderDetailProps {
|
interface PurchaseOrderDetailProps {
|
||||||
type?: 'detail' | 'edit';
|
type?: 'detail' | 'edit';
|
||||||
|
data?: Purchase;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PurchaseOrderItem {
|
const dummyPurchaseData: Purchase = {
|
||||||
id: number;
|
id: 1,
|
||||||
product: string;
|
pr_number: 'PR-MBU-01837',
|
||||||
productType: string;
|
po_number: 'Belum dibuat',
|
||||||
quantity: number;
|
po_date: '2025-01-10T00:00:00Z',
|
||||||
unit: string;
|
supplier: {
|
||||||
unitPrice: number;
|
id: 1,
|
||||||
total: number;
|
name: 'PT. CHAROEN POKPHAND JAYA FARM',
|
||||||
}
|
alias: '',
|
||||||
|
pic: '',
|
||||||
interface GoodsReceiptItem {
|
type: '',
|
||||||
id: number;
|
category: '',
|
||||||
tanggalPenerimaan: string;
|
hatchery: '',
|
||||||
gudangTujuan: string;
|
phone: '',
|
||||||
noSuratJalan: string;
|
email: '',
|
||||||
dokumenSuratJalan: string;
|
address: '-',
|
||||||
noArmada: string;
|
npwp: '',
|
||||||
pengangkut: string;
|
account_number: '',
|
||||||
jumlahTotal: string;
|
due_date: 0,
|
||||||
jumlahDiterima: string;
|
balance: 0,
|
||||||
jumlahRetur: string;
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
ekspedisi: string;
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
transportPerItem: string;
|
created_user: createdUser,
|
||||||
transportTotal: string;
|
},
|
||||||
status?: 'diterima' | 'belum-diterima';
|
credit_term: 30,
|
||||||
}
|
due_date: '2025-11-13T00:00:00Z',
|
||||||
|
grand_total: 65000000,
|
||||||
interface PurchaseOrderInfo {
|
notes: null,
|
||||||
businessUnit: string;
|
area: dummyAreas[0],
|
||||||
area: string;
|
location: dummyLocations[0],
|
||||||
location: string;
|
items: [
|
||||||
warehouse: string;
|
{
|
||||||
vendorName: string;
|
id: 1,
|
||||||
vendorAddress: string;
|
purchase_id: 1,
|
||||||
dueDate: string;
|
product: {
|
||||||
number: string;
|
id: 1,
|
||||||
poNumber: string;
|
name: 'CP Vaksin',
|
||||||
}
|
brand: '',
|
||||||
|
sku: '',
|
||||||
const dummyPurchaseOrderInfo: PurchaseOrderInfo = {
|
product_price: 0,
|
||||||
businessUnit: 'PT MITRA BERLIAN UNGGAS',
|
selling_price: 0,
|
||||||
area: 'Banten 2',
|
tax: 0,
|
||||||
location: 'FARM PASIR TAPLOK',
|
expiry_period: 0,
|
||||||
warehouse: 'GUDANG PASIR TAPLOK 1',
|
uom: {
|
||||||
vendorName: 'PT. CHAROEN POKPHAND JAYA FARM',
|
id: 1,
|
||||||
vendorAddress: '-',
|
name: 'Ekor',
|
||||||
dueDate: '13-Nov-2025 (1 hari)',
|
created_user: {
|
||||||
number: 'PR-MBU-01837',
|
id: 1,
|
||||||
poNumber: 'Belum dibuat',
|
id_user: 1,
|
||||||
|
email: 'hello@gmail.com',
|
||||||
|
name: 'Admin',
|
||||||
|
},
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
product_category: {
|
||||||
|
id: 1,
|
||||||
|
code: 'DOC',
|
||||||
|
name: 'DOC',
|
||||||
|
created_user: {
|
||||||
|
id: 1,
|
||||||
|
id_user: 1,
|
||||||
|
email: 'hello@gmail.com',
|
||||||
|
name: 'Admin',
|
||||||
|
},
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
suppliers: [],
|
||||||
|
flags: [],
|
||||||
|
created_user: {
|
||||||
|
id: 1,
|
||||||
|
id_user: 1,
|
||||||
|
email: 'hello@gmail.com',
|
||||||
|
name: 'Admin',
|
||||||
|
},
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
product_warehouse: dummyProductWarehouses[0],
|
||||||
|
quantity: 10000,
|
||||||
|
sub_qty: 10000,
|
||||||
|
total_qty: 10000,
|
||||||
|
total_used: 0,
|
||||||
|
price: 6500,
|
||||||
|
total_price: 65000000,
|
||||||
|
received_date: null,
|
||||||
|
travel_number: null,
|
||||||
|
travel_number_docs: null,
|
||||||
|
vehicle_number: null,
|
||||||
|
warehouse: dummyWarehouses[0],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
created_at: '2025-01-10T00:00:00Z',
|
||||||
|
updated_at: '2025-01-10T00:00:00Z',
|
||||||
|
created_by: 1,
|
||||||
|
deleted_at: null,
|
||||||
|
created_user: createdUser,
|
||||||
|
warehouse: dummyWarehouses[0],
|
||||||
};
|
};
|
||||||
|
|
||||||
const dummyPurchaseOrderItems: PurchaseOrderItem[] = [
|
// Goods Receipt data - using items from PurchaseItem with received data
|
||||||
|
const dummyGoodsReceiptItems: PurchaseItem[] = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
product: 'CP Vaksin',
|
purchase_id: 1,
|
||||||
productType: 'DOC',
|
product: {
|
||||||
|
id: 1,
|
||||||
|
product_category: {
|
||||||
|
id: 1,
|
||||||
|
code: 'DOC',
|
||||||
|
name: 'DOC',
|
||||||
|
created_user: createdUser,
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
name: 'CP Vaksin',
|
||||||
|
brand: '',
|
||||||
|
sku: '',
|
||||||
|
product_price: 0,
|
||||||
|
selling_price: 0,
|
||||||
|
tax: 0,
|
||||||
|
expiry_period: 0,
|
||||||
|
uom: {
|
||||||
|
id: 1,
|
||||||
|
name: 'Ekor',
|
||||||
|
created_user: createdUser,
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
suppliers: [],
|
||||||
|
flags: [],
|
||||||
|
created_user: {
|
||||||
|
id: 1,
|
||||||
|
id_user: 1,
|
||||||
|
email: 'hello@gmail.com',
|
||||||
|
name: 'Admin',
|
||||||
|
},
|
||||||
|
created_at: '2025-01-01T00:00:00Z',
|
||||||
|
updated_at: '2025-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
product_warehouse: dummyProductWarehouses[0],
|
||||||
quantity: 10000,
|
quantity: 10000,
|
||||||
unit: 'Ekor',
|
sub_qty: 10000,
|
||||||
unitPrice: 6500,
|
total_qty: 10000,
|
||||||
total: 65000000,
|
total_used: 0,
|
||||||
},
|
price: 6500,
|
||||||
];
|
total_price: 65000000,
|
||||||
|
received_date: '2025-01-15T00:00:00Z',
|
||||||
const dummyGoodsReceiptItems: GoodsReceiptItem[] = [
|
travel_number: 'NSJ-1',
|
||||||
{
|
travel_number_docs: '/documents/nsj-1.pdf',
|
||||||
id: 1,
|
vehicle_number: 'NAP-1',
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
warehouse: dummyWarehouses[0],
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'details',
|
|
||||||
jumlahRetur: 'details',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp1.000,00',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'details',
|
|
||||||
jumlahRetur: 'Rp0',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp10.000,00',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'Jumlah Produk Diterima',
|
|
||||||
jumlahRetur: 'Rp0.000,00',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp10.000,00',
|
|
||||||
status: 'diterima',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'Jumlah Produk Belum Diterima',
|
|
||||||
jumlahRetur: 'Rp0.000,00',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp10.000,00',
|
|
||||||
status: 'belum-diterima',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'Nominal Produk Diterima',
|
|
||||||
jumlahRetur: 'Rp0.000,00',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp10.000,00',
|
|
||||||
status: 'diterima',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
tanggalPenerimaan: '1 Jan 1970 00:00',
|
|
||||||
gudangTujuan: 'Gudang A',
|
|
||||||
noSuratJalan: 'NSJ-1',
|
|
||||||
dokumenSuratJalan: 'details',
|
|
||||||
noArmada: 'NAP-1',
|
|
||||||
pengangkut: 'details',
|
|
||||||
jumlahTotal: 'Rp10.000,00',
|
|
||||||
jumlahDiterima: 'Nominal Produk Belum Diterima',
|
|
||||||
jumlahRetur: 'Rp0.000,00',
|
|
||||||
ekspedisi: 'Ekspedisi 1',
|
|
||||||
transportPerItem: 'details',
|
|
||||||
transportTotal: 'Rp10.000,00',
|
|
||||||
status: 'belum-diterima',
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -274,10 +279,13 @@ const dummyGroupedApprovals: BaseGroupedApproval[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
const PurchaseOrderDetail = ({
|
||||||
|
type = 'detail',
|
||||||
|
data,
|
||||||
|
}: PurchaseOrderDetailProps) => {
|
||||||
// ===== STATIC DATA =====
|
// ===== STATIC DATA =====
|
||||||
const purchaseOrderInfo = dummyPurchaseOrderInfo;
|
const purchaseData = data || dummyPurchaseData;
|
||||||
const purchaseOrderItems = dummyPurchaseOrderItems;
|
const purchaseOrderItems = purchaseData.items || [];
|
||||||
const goodsReceiptItems = dummyGoodsReceiptItems;
|
const goodsReceiptItems = dummyGoodsReceiptItems;
|
||||||
const groupedApprovals = dummyGroupedApprovals;
|
const groupedApprovals = dummyGroupedApprovals;
|
||||||
const latestApproval =
|
const latestApproval =
|
||||||
@@ -300,7 +308,10 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
}, [groupedApprovals, latestApproval]);
|
}, [groupedApprovals, latestApproval]);
|
||||||
|
|
||||||
const totalBeforeTax = useMemo(() => {
|
const totalBeforeTax = useMemo(() => {
|
||||||
return purchaseOrderItems.reduce((sum, item) => sum + item.total, 0);
|
return purchaseOrderItems.reduce(
|
||||||
|
(sum, item) => sum + (item.total_price || 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
}, [purchaseOrderItems]);
|
}, [purchaseOrderItems]);
|
||||||
|
|
||||||
const formatCurrency = (value: number) => {
|
const formatCurrency = (value: number) => {
|
||||||
@@ -315,14 +326,17 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
return new Intl.NumberFormat('id-ID').format(value);
|
return new Intl.NumberFormat('id-ID').format(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const purchaseOrderColumns: ColumnDef<PurchaseOrderItem>[] = [
|
const purchaseOrderColumns: ColumnDef<PurchaseItem>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: 'product',
|
accessorKey: 'product.name',
|
||||||
header: 'Produk',
|
header: 'Produk',
|
||||||
|
cell: (props) => props.row.original.product?.name || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'productType',
|
accessorKey: 'product.product_category.name',
|
||||||
header: 'Jenis Produk',
|
header: 'Jenis Produk',
|
||||||
|
cell: (props) =>
|
||||||
|
props.row.original.product?.product_category?.name || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'quantity',
|
accessorKey: 'quantity',
|
||||||
@@ -330,69 +344,83 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
cell: (props) => formatNumber(props.getValue() as number),
|
cell: (props) => formatNumber(props.getValue() as number),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'unit',
|
accessorKey: 'product.uom.name',
|
||||||
header: 'Satuan',
|
header: 'Satuan',
|
||||||
|
cell: (props) => props.row.original.product?.uom?.name || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'unitPrice',
|
accessorKey: 'price',
|
||||||
header: 'Harga Satuan',
|
header: 'Harga Satuan',
|
||||||
cell: (props) => formatCurrency(props.getValue() as number),
|
cell: (props) => formatCurrency(props.getValue() as number),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'total',
|
accessorKey: 'total_price',
|
||||||
header: 'Total (Rp.)',
|
header: 'Total (Rp.)',
|
||||||
cell: (props) => formatCurrency(props.getValue() as number),
|
cell: (props) => formatCurrency(props.getValue() as number),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const goodsReceiptColumns: ColumnDef<GoodsReceiptItem>[] = [
|
const goodsReceiptColumns: ColumnDef<PurchaseItem>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: 'tanggalPenerimaan',
|
accessorKey: 'received_date',
|
||||||
header: 'Tanggal Penerimaan',
|
header: 'Tanggal Penerimaan',
|
||||||
|
cell: (props) =>
|
||||||
|
props.row.original.received_date
|
||||||
|
? new Date(props.row.original.received_date).toLocaleDateString(
|
||||||
|
'id-ID'
|
||||||
|
)
|
||||||
|
: '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'gudangTujuan',
|
accessorKey: 'product_warehouse.warehouse.name',
|
||||||
header: 'Gudang Tujuan',
|
header: 'Gudang Tujuan',
|
||||||
|
cell: (props) =>
|
||||||
|
props.row.original.product_warehouse?.warehouse?.name || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'noSuratJalan',
|
accessorKey: 'travel_number',
|
||||||
header: 'No. Surat Jalan',
|
header: 'No. Surat Jalan',
|
||||||
|
cell: (props) => props.row.original.travel_number || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'dokumenSuratJalan',
|
accessorKey: 'travel_number_docs',
|
||||||
header: 'Dokumen Surat Jalan',
|
header: 'Dokumen Surat Jalan',
|
||||||
|
cell: (props) => props.row.original.travel_number_docs || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'noArmada',
|
accessorKey: 'vehicle_number',
|
||||||
header: 'No. Armada',
|
header: 'No. Armada',
|
||||||
|
cell: (props) => props.row.original.vehicle_number || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'pengangkut',
|
accessorKey: 'pengangkut',
|
||||||
header: 'Pengangkut',
|
header: 'Pengangkut',
|
||||||
|
cell: (props) => props.row.original.product?.name || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'jumlahTotal',
|
accessorKey: 'quantity',
|
||||||
header: 'Jumlah Total',
|
header: 'Jumlah Total',
|
||||||
|
cell: (props) => formatNumber(props.getValue() as number),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'jumlahDiterima',
|
accessorKey: 'sub_qty',
|
||||||
header: 'Jumlah Diterima',
|
header: 'Jumlah Diterima',
|
||||||
},
|
cell: (props) => formatNumber(props.getValue() as number),
|
||||||
{
|
|
||||||
accessorKey: 'jumlahRetur',
|
|
||||||
header: 'Jumlah Retur',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'ekspedisi',
|
accessorKey: 'ekspedisi',
|
||||||
header: 'Ekspedisi',
|
header: 'Ekspedisi',
|
||||||
|
cell: (props) => 'Ekspedisi 1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'transportPerItem',
|
accessorKey: 'price',
|
||||||
header: 'Transport /Item',
|
header: 'Transport /Item',
|
||||||
|
cell: (props) => formatCurrency(props.getValue() as number),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'transportTotal',
|
accessorKey: 'total_price',
|
||||||
header: 'Transport Total',
|
header: 'Transport Total',
|
||||||
|
cell: (props) => formatCurrency(props.getValue() as number),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -458,23 +486,13 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
<div className='grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-4'>
|
<div className='grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-4'>
|
||||||
{/* Kolom 1 */}
|
{/* Kolom 1 */}
|
||||||
<div className='space-y-4'>
|
<div className='space-y-4'>
|
||||||
<div className='group'>
|
|
||||||
<div className='flex items-start'>
|
|
||||||
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
|
||||||
Unit Bisnis
|
|
||||||
</span>
|
|
||||||
<span className='text-gray-900 font-medium ml-3 break-all'>
|
|
||||||
{purchaseOrderInfo.businessUnit}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='group'>
|
<div className='group'>
|
||||||
<div className='flex items-start'>
|
<div className='flex items-start'>
|
||||||
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
||||||
Area
|
Area
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all'>
|
<span className='text-gray-900 ml-3 break-all'>
|
||||||
{purchaseOrderInfo.area}
|
{purchaseData.area?.name || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -484,7 +502,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
Lokasi
|
Lokasi
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all'>
|
<span className='text-gray-900 ml-3 break-all'>
|
||||||
{purchaseOrderInfo.location}
|
{purchaseData.location?.name || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -494,7 +512,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
Gudang Penyimpanan
|
Gudang Penyimpanan
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all'>
|
<span className='text-gray-900 ml-3 break-all'>
|
||||||
{purchaseOrderInfo.warehouse}
|
{purchaseData.warehouse?.name || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -505,20 +523,20 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
<div className='group'>
|
<div className='group'>
|
||||||
<div className='flex items-start'>
|
<div className='flex items-start'>
|
||||||
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
||||||
Nama Vendor
|
Nama Supplier
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 font-medium ml-3 break-all'>
|
<span className='text-gray-900 font-medium ml-3 break-all'>
|
||||||
{purchaseOrderInfo.vendorName}
|
{purchaseData.supplier?.name || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='group'>
|
<div className='group'>
|
||||||
<div className='flex items-start'>
|
<div className='flex items-start'>
|
||||||
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
<span className='font-medium text-gray-600 min-w-[140px] flex-shrink-0'>
|
||||||
Alamat Vendor
|
Alamat Supplier
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all'>
|
<span className='text-gray-900 ml-3 break-all'>
|
||||||
{purchaseOrderInfo.vendorAddress}
|
{purchaseData.supplier?.address || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -528,7 +546,15 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
Tgl. Jatuh Tempo
|
Tgl. Jatuh Tempo
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all'>
|
<span className='text-gray-900 ml-3 break-all'>
|
||||||
{purchaseOrderInfo.dueDate}
|
{new Date(purchaseData.due_date).toLocaleDateString(
|
||||||
|
'id-ID',
|
||||||
|
{
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric',
|
||||||
|
}
|
||||||
|
)}{' '}
|
||||||
|
({purchaseData.credit_term} hari)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -538,7 +564,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
Nomor
|
Nomor
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all font-mono text-sm'>
|
<span className='text-gray-900 ml-3 break-all font-mono text-sm'>
|
||||||
{purchaseOrderInfo.number}
|
{purchaseData.pr_number}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -548,7 +574,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
Nomor PO
|
Nomor PO
|
||||||
</span>
|
</span>
|
||||||
<span className='text-gray-900 ml-3 break-all font-mono text-sm'>
|
<span className='text-gray-900 ml-3 break-all font-mono text-sm'>
|
||||||
{purchaseOrderInfo.poNumber}
|
{purchaseData.po_number || 'Belum dibuat'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -564,7 +590,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
<div className='rounded-lg border border-gray-200 overflow-hidden'>
|
<div className='rounded-lg border border-gray-200 overflow-hidden'>
|
||||||
{/* Product Table */}
|
{/* Product Table */}
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
<Table<PurchaseOrderItem>
|
<Table<PurchaseItem>
|
||||||
data={purchaseOrderItems}
|
data={purchaseOrderItems}
|
||||||
columns={purchaseOrderColumns}
|
columns={purchaseOrderColumns}
|
||||||
isLoading={false}
|
isLoading={false}
|
||||||
@@ -588,7 +614,9 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
{/* Catatan Section */}
|
{/* Catatan Section */}
|
||||||
<div className='lg:col-span-3 p-6 border-r border-gray-200'>
|
<div className='lg:col-span-3 p-6 border-r border-gray-200'>
|
||||||
<h4 className='font-medium text-gray-700 mb-3'>Catatan</h4>
|
<h4 className='font-medium text-gray-700 mb-3'>Catatan</h4>
|
||||||
<div className='text-gray-900 min-h-[60px] italic text-sm'></div>
|
<div className='text-gray-900 min-h-[60px] italic text-sm'>
|
||||||
|
{purchaseData.notes || 'Tidak ada catatan'}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Summary Section */}
|
{/* Summary Section */}
|
||||||
@@ -626,7 +654,7 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
>
|
>
|
||||||
<div className='rounded-lg border border-gray-200 overflow-hidden'>
|
<div className='rounded-lg border border-gray-200 overflow-hidden'>
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
<Table<GoodsReceiptItem>
|
<Table<PurchaseItem>
|
||||||
data={goodsReceiptItems}
|
data={goodsReceiptItems}
|
||||||
columns={goodsReceiptColumns}
|
columns={goodsReceiptColumns}
|
||||||
isLoading={false}
|
isLoading={false}
|
||||||
@@ -639,7 +667,8 @@ const PurchaseOrderDetail = ({ type = 'detail' }: PurchaseOrderDetailProps) => {
|
|||||||
'px-4 py-3 text-sm font-semibold text-gray-700 text-left whitespace-nowrap',
|
'px-4 py-3 text-sm font-semibold text-gray-700 text-left whitespace-nowrap',
|
||||||
bodyRowClassName:
|
bodyRowClassName:
|
||||||
'border-b border-gray-100 hover:bg-gray-50 transition-colors',
|
'border-b border-gray-100 hover:bg-gray-50 transition-colors',
|
||||||
bodyColumnClassName: 'px-4 py-3 text-sm text-gray-900 whitespace-nowrap',
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-sm text-gray-900 whitespace-nowrap',
|
||||||
paginationClassName: 'hidden',
|
paginationClassName: 'hidden',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user