mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
Compare commits
8 Commits
23dd220b2f
...
456070491f
| Author | SHA1 | Date | |
|---|---|---|---|
| 456070491f | |||
| c12beca4d7 | |||
| 910981645b | |||
| 82b5429d02 | |||
| 6c6f739fc0 | |||
| 001dafecb7 | |||
| 4bb3ada779 | |||
| 0b63dcb532 |
@@ -1,7 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { CellContext, ColumnDef } from '@tanstack/react-table';
|
import {
|
||||||
|
CellContext,
|
||||||
|
ColumnDef,
|
||||||
|
SortingState,
|
||||||
|
Updater,
|
||||||
|
} from '@tanstack/react-table';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
@@ -183,7 +188,8 @@ const FinanceTable = () => {
|
|||||||
bankIds: '',
|
bankIds: '',
|
||||||
customerIds: '',
|
customerIds: '',
|
||||||
supplierIds: '',
|
supplierIds: '',
|
||||||
sortBy: '',
|
sort_by: '',
|
||||||
|
orderBy: '',
|
||||||
startDate: '',
|
startDate: '',
|
||||||
endDate: '',
|
endDate: '',
|
||||||
bankNames: '',
|
bankNames: '',
|
||||||
@@ -197,7 +203,8 @@ const FinanceTable = () => {
|
|||||||
bankIds: 'bank_ids',
|
bankIds: 'bank_ids',
|
||||||
customerIds: 'customer_ids',
|
customerIds: 'customer_ids',
|
||||||
supplierIds: 'supplier_ids',
|
supplierIds: 'supplier_ids',
|
||||||
sortBy: 'sort_date',
|
sort_by: 'sort_by',
|
||||||
|
orderBy: 'sort_order',
|
||||||
startDate: 'start_date',
|
startDate: 'start_date',
|
||||||
endDate: 'end_date',
|
endDate: 'end_date',
|
||||||
},
|
},
|
||||||
@@ -248,7 +255,7 @@ const FinanceTable = () => {
|
|||||||
updateFilter('bankIds', values.bank_ids, true);
|
updateFilter('bankIds', values.bank_ids, true);
|
||||||
updateFilter('customerIds', values.customer_ids, true);
|
updateFilter('customerIds', values.customer_ids, true);
|
||||||
updateFilter('supplierIds', values.supplier_ids, true);
|
updateFilter('supplierIds', values.supplier_ids, true);
|
||||||
updateFilter('sortBy', values.sort_by, true);
|
updateFilter('sort_by', values.sort_by, true);
|
||||||
updateFilter('startDate', values.start_date, true);
|
updateFilter('startDate', values.start_date, true);
|
||||||
updateFilter('endDate', values.end_date, true);
|
updateFilter('endDate', values.end_date, true);
|
||||||
// Save display names for restoration on modal reopen
|
// Save display names for restoration on modal reopen
|
||||||
@@ -276,7 +283,8 @@ const FinanceTable = () => {
|
|||||||
updateFilter('bankIds', '', true);
|
updateFilter('bankIds', '', true);
|
||||||
updateFilter('customerIds', '', true);
|
updateFilter('customerIds', '', true);
|
||||||
updateFilter('supplierIds', '', true);
|
updateFilter('supplierIds', '', true);
|
||||||
updateFilter('sortBy', '', true);
|
updateFilter('sort_by', '', true);
|
||||||
|
updateFilter('orderBy', '', true);
|
||||||
updateFilter('startDate', '', true);
|
updateFilter('startDate', '', true);
|
||||||
updateFilter('endDate', '', true);
|
updateFilter('endDate', '', true);
|
||||||
updateFilter('bankNames', '', true);
|
updateFilter('bankNames', '', true);
|
||||||
@@ -394,6 +402,26 @@ const FinanceTable = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sorting: SortingState = tableFilterState.sort_by
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
id: tableFilterState.sort_by,
|
||||||
|
desc: tableFilterState.orderBy === 'desc',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const handleSortingChange = (updater: Updater<SortingState>) => {
|
||||||
|
const next = typeof updater === 'function' ? updater(sorting) : updater;
|
||||||
|
if (next.length > 0) {
|
||||||
|
updateFilter('sort_by', next[0].id, true);
|
||||||
|
updateFilter('orderBy', next[0].desc ? 'desc' : 'asc', true);
|
||||||
|
} else {
|
||||||
|
updateFilter('sort_by', '', true);
|
||||||
|
updateFilter('orderBy', '', true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
const endDate = filterFormik.values.end_date;
|
const endDate = filterFormik.values.end_date;
|
||||||
@@ -505,7 +533,7 @@ const FinanceTable = () => {
|
|||||||
// Restore sort by
|
// Restore sort by
|
||||||
const restoredSortBy =
|
const restoredSortBy =
|
||||||
sortByOptions.find(
|
sortByOptions.find(
|
||||||
(opt) => String(opt.value) === tableFilterState.sortBy
|
(opt) => String(opt.value) === tableFilterState.sort_by
|
||||||
) || null;
|
) || null;
|
||||||
setSelectedSortBy(restoredSortBy);
|
setSelectedSortBy(restoredSortBy);
|
||||||
|
|
||||||
@@ -516,7 +544,7 @@ const FinanceTable = () => {
|
|||||||
bank_ids: tableFilterState.bankIds || '',
|
bank_ids: tableFilterState.bankIds || '',
|
||||||
customer_ids: tableFilterState.customerIds || '',
|
customer_ids: tableFilterState.customerIds || '',
|
||||||
supplier_ids: tableFilterState.supplierIds || '',
|
supplier_ids: tableFilterState.supplierIds || '',
|
||||||
sort_by: tableFilterState.sortBy || '',
|
sort_by: tableFilterState.sort_by || '',
|
||||||
start_date: tableFilterState.startDate || '',
|
start_date: tableFilterState.startDate || '',
|
||||||
end_date: tableFilterState.endDate || '',
|
end_date: tableFilterState.endDate || '',
|
||||||
});
|
});
|
||||||
@@ -540,10 +568,12 @@ const FinanceTable = () => {
|
|||||||
{
|
{
|
||||||
header: 'ID',
|
header: 'ID',
|
||||||
accessorKey: 'payment_code',
|
accessorKey: 'payment_code',
|
||||||
|
enableSorting: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'References Number',
|
header: 'References Number',
|
||||||
accessorKey: 'reference_number',
|
accessorKey: 'reference_number',
|
||||||
|
enableSorting: true,
|
||||||
cell: (props: CellContext<Finance, unknown>) => {
|
cell: (props: CellContext<Finance, unknown>) => {
|
||||||
const value = props.row.original.reference_number;
|
const value = props.row.original.reference_number;
|
||||||
return <span>{value ?? '-'}</span>;
|
return <span>{value ?? '-'}</span>;
|
||||||
@@ -552,6 +582,7 @@ const FinanceTable = () => {
|
|||||||
{
|
{
|
||||||
header: 'Jenis Transaksi',
|
header: 'Jenis Transaksi',
|
||||||
accessorKey: 'transaction_type',
|
accessorKey: 'transaction_type',
|
||||||
|
enableSorting: true,
|
||||||
cell: (props: CellContext<Finance, unknown>) => {
|
cell: (props: CellContext<Finance, unknown>) => {
|
||||||
const value = props.row.original.transaction_type
|
const value = props.row.original.transaction_type
|
||||||
.split('_')
|
.split('_')
|
||||||
@@ -561,7 +592,8 @@ const FinanceTable = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Pihak',
|
header: 'Pihak',
|
||||||
accessorFn: (finance: Finance) => finance.party?.name,
|
accessorKey: 'customer_name',
|
||||||
|
enableSorting: true,
|
||||||
cell: (props: CellContext<Finance, unknown>) => {
|
cell: (props: CellContext<Finance, unknown>) => {
|
||||||
if (props.row.original.party?.id) {
|
if (props.row.original.party?.id) {
|
||||||
return <span>{props.row.original.party?.name}</span>;
|
return <span>{props.row.original.party?.name}</span>;
|
||||||
@@ -571,16 +603,22 @@ const FinanceTable = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Tanggal Pembayaran',
|
header: 'Tanggal Pembayaran',
|
||||||
accessorFn: (finance: Finance) =>
|
accessorKey: 'payment_date',
|
||||||
formatDate(finance.payment_date, 'DD MMM YYYY'),
|
enableSorting: true,
|
||||||
|
cell: (props) =>
|
||||||
|
formatDate(props.row.original.payment_date, 'DD MMM YYYY'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Tanggal Dibuat',
|
header: 'Tanggal Dibuat',
|
||||||
accessorFn: (finance) => formatDate(finance.created_at, 'DD MMM YYYY'),
|
accessorKey: 'created_at',
|
||||||
|
enableSorting: true,
|
||||||
|
cell: (props) =>
|
||||||
|
formatDate(props.row.original.created_at, 'DD MMM YYYY'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Metode Pembayaran',
|
header: 'Metode Pembayaran',
|
||||||
accessorKey: 'payment_method',
|
accessorKey: 'payment_method',
|
||||||
|
enableSorting: true,
|
||||||
cell: (props: CellContext<Finance, unknown>) => {
|
cell: (props: CellContext<Finance, unknown>) => {
|
||||||
const value = props.row.original.payment_method.split('_').join(' ');
|
const value = props.row.original.payment_method.split('_').join(' ');
|
||||||
return <span>{formatTitleCase(value)}</span>;
|
return <span>{formatTitleCase(value)}</span>;
|
||||||
@@ -588,20 +626,26 @@ const FinanceTable = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Bank',
|
header: 'Bank',
|
||||||
accessorFn: (finance: Finance) =>
|
accessorKey: 'bank',
|
||||||
finance.bank
|
enableSorting: true,
|
||||||
? `${finance.bank?.alias} - ${finance.bank?.account_number} - ${finance.bank?.owner}`
|
cell: (props) =>
|
||||||
|
props.row.original.bank
|
||||||
|
? `${props.row.original.bank?.alias} - ${props.row.original.bank?.account_number} - ${props.row.original.bank?.owner}`
|
||||||
: '-',
|
: '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Pengeluaran (Rp)',
|
header: 'Pengeluaran (Rp)',
|
||||||
accessorFn: (finance: Finance) =>
|
accessorKey: 'expense_amount',
|
||||||
formatCurrency(Math.abs(finance.expense_amount)),
|
enableSorting: true,
|
||||||
|
cell: (props) =>
|
||||||
|
formatCurrency(Math.abs(props.row.original.expense_amount)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Pemasukan (Rp)',
|
header: 'Pemasukan (Rp)',
|
||||||
accessorFn: (finance: Finance) =>
|
accessorKey: 'income_amount',
|
||||||
formatCurrency(Math.abs(finance.income_amount)),
|
enableSorting: true,
|
||||||
|
cell: (props) =>
|
||||||
|
formatCurrency(Math.abs(props.row.original.income_amount)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Aksi',
|
header: 'Aksi',
|
||||||
@@ -707,6 +751,7 @@ const FinanceTable = () => {
|
|||||||
'page',
|
'page',
|
||||||
'pageSize',
|
'pageSize',
|
||||||
'search',
|
'search',
|
||||||
|
'orderBy',
|
||||||
'bankNames',
|
'bankNames',
|
||||||
'customerNames',
|
'customerNames',
|
||||||
'supplierNames',
|
'supplierNames',
|
||||||
@@ -749,6 +794,9 @@ const FinanceTable = () => {
|
|||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onPageSizeChange={setPageSize}
|
onPageSizeChange={setPageSize}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
sorting={sorting}
|
||||||
|
setSorting={handleSortingChange}
|
||||||
|
manualSorting
|
||||||
className={{
|
className={{
|
||||||
containerClassName: cn('p-3 mb-0'),
|
containerClassName: cn('p-3 mb-0'),
|
||||||
headerColumnClassName: 'text-nowrap',
|
headerColumnClassName: 'text-nowrap',
|
||||||
|
|||||||
@@ -849,7 +849,11 @@ const DeliveryOrderFormModal = ({}: { initialValues?: Marketing }) => {
|
|||||||
className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold'
|
className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold'
|
||||||
disabled={deliveryRejected}
|
disabled={deliveryRejected}
|
||||||
>
|
>
|
||||||
Approve
|
{marketing?.data?.latest_approval?.step_number === 1 &&
|
||||||
|
'Approve'}
|
||||||
|
|
||||||
|
{marketing?.data?.latest_approval?.step_number === 2 &&
|
||||||
|
'Deliver Item'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ const SalesOrderFormModal = ({
|
|||||||
})
|
})
|
||||||
.filter((item) => Boolean(item)),
|
.filter((item) => Boolean(item)),
|
||||||
} as UpdateDeliveryOrderPayload);
|
} as UpdateDeliveryOrderPayload);
|
||||||
|
|
||||||
switch (modalAction) {
|
switch (modalAction) {
|
||||||
case 'add':
|
case 'add':
|
||||||
await createMarketingHandler(payload as CreateSalesOrderPayload);
|
await createMarketingHandler(payload as CreateSalesOrderPayload);
|
||||||
@@ -261,11 +262,7 @@ const SalesOrderFormModal = ({
|
|||||||
|
|
||||||
// ===== Formik Error List =====
|
// ===== Formik Error List =====
|
||||||
const { formErrorList, setFormErrorList, close, handleFormSubmit } =
|
const { formErrorList, setFormErrorList, close, handleFormSubmit } =
|
||||||
useFormikErrorList(formik, {
|
useFormikErrorList(formik);
|
||||||
onAfterSubmit: () => {
|
|
||||||
router.push('/marketing');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// ================== FORM REPEATER HANDLER ==================
|
// ================== FORM REPEATER HANDLER ==================
|
||||||
const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
||||||
|
|||||||
@@ -71,14 +71,14 @@ export const DeliveryOrderSchema: Yup.ObjectSchema<DeliveryOrderSchemaType> =
|
|||||||
.required('Pengiriman wajib diisi!')
|
.required('Pengiriman wajib diisi!')
|
||||||
.test(
|
.test(
|
||||||
'at-least-one-valid-row',
|
'at-least-one-valid-row',
|
||||||
'Minimal harus ada satu baris pengiriman yang lengkap diisi!',
|
'Seluruh data pengiriman harus diisi lengkap!',
|
||||||
function (items) {
|
function (items) {
|
||||||
if (!items || items.length === 0) return false;
|
if (!items || items.length === 0) return false;
|
||||||
|
|
||||||
// VALIDASI: minimal 1 item valid full
|
// VALIDASI: seluruh item harus valid full
|
||||||
const itemSchema = DeliveryOrderProductSchema;
|
const itemSchema = DeliveryOrderProductSchema;
|
||||||
|
|
||||||
const hasValidItem = items.some((item) => {
|
const hasValidItem = items.every((item) => {
|
||||||
if (!item) return false;
|
if (!item) return false;
|
||||||
return itemSchema.isValidSync(item, { abortEarly: true });
|
return itemSchema.isValidSync(item, { abortEarly: true });
|
||||||
});
|
});
|
||||||
|
|||||||
+6
-16
@@ -146,15 +146,6 @@ const DeliveryOrderProductForm = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ============ Fetch Data ============
|
// ============ Fetch Data ============
|
||||||
const { data: productData } = useSWR(
|
|
||||||
selectedProduct?.value
|
|
||||||
? ProductApi.basePath + '/' + selectedProduct?.value
|
|
||||||
: null,
|
|
||||||
() =>
|
|
||||||
selectedProduct?.value
|
|
||||||
? ProductApi.getSingle(Number(selectedProduct?.value))
|
|
||||||
: undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
// Options Week dari minggu 1 - 22
|
// Options Week dari minggu 1 - 22
|
||||||
// const optionsWeek = useMemo(() => {
|
// const optionsWeek = useMemo(() => {
|
||||||
@@ -440,7 +431,8 @@ const DeliveryOrderProductForm = ({
|
|||||||
handleBlurField(currentInput);
|
handleBlurField(currentInput);
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
'uom',
|
'uom',
|
||||||
isResponseSuccess(productData) ? productData?.data?.uom?.name : ''
|
initialValues?.marketing_product?.product_warehouse_data?.product?.uom
|
||||||
|
?.name ?? ''
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -813,9 +805,8 @@ const DeliveryOrderProductForm = ({
|
|||||||
endAdornment={
|
endAdornment={
|
||||||
<div className='flex items-center gap-2'>
|
<div className='flex items-center gap-2'>
|
||||||
<span className='text-sm text-gray-500'>
|
<span className='text-sm text-gray-500'>
|
||||||
{isResponseSuccess(productData)
|
{initialValues?.marketing_product?.product_warehouse_data
|
||||||
? productData?.data?.uom.name
|
?.product?.uom?.name ?? ''}
|
||||||
: ''}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -826,9 +817,8 @@ const DeliveryOrderProductForm = ({
|
|||||||
(item) => item.id === formik.values.marketing_product_id
|
(item) => item.id === formik.values.marketing_product_id
|
||||||
)?.qty +
|
)?.qty +
|
||||||
' ' +
|
' ' +
|
||||||
(isResponseSuccess(productData)
|
(initialValues?.marketing_product?.product_warehouse_data
|
||||||
? productData?.data?.uom.name
|
?.product?.uom?.name ?? '')
|
||||||
: '')
|
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -252,6 +252,11 @@ const SalesOrderProductForm = ({
|
|||||||
setSelectedProductWarehouse(productWarehouse || null);
|
setSelectedProductWarehouse(productWarehouse || null);
|
||||||
formik.setFieldValue('product_warehouse_data', productWarehouse || null);
|
formik.setFieldValue('product_warehouse_data', productWarehouse || null);
|
||||||
formik.setFieldValue('qty', productWarehouse?.quantity);
|
formik.setFieldValue('qty', productWarehouse?.quantity);
|
||||||
|
|
||||||
|
if (productWarehouse?.quantity) {
|
||||||
|
handleFieldChange('qty', productWarehouse?.quantity);
|
||||||
|
}
|
||||||
|
|
||||||
formik.setFieldValue('uom', productWarehouse?.product?.uom?.name || '');
|
formik.setFieldValue('uom', productWarehouse?.product?.uom?.name || '');
|
||||||
if (
|
if (
|
||||||
productWarehouse?.week !== undefined &&
|
productWarehouse?.week !== undefined &&
|
||||||
|
|||||||
Reference in New Issue
Block a user