Merge branch 'development' of gitlab.com:mbugroup/lti-web-client into dev/restu

This commit is contained in:
rstubryan
2025-12-31 13:57:28 +07:00
9 changed files with 235 additions and 61 deletions
@@ -3,7 +3,7 @@
import Card from '@/components/Card'; import Card from '@/components/Card';
import Table from '@/components/Table'; import Table from '@/components/Table';
import { formatCurrency, formatNumber } from '@/lib/helper'; import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
import { import {
RowSapronakCalculation, RowSapronakCalculation,
TotalSapronakCalculation, TotalSapronakCalculation,
@@ -38,23 +38,29 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'Tanggal', header: 'Tanggal',
accessorKey: 'tanggal', accessorKey: 'tanggal',
cell: (props) => (props.getValue() as string) || '-', cell: (props) =>
props.row.original.tanggal
? formatDate(props.row.original.tanggal, 'DD MMM YYYY')
: '-',
footer: 'Total', footer: 'Total',
}, },
{ {
header: 'No. Referensi', header: 'No. Referensi',
accessorKey: 'no_referensi', accessorKey: 'no_referensi',
cell: (props) => (props.getValue() as string) || '-', cell: (props) => (props.row.original.no_referensi as string) || '-',
footer: '', footer: '',
}, },
{ {
header: 'QTY Masuk', header: 'QTY Masuk',
accessorKey: 'qty_masuk', accessorKey: 'qty_masuk',
cell: (props) => formatNumber(props.getValue() as number), cell: (props) =>
props.row.original.qty_masuk
? formatNumber(props.row.original.qty_masuk as number)
: '-',
footer: total footer: total
? () => ( ? () => (
<div className='font-semibold text-gray-900'> <div className='font-semibold text-gray-900'>
{formatNumber(total?.qty_masuk)} {total?.qty_masuk ? formatNumber(total?.qty_masuk) : '-'}
</div> </div>
) )
: '', : '',
@@ -62,11 +68,14 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'QTY Keluar', header: 'QTY Keluar',
accessorKey: 'qty_keluar', accessorKey: 'qty_keluar',
cell: (props) => formatNumber(props.getValue() as number), cell: (props) =>
props.row.original.qty_keluar
? formatNumber(props.row.original.qty_keluar as number)
: '-',
footer: total footer: total
? () => ( ? () => (
<div className='font-semibold text-gray-900'> <div className='font-semibold text-gray-900'>
{formatNumber(total?.qty_keluar)} {total?.qty_keluar ? formatNumber(total?.qty_keluar) : '-'}
</div> </div>
) )
: '', : '',
@@ -74,11 +83,14 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'QTY Pakai', header: 'QTY Pakai',
accessorKey: 'qty_pakai', accessorKey: 'qty_pakai',
cell: (props) => formatNumber(props.getValue() as number), cell: (props) =>
props.row.original.qty_pakai
? formatNumber(props.row.original.qty_pakai as number)
: '-',
footer: total footer: total
? () => ( ? () => (
<div className='font-semibold text-gray-900'> <div className='font-semibold text-gray-900'>
{formatNumber(total?.qty_pakai)} {total?.qty_pakai ? formatNumber(total?.qty_pakai) : '-'}
</div> </div>
) )
: '', : '',
@@ -86,23 +98,28 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'Uraian', header: 'Uraian',
accessorKey: 'uraian', accessorKey: 'uraian',
cell: (props) => (props.getValue() as string) || '-', cell: (props) => (props.row.original.uraian as string) || '-',
footer: '', footer: '',
}, },
{ {
header: 'Kategori Produk', header: 'Kategori Produk',
accessorKey: 'kategori_produk', accessorKey: 'kategori_produk',
cell: (props) => (props.getValue() as string) || '-', cell: (props) => (props.row.original.kategori_produk as string) || '-',
footer: '', footer: '',
}, },
{ {
header: 'Harga Beli/Qty (Rp)', header: 'Harga Beli/Qty (Rp)',
accessorKey: 'harga_beli_per_qty', accessorKey: 'harga_beli_per_qty',
cell: (props) => formatCurrency(props.getValue() as number), cell: (props) =>
props.row.original.harga_beli_per_qty
? formatCurrency(props.row.original.harga_beli_per_qty as number)
: '-',
footer: total footer: total
? () => ( ? () => (
<div className='font-semibold text-gray-900'> <div className='font-semibold text-gray-900'>
{formatCurrency(total?.harga_beli_per_qty)} {total?.harga_beli_per_qty
? formatCurrency(total?.harga_beli_per_qty)
: '-'}
</div> </div>
) )
: '', : '',
@@ -110,11 +127,14 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'Total Harga (Rp)', header: 'Total Harga (Rp)',
accessorKey: 'total_harga', accessorKey: 'total_harga',
cell: (props) => formatCurrency(props.getValue() as number), cell: (props) =>
props.row.original.total_harga
? formatCurrency(props.row.original.total_harga as number)
: '-',
footer: total footer: total
? () => ( ? () => (
<div className='font-semibold text-gray-900'> <div className='font-semibold text-gray-900'>
{formatCurrency(total?.total_harga)} {total?.total_harga ? formatCurrency(total?.total_harga) : '-'}
</div> </div>
) )
: '', : '',
@@ -122,7 +142,7 @@ const ClosingSapronakCalculationTable = ({
{ {
header: 'Keterangan', header: 'Keterangan',
accessorKey: 'keterangan', accessorKey: 'keterangan',
cell: (props) => (props.getValue() as string) || '-', cell: (props) => (props.row.original.keterangan as string) || '-',
footer: '', footer: '',
}, },
]; ];
@@ -188,6 +188,8 @@ const FormFinanceAdd = ({
value={formik.values.party_type_option} value={formik.values.party_type_option}
onChange={(value) => { onChange={(value) => {
formik.setFieldValue('party_type_option', value); formik.setFieldValue('party_type_option', value);
formik.setFieldValue('party_id_option', null);
formik.setFieldValue('party_account_number', '');
}} }}
isError={Boolean( isError={Boolean(
formik.touched.party_type_option && formik.touched.party_type_option &&
@@ -189,6 +189,8 @@ const FormFinanceAddInitialBalance = ({
value={formik.values.party_type_option} value={formik.values.party_type_option}
onChange={(value) => { onChange={(value) => {
formik.setFieldValue('party_type_option', value); formik.setFieldValue('party_type_option', value);
formik.setFieldValue('party_id_option', null);
formik.setFieldValue('party_account_number', '');
}} }}
isError={Boolean( isError={Boolean(
formik.touched.party_type_option && formik.touched.party_type_option &&
@@ -52,7 +52,7 @@ const RowsOptionsMenu = ({
)} )}
> >
<div className='flex flex-col gap-1'> <div className='flex flex-col gap-1'>
<RequirePermission permissions='lti.marketing.delivery_order.detail'> {/* <RequirePermission permissions='lti.marketing.delivery_order.detail'>
<Button <Button
href={`/marketing/detail?marketingId=${props.row.original.id}`} href={`/marketing/detail?marketingId=${props.row.original.id}`}
variant='ghost' variant='ghost'
@@ -62,15 +62,46 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:eye-outline' width={16} height={16} /> <Icon icon='mdi:eye-outline' width={16} height={16} />
Detail Detail
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
href={`/marketing/detail?marketingId=${props.row.original.id}`}
variant='ghost'
color='primary'
className='justify-start text-sm'
>
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
{props.row.original.latest_approval.step_number != 1 && ( {props.row.original.latest_approval.step_number != 1 && (
<RequirePermission <>
permissions={ {/* <RequirePermission
props.row.original.latest_approval.step_number == 3 permissions={
? 'lti.marketing.delivery_order.update' props.row.original.latest_approval.step_number == 3
: 'lti.marketing.delivery_order.create' ? 'lti.marketing.delivery_order.update'
} : 'lti.marketing.delivery_order.create'
> }
>
<Button
href={
props.row.original.latest_approval.step_number == 3
? `/marketing/detail/delivery-orders/edit?marketingId=${props.row.original.id}`
: props.row.original.latest_approval.step_number == 2
? `/marketing/add/delivery-orders?marketingId=${props.row.original.id}`
: undefined
}
onClick={() => {
if (props.row.original.latest_approval.step_number == 2) {
deliveryClickHandler?.();
}
}}
variant='ghost'
color='success'
className='justify-start text-sm'
>
<Icon icon='mdi:truck' width={16} height={16} />
Deliver
</Button>
</RequirePermission> */}
<Button <Button
href={ href={
props.row.original.latest_approval.step_number == 3 props.row.original.latest_approval.step_number == 3
@@ -91,10 +122,21 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:truck' width={16} height={16} /> <Icon icon='mdi:truck' width={16} height={16} />
Deliver Deliver
</Button> </Button>
</RequirePermission> </>
)} )}
{props.row.original.latest_approval.step_number != 3 && ( {props.row.original.latest_approval.step_number != 3 && (
<RequirePermission permissions='lti.marketing.sales_order.update'> <>
{/* <RequirePermission permissions='lti.marketing.sales_order.update'>
<Button
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
variant='ghost'
color='warning'
className='justify-start text-sm'
>
<Icon icon='mdi:pencil-outline' width={16} height={16} />
Edit
</Button>
</RequirePermission> */}
<Button <Button
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`} href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
variant='ghost' variant='ghost'
@@ -104,9 +146,9 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:pencil-outline' width={16} height={16} /> <Icon icon='mdi:pencil-outline' width={16} height={16} />
Edit Edit
</Button> </Button>
</RequirePermission> </>
)} )}
<RequirePermission permissions='lti.marketing.sales_order.delete'> {/* <RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button <Button
onClick={deleteClickHandler} onClick={deleteClickHandler}
variant='ghost' variant='ghost'
@@ -116,7 +158,16 @@ const RowsOptionsMenu = ({
<Icon icon='mdi:delete-outline' width={16} height={16} /> <Icon icon='mdi:delete-outline' width={16} height={16} />
Delete Delete
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
onClick={deleteClickHandler}
variant='ghost'
color='error'
className='text-error hover:text-inherit justify-start text-sm'
>
<Icon icon='mdi:delete-outline' width={16} height={16} />
Delete
</Button>
</div> </div>
</div> </div>
); );
@@ -302,7 +353,7 @@ const MarketingTable = () => {
}} }}
/> />
<div className='flex flex-row gap-2'> <div className='flex flex-row gap-2'>
<RequirePermission permissions='lti.marketing.sales_order.approve'> {/* <RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='success' color='success'
onClick={approveClickHandler} onClick={approveClickHandler}
@@ -312,9 +363,18 @@ const MarketingTable = () => {
<Icon icon='material-symbols:check' width={24} height={24} /> <Icon icon='material-symbols:check' width={24} height={24} />
Approve Approve
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
color='success'
onClick={approveClickHandler}
className='justify-start text-sm'
disabled={disableApprove}
>
<Icon icon='material-symbols:check' width={24} height={24} />
Approve
</Button>
<RequirePermission permissions='lti.marketing.sales_order.approve'> {/* <RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='error' color='error'
onClick={rejectClickHandler} onClick={rejectClickHandler}
@@ -324,7 +384,16 @@ const MarketingTable = () => {
<Icon icon='material-symbols:close' width={24} height={24} /> <Icon icon='material-symbols:close' width={24} height={24} />
Reject Reject
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
color='error'
onClick={rejectClickHandler}
className='justify-start text-sm'
disabled={disableReject}
>
<Icon icon='material-symbols:close' width={24} height={24} />
Reject
</Button>
</div> </div>
<TableRowSizeSelector <TableRowSizeSelector
value={pageSize} value={pageSize}
@@ -135,7 +135,7 @@ const MarketingDetail = ({
<div className='flex-row flex gap-3'> <div className='flex-row flex gap-3'>
{initialValues?.latest_approval?.step_number == 1 && ( {initialValues?.latest_approval?.step_number == 1 && (
<> <>
<RequirePermission permissions='lti.marketing.sales_order.approve'> {/* <RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='success' color='success'
onClick={approveClickHandler} onClick={approveClickHandler}
@@ -147,9 +147,20 @@ const MarketingDetail = ({
<Icon icon='mdi:check' width={24} height={24} /> <Icon icon='mdi:check' width={24} height={24} />
Approve Approve
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
color='success'
onClick={approveClickHandler}
disabled={
initialValues?.latest_approval?.step_number == 1 &&
initialValues?.latest_approval?.action == 'REJECTED'
}
>
<Icon icon='mdi:check' width={24} height={24} />
Approve
</Button>
<RequirePermission permissions='lti.marketing.sales_order.approve'> {/* <RequirePermission permissions='lti.marketing.sales_order.approve'>
<Button <Button
color='error' color='error'
onClick={rejectClickHandler} onClick={rejectClickHandler}
@@ -161,17 +172,44 @@ const MarketingDetail = ({
<Icon icon='mdi:close' width={24} height={24} /> <Icon icon='mdi:close' width={24} height={24} />
Reject Reject
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
color='error'
onClick={rejectClickHandler}
disabled={
initialValues?.latest_approval?.step_number == 1 &&
initialValues?.latest_approval?.action == 'REJECTED'
}
>
<Icon icon='mdi:close' width={24} height={24} />
Reject
</Button>
</> </>
)} )}
{initialValues?.latest_approval?.step_number != 1 && ( {initialValues?.latest_approval?.step_number != 1 && (
<RequirePermission <>
permissions={ {/* <RequirePermission
initialValues?.latest_approval?.step_number == 3 permissions={
? 'lti.marketing.delivery_order.update' initialValues?.latest_approval?.step_number == 3
: 'lti.marketing.delivery_order.create' ? 'lti.marketing.delivery_order.update'
} : 'lti.marketing.delivery_order.create'
> }
>
<Button
color='success'
href={
initialValues?.latest_approval?.step_number == 3
? `/marketing/detail/delivery-orders/edit?marketingId=${initialValues?.id}`
: `/marketing/add/delivery-orders?marketingId=${initialValues?.id}`
}
>
<Icon icon='mdi:truck' width={24} height={24} />
{initialValues?.latest_approval?.step_number == 3
? 'Edit '
: 'Tambah '}
Delivery Order
</Button>
</RequirePermission> */}
<Button <Button
color='success' color='success'
href={ href={
@@ -186,7 +224,7 @@ const MarketingDetail = ({
: 'Tambah '} : 'Tambah '}
Delivery Order Delivery Order
</Button> </Button>
</RequirePermission> </>
)} )}
</div> </div>
@@ -427,7 +465,17 @@ const MarketingDetail = ({
)} )}
<div className='flex flex-row gap-3'> <div className='flex flex-row gap-3'>
{initialValues?.latest_approval?.step_number != 3 && ( {initialValues?.latest_approval?.step_number != 3 && (
<RequirePermission permissions='lti.marketing.sales_order.update'> <>
{/* <RequirePermission permissions='lti.marketing.sales_order.update'>
<Button
color='warning'
type='button'
href={`/marketing/detail/${initialValues?.latest_approval?.step_number == 3 ? 'delivery-orders' : 'sales-orders'}/edit?marketingId=${initialValues?.id}`}
>
<Icon icon='mdi:pencil' width={24} height={24} />
Edit
</Button>
</RequirePermission> */}
<Button <Button
color='warning' color='warning'
type='button' type='button'
@@ -436,14 +484,18 @@ const MarketingDetail = ({
<Icon icon='mdi:pencil' width={24} height={24} /> <Icon icon='mdi:pencil' width={24} height={24} />
Edit Edit
</Button> </Button>
</RequirePermission> </>
)} )}
<RequirePermission permissions='lti.marketing.sales_order.delete'> {/* <RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button color='error' onClick={deleteClickHandler}> <Button color='error' onClick={deleteClickHandler}>
<Icon icon='mdi:delete' width={24} height={24} /> <Icon icon='mdi:delete' width={24} height={24} />
Hapus Hapus
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button color='error' onClick={deleteClickHandler}>
<Icon icon='mdi:delete' width={24} height={24} />
Hapus
</Button>
</div> </div>
</div> </div>
<ConfirmationModal <ConfirmationModal
@@ -690,7 +690,7 @@ const MarketingForm = ({
{/* Actions button */} {/* Actions button */}
{formType == 'edit' && ( {formType == 'edit' && (
<div className='flex flex-row justify-start'> <div className='flex flex-row justify-start'>
<RequirePermission permissions='lti.marketing.sales_order.delete'> {/* <RequirePermission permissions='lti.marketing.sales_order.delete'>
<Button <Button
type='button' type='button'
color='error' color='error'
@@ -700,7 +700,16 @@ const MarketingForm = ({
<Icon icon='mdi:trash' width={24} height={24} /> <Icon icon='mdi:trash' width={24} height={24} />
Hapus Hapus
</Button> </Button>
</RequirePermission> </RequirePermission> */}
<Button
type='button'
color='error'
onClick={handleDelete}
isLoading={isLoading}
>
<Icon icon='mdi:trash' width={24} height={24} />
Hapus
</Button>
</div> </div>
)} )}
@@ -421,8 +421,8 @@ const WarehouseForm = ({ type = 'add', initialValues }: WarehouseFormProps) => {
value={formik.values.kandang ?? undefined} value={formik.values.kandang ?? undefined}
onChange={kandangChangeHandler} onChange={kandangChangeHandler}
options={kandangOptions} options={kandangOptions}
onInputChange={setLocationSelectInputValue} onInputChange={setKandangSelectInputValue}
isLoading={isLoadingLocations} isLoading={isLoadingKandangs}
isError={ isError={
formik.touched.kandangId && Boolean(formik.errors.kandangId) formik.touched.kandangId && Boolean(formik.errors.kandangId)
} }
@@ -228,11 +228,18 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
const confirmationModalDeleteClickHandler = async () => { const confirmationModalDeleteClickHandler = async () => {
setIsDeleteLoading(true); setIsDeleteLoading(true);
await ProjectFlockApi.delete(selectedSingleRow?.id as number); const response = await ProjectFlockApi.delete(
selectedSingleRow?.id as number
);
if (isResponseSuccess(response)) {
toast.success(response?.message as string);
}
if (isResponseError(response)) {
toast.error(response?.message as string);
}
refreshProjectFlocks(); refreshProjectFlocks();
deleteModal.closeModal(); deleteModal.closeModal();
toast.success('Successfully delete Project Flock!');
setIsDeleteLoading(false); setIsDeleteLoading(false);
setRowSelection({}); setRowSelection({});
}; };
+18 -5
View File
@@ -58,14 +58,27 @@ export const ROUTE_PERMISSIONS: Record<string, string[]> = {
'/purchase/detail/edit/': ['lti.purchase.update'], '/purchase/detail/edit/': ['lti.purchase.update'],
// Marketing // Marketing
'/marketing/': ['lti.marketing.delivery_order.list'], '/marketing/': ['lti.dashboard.list', 'lti.marketing.delivery_order.list'],
'/marketing/add/delivery-orders/': ['lti.marketing.delivery_order.create'], '/marketing/add/delivery-orders/': [
'/marketing/add/sales-orders/': ['lti.marketing.sales_order.create'], 'lti.dashboard.list',
'/marketing/detail/': ['lti.marketing.delivery_order.detail'], 'lti.marketing.delivery_order.create',
],
'/marketing/add/sales-orders/': [
'lti.dashboard.list',
'lti.marketing.sales_order.create',
],
'/marketing/detail/': [
'lti.dashboard.list',
'lti.marketing.delivery_order.detail',
],
'/marketing/detail/delivery-orders/edit/': [ '/marketing/detail/delivery-orders/edit/': [
'lti.dashboard.list',
'lti.marketing.delivery_order.update', 'lti.marketing.delivery_order.update',
], ],
'/marketing/detail/sales-orders/edit/': ['lti.marketing.sales_order.update'], '/marketing/detail/sales-orders/edit/': [
'lti.dashboard.list',
'lti.marketing.sales_order.update',
],
// Expense // Expense
'/expense/': ['lti.expense.list'], '/expense/': ['lti.expense.list'],