mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
Merge branch 'development' of gitlab.com:mbugroup/lti-web-client into dev/hotfix/restu
This commit is contained in:
@@ -34,7 +34,7 @@ const FinanceDetail = ({ finance }: { finance: Finance }) => {
|
||||
},
|
||||
{
|
||||
label: 'Pihak',
|
||||
value: finance.party.id ? finance.party.name : '-',
|
||||
value: finance.party?.id ? finance.party?.name : '-',
|
||||
},
|
||||
{
|
||||
label: 'Tanggal',
|
||||
@@ -56,25 +56,21 @@ const FinanceDetail = ({ finance }: { finance: Finance }) => {
|
||||
},
|
||||
{
|
||||
label: 'Nomor Rekening',
|
||||
value: `${finance.bank.alias} - ${finance.bank.account_number} - ${finance.bank.owner}`,
|
||||
value: `${finance.bank?.alias} - ${finance.bank?.account_number} - ${finance.bank?.owner}`,
|
||||
},
|
||||
{
|
||||
label: `Rekening ${formatTitleCase(finance.party.type)}`,
|
||||
value: finance.party.account_number,
|
||||
label: `Rekening ${formatTitleCase(finance.party?.type)}`,
|
||||
value: finance.party?.account_number,
|
||||
},
|
||||
{
|
||||
label: 'Nominal',
|
||||
value: formatCurrency(finance.expense_amount),
|
||||
},
|
||||
{
|
||||
label: 'Sisa',
|
||||
value: formatCurrency(finance.income_amount),
|
||||
value: formatCurrency(finance.nominal),
|
||||
},
|
||||
].filter((item) => {
|
||||
// Hide party account number row if transaction type is INJECTION
|
||||
if (
|
||||
FINANCE_INJECTION_STATUS.includes(finance.transaction_type) &&
|
||||
item.label === `Rekening ${formatTitleCase(finance.party.type)}`
|
||||
item.label === `Rekening ${formatTitleCase(finance.party?.type)}`
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -148,18 +144,19 @@ const FinanceDetail = ({ finance }: { finance: Finance }) => {
|
||||
</Card>
|
||||
|
||||
<div className='flex flex-row gap-2 justify-end'>
|
||||
{FINANCE_TRANSACTION_STATUS.includes(finance.transaction_type) && (
|
||||
<RequirePermission permissions='lti.finance.payments.update'>
|
||||
<Button
|
||||
color='warning'
|
||||
className='min-w-24'
|
||||
href={`/finance/detail/edit?financeId=${finance.id}`}
|
||||
>
|
||||
<Icon icon='mdi:pencil-outline' />
|
||||
Edit
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
)}
|
||||
{FINANCE_TRANSACTION_STATUS.includes(finance.transaction_type) &&
|
||||
finance.party?.type !== 'SUPPLIER' && (
|
||||
<RequirePermission permissions='lti.finance.payments.update'>
|
||||
<Button
|
||||
color='warning'
|
||||
className='min-w-24'
|
||||
href={`/finance/detail/edit?financeId=${finance.id}`}
|
||||
>
|
||||
<Icon icon='mdi:pencil-outline' />
|
||||
Edit
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
)}
|
||||
{FINANCE_INITIAL_BALANCE_STATUS.includes(finance.transaction_type) && (
|
||||
<RequirePermission permissions='lti.finance.initial_balances.update'>
|
||||
<Button
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
} from '@/config/constant';
|
||||
import { FinanceApi } from '@/services/api/finance';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { BankApi } from '@/services/api/master-data';
|
||||
import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data';
|
||||
import { Bank } from '@/types/api/master-data/bank';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
@@ -65,19 +65,24 @@ const RowOptionsMenu = ({
|
||||
|
||||
{FINANCE_TRANSACTION_STATUS.includes(
|
||||
props.row.original.transaction_type
|
||||
) && (
|
||||
<RequirePermission permissions='lti.finance.payments.update'>
|
||||
<Button
|
||||
href={`/finance/detail/edit?financeId=${props.row.original.id}`}
|
||||
variant='ghost'
|
||||
color='warning'
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:edit-outline' width={16} height={16} />
|
||||
Edit
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
)}
|
||||
) &&
|
||||
props.row.original.party?.type !== 'SUPPLIER' && (
|
||||
<RequirePermission permissions='lti.finance.payments.update'>
|
||||
<Button
|
||||
href={`/finance/detail/edit?financeId=${props.row.original.id}`}
|
||||
variant='ghost'
|
||||
color='warning'
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:edit-outline'
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Edit
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
)}
|
||||
|
||||
{FINANCE_INITIAL_BALANCE_STATUS.includes(
|
||||
props.row.original.transaction_type
|
||||
@@ -194,20 +199,25 @@ const FinanceTable = () => {
|
||||
|
||||
// ===== Options =====
|
||||
const transactionTypeOptions = useMemo(() => {
|
||||
return [
|
||||
{ label: 'Transfer', value: 'TRANSFER' },
|
||||
{ label: 'Cash', value: 'CASH' },
|
||||
{ label: 'Card', value: 'CARD' },
|
||||
{ label: 'Cheque', value: 'CHEQUE' },
|
||||
{ label: 'Saldo', value: 'SALDO' },
|
||||
];
|
||||
}, []);
|
||||
const partyTypeOptions = useMemo(() => {
|
||||
return [
|
||||
{ label: 'Customer', value: 'CUSTOMER' },
|
||||
{ label: 'Supplier', value: 'SUPPLIER' },
|
||||
];
|
||||
}, []);
|
||||
const {
|
||||
options: partyTypeOptions,
|
||||
isLoadingOptions: partyTypeIsLoadingOptions,
|
||||
setInputValue: partyTypeInputValue,
|
||||
loadMore: partyTypeLoadMore,
|
||||
} = useSelect(
|
||||
selectedTransactionType
|
||||
? selectedTransactionType.value === 'CUSTOMER'
|
||||
? CustomerApi.basePath
|
||||
: SupplierApi.basePath
|
||||
: '',
|
||||
'id',
|
||||
'name'
|
||||
);
|
||||
const sortByOptions = useMemo(() => {
|
||||
return [
|
||||
{ label: 'Tanggal Pembayaran', value: 'payment_date' },
|
||||
@@ -336,10 +346,10 @@ const FinanceTable = () => {
|
||||
},
|
||||
{
|
||||
header: 'Pihak',
|
||||
accessorFn: (finance: Finance) => finance.party.name,
|
||||
accessorFn: (finance: Finance) => finance.party?.name,
|
||||
cell: (props: CellContext<Finance, unknown>) => {
|
||||
if (props.row.original.party.id) {
|
||||
return <span>{props.row.original.party.name}</span>;
|
||||
if (props.row.original.party?.id) {
|
||||
return <span>{props.row.original.party?.name}</span>;
|
||||
}
|
||||
return <span>{'-'}</span>;
|
||||
},
|
||||
@@ -360,12 +370,12 @@ const FinanceTable = () => {
|
||||
{
|
||||
header: 'Bank',
|
||||
accessorFn: (finance: Finance) =>
|
||||
`${finance.bank.alias} - ${finance.bank.account_number} - ${finance.bank.owner}`,
|
||||
`${finance.bank?.alias} - ${finance.bank?.account_number} - ${finance.bank?.owner}`,
|
||||
},
|
||||
{
|
||||
header: 'Pengeluaran (Rp)',
|
||||
accessorFn: (finance: Finance) =>
|
||||
formatCurrency(finance.expense_amount),
|
||||
formatCurrency(Math.abs(finance.expense_amount)),
|
||||
},
|
||||
{
|
||||
header: 'Pemasukan (Rp)',
|
||||
@@ -468,25 +478,41 @@ const FinanceTable = () => {
|
||||
<div className='grid grid-cols-4 gap-6'>
|
||||
<SelectInput
|
||||
options={transactionTypeOptions}
|
||||
label='Jenis Transaksi'
|
||||
label='Tipe Transaksi'
|
||||
value={selectedTransactionType}
|
||||
onChange={transactionTypeChangeHandler}
|
||||
isClearable
|
||||
/>
|
||||
<SelectInput
|
||||
options={partyTypeOptions}
|
||||
label={
|
||||
selectedTransactionType
|
||||
? selectedTransactionType.value === 'CUSTOMER'
|
||||
? 'Pelanggan'
|
||||
: 'Supplier'
|
||||
: 'Pihak'
|
||||
}
|
||||
value={selectedPartyType}
|
||||
onChange={partyTypeChangeHandler}
|
||||
onInputChange={partyTypeInputValue}
|
||||
onMenuScrollToBottom={partyTypeLoadMore}
|
||||
isLoading={partyTypeIsLoadingOptions}
|
||||
isClearable
|
||||
/>
|
||||
<SelectInput
|
||||
options={
|
||||
isResponseSuccess(bankRawData)
|
||||
? bankOptions.map((bank) => ({
|
||||
label:
|
||||
bankRawData.data.find((data) => data.id === bank.value)
|
||||
bankRawData.data.find((data) => data.id === bank?.value)
|
||||
?.alias +
|
||||
' - ' +
|
||||
bankRawData.data.find((data) => data.id === bank.value)
|
||||
bankRawData.data.find((data) => data.id === bank?.value)
|
||||
?.account_number +
|
||||
' - ' +
|
||||
bankRawData.data.find((data) => data.id === bank.value)
|
||||
bankRawData.data.find((data) => data.id === bank?.value)
|
||||
?.owner,
|
||||
value: bank.value,
|
||||
value: bank?.value,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
@@ -497,13 +523,6 @@ const FinanceTable = () => {
|
||||
onMenuScrollToBottom={bankLoadMore}
|
||||
isClearable
|
||||
/>
|
||||
<SelectInput
|
||||
options={partyTypeOptions}
|
||||
label='Pihak'
|
||||
value={selectedPartyType}
|
||||
onChange={partyTypeChangeHandler}
|
||||
isClearable
|
||||
/>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
label='Cari'
|
||||
|
||||
@@ -32,8 +32,10 @@ import {
|
||||
import { Bank } from '@/types/api/master-data/bank';
|
||||
import { useFormik } from 'formik';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import Alert from '@/components/Alert';
|
||||
import { Icon } from '@iconify/react';
|
||||
|
||||
interface FormFinanceAddProps {
|
||||
type?: 'add' | 'edit';
|
||||
@@ -51,18 +53,22 @@ const FormFinanceAdd = ({
|
||||
initialValues,
|
||||
}: FormFinanceAddProps) => {
|
||||
const router = useRouter();
|
||||
const [serverErrorMessage, setServerErrorMessage] = useState('');
|
||||
const [isSupplier, setIsSupplier] = useState(
|
||||
initialValues?.party?.type === 'SUPPLIER'
|
||||
);
|
||||
|
||||
// ===== Formik =====
|
||||
const formikInitialValues = useMemo((): FinanceFormValues => {
|
||||
return {
|
||||
party_type_option:
|
||||
FINANCE_PARTY_TYPE_OPTIONS.find(
|
||||
(option) => option.value === initialValues?.party.type
|
||||
(option) => option.value === initialValues?.party?.type
|
||||
) || null,
|
||||
party_id_option: initialValues?.party
|
||||
? {
|
||||
label: initialValues?.party.name || '',
|
||||
value: initialValues?.party.id || 0,
|
||||
label: initialValues?.party?.name || '',
|
||||
value: initialValues?.party?.id || 0,
|
||||
}
|
||||
: null,
|
||||
payment_date: initialValues?.payment_date || '',
|
||||
@@ -72,11 +78,11 @@ const FormFinanceAdd = ({
|
||||
) || null,
|
||||
bank_id_option: initialValues?.bank
|
||||
? {
|
||||
label: initialValues.bank.name,
|
||||
value: initialValues.bank.id,
|
||||
label: initialValues?.bank?.name,
|
||||
value: initialValues?.bank?.id,
|
||||
}
|
||||
: null,
|
||||
party_account_number: initialValues?.party.account_number || '',
|
||||
party_account_number: initialValues?.party?.account_number || '',
|
||||
reference_number: initialValues?.reference_number || '',
|
||||
nominal: initialValues?.nominal.toString() || '',
|
||||
notes: initialValues?.notes || '',
|
||||
@@ -153,6 +159,7 @@ const FormFinanceAdd = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -168,6 +175,7 @@ const FormFinanceAdd = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -207,6 +215,7 @@ const FormFinanceAdd = ({
|
||||
? formik.errors.party_type_option
|
||||
: ''
|
||||
}
|
||||
isDisabled={type === 'edit' || isSupplier}
|
||||
required
|
||||
isClearable
|
||||
/>
|
||||
@@ -245,7 +254,7 @@ const FormFinanceAdd = ({
|
||||
}
|
||||
required
|
||||
isClearable
|
||||
isDisabled={!formik.values.party_type_option?.value}
|
||||
isDisabled={!formik.values.party_type_option?.value || isSupplier}
|
||||
/>
|
||||
<DateInput
|
||||
label='Tanggal'
|
||||
@@ -263,6 +272,7 @@ const FormFinanceAdd = ({
|
||||
: ''
|
||||
}
|
||||
required
|
||||
disabled={isSupplier}
|
||||
/>
|
||||
<SelectInput
|
||||
label='Metode Pembayaran'
|
||||
@@ -284,6 +294,7 @@ const FormFinanceAdd = ({
|
||||
}
|
||||
required
|
||||
isClearable
|
||||
isDisabled={isSupplier}
|
||||
/>
|
||||
<SelectInput
|
||||
label='Bank'
|
||||
@@ -324,6 +335,7 @@ const FormFinanceAdd = ({
|
||||
}
|
||||
required
|
||||
isClearable
|
||||
isDisabled={isSupplier}
|
||||
/>
|
||||
<TextInput
|
||||
label={`Nomor Rekening ${formik.values.party_type_option?.value ? formatTitleCase(formik.values.party_type_option.value as string) : 'Pihak'}`}
|
||||
@@ -344,6 +356,7 @@ const FormFinanceAdd = ({
|
||||
}
|
||||
required
|
||||
readOnly
|
||||
disabled={isSupplier}
|
||||
/>
|
||||
<TextInput
|
||||
label='Nomor Referensi'
|
||||
@@ -363,6 +376,7 @@ const FormFinanceAdd = ({
|
||||
: ''
|
||||
}
|
||||
required
|
||||
disabled={isSupplier}
|
||||
/>
|
||||
<NumberInput
|
||||
label='Nominal'
|
||||
@@ -378,6 +392,7 @@ const FormFinanceAdd = ({
|
||||
: ''
|
||||
}
|
||||
required
|
||||
disabled={isSupplier}
|
||||
/>
|
||||
<TextArea
|
||||
label='Catatan'
|
||||
@@ -393,8 +408,18 @@ const FormFinanceAdd = ({
|
||||
: ''
|
||||
}
|
||||
required
|
||||
disabled={isSupplier}
|
||||
/>
|
||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
||||
{serverErrorMessage && (
|
||||
<Alert color='error'>
|
||||
<Icon icon='mdi:alert' />
|
||||
{serverErrorMessage}
|
||||
<Button color='error' onClick={() => setServerErrorMessage('')}>
|
||||
<Icon icon='mdi:close' />
|
||||
</Button>
|
||||
</Alert>
|
||||
)}
|
||||
<div className='flex justify-center gap-4'>
|
||||
<Button
|
||||
type='reset'
|
||||
|
||||
+1
-7
@@ -27,13 +27,7 @@ export const InitialBalanceFormSchema = Yup.object().shape({
|
||||
'Pihak wajib diisi',
|
||||
(value) => value !== null && value !== undefined
|
||||
),
|
||||
bank_id_option: Yup.mixed()
|
||||
.nullable()
|
||||
.test(
|
||||
'is-valid-option',
|
||||
'Bank wajib diisi',
|
||||
(value) => value !== null && value !== undefined
|
||||
),
|
||||
bank_id_option: Yup.mixed().nullable(),
|
||||
reference_number: Yup.string().required('Nomor referensi wajib diisi'),
|
||||
initial_balance_type_option: Yup.mixed()
|
||||
.nullable()
|
||||
|
||||
@@ -29,8 +29,9 @@ import { Bank } from '@/types/api/master-data/bank';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useFormik } from 'formik';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import Alert from '@/components/Alert';
|
||||
|
||||
interface FormFinanceAddInitialBalanceProps {
|
||||
type?: 'add' | 'edit';
|
||||
@@ -42,6 +43,7 @@ const FormFinanceAddInitialBalance = ({
|
||||
initialValues,
|
||||
}: FormFinanceAddInitialBalanceProps) => {
|
||||
const router = useRouter();
|
||||
const [serverErrorMessage, setServerErrorMessage] = useState('');
|
||||
|
||||
// ===== Formik =====
|
||||
const formikInitialValues = useMemo((): InitialBalanceFormValues => {
|
||||
@@ -53,18 +55,18 @@ const FormFinanceAddInitialBalance = ({
|
||||
return {
|
||||
party_type_option:
|
||||
FINANCE_PARTY_TYPE_OPTIONS.find(
|
||||
(option) => option.value === initialValues?.party.type
|
||||
(option) => option.value === initialValues?.party?.type
|
||||
) || null,
|
||||
party_id_option: initialValues?.party
|
||||
? {
|
||||
label: initialValues.party.name,
|
||||
value: initialValues.party.id,
|
||||
label: initialValues.party?.name,
|
||||
value: initialValues.party?.id,
|
||||
}
|
||||
: null,
|
||||
bank_id_option: initialValues?.bank
|
||||
? {
|
||||
label: initialValues.bank.name,
|
||||
value: initialValues.bank.id,
|
||||
label: initialValues.bank?.name,
|
||||
value: initialValues.bank?.id,
|
||||
}
|
||||
: null,
|
||||
reference_number: initialValues?.reference_number || '',
|
||||
@@ -147,6 +149,7 @@ const FormFinanceAddInitialBalance = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,6 +169,7 @@ const FormFinanceAddInitialBalance = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,6 +215,7 @@ const FormFinanceAddInitialBalance = ({
|
||||
: ''
|
||||
}
|
||||
required
|
||||
isDisabled={type === 'edit'}
|
||||
isClearable
|
||||
/>
|
||||
<SelectInput
|
||||
@@ -277,7 +282,6 @@ const FormFinanceAddInitialBalance = ({
|
||||
? formik.errors.bank_id_option
|
||||
: ''
|
||||
}
|
||||
required
|
||||
isClearable
|
||||
/>
|
||||
<TextInput
|
||||
@@ -362,7 +366,18 @@ const FormFinanceAddInitialBalance = ({
|
||||
}
|
||||
required
|
||||
/>
|
||||
|
||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
||||
{serverErrorMessage && (
|
||||
<Alert color='error'>
|
||||
<Icon icon='mdi:alert' />
|
||||
{serverErrorMessage}
|
||||
<Button color='error' onClick={() => setServerErrorMessage('')}>
|
||||
<Icon icon='mdi:close' />
|
||||
</Button>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<div className='flex justify-center gap-4'>
|
||||
<Button
|
||||
type='reset'
|
||||
|
||||
@@ -24,8 +24,10 @@ import {
|
||||
import { Bank } from '@/types/api/master-data/bank';
|
||||
import { useFormik } from 'formik';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import Alert from '@/components/Alert';
|
||||
import { Icon } from '@iconify/react';
|
||||
|
||||
interface FormFinanceInjectionProps {
|
||||
type?: 'add' | 'edit';
|
||||
@@ -37,14 +39,15 @@ const FormFinanceInjection = ({
|
||||
initialValues,
|
||||
}: FormFinanceInjectionProps) => {
|
||||
const router = useRouter();
|
||||
const [serverErrorMessage, setServerErrorMessage] = useState('');
|
||||
|
||||
// ===== Formik =====
|
||||
const formikInitialValues = useMemo((): InjectionFormValues => {
|
||||
return {
|
||||
bank_id_option: initialValues?.bank
|
||||
? {
|
||||
label: initialValues.bank.name,
|
||||
value: initialValues.bank.id,
|
||||
label: initialValues.bank?.name,
|
||||
value: initialValues.bank?.id,
|
||||
}
|
||||
: null,
|
||||
adjustment_date: initialValues?.payment_date || '',
|
||||
@@ -103,6 +106,7 @@ const FormFinanceInjection = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,6 +123,7 @@ const FormFinanceInjection = ({
|
||||
|
||||
if (isResponseError(response)) {
|
||||
toast.error(response.message);
|
||||
setServerErrorMessage(response.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -230,6 +235,15 @@ const FormFinanceInjection = ({
|
||||
required
|
||||
/>
|
||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
||||
{serverErrorMessage && (
|
||||
<Alert color='error'>
|
||||
<Icon icon='mdi:alert' />
|
||||
{serverErrorMessage}
|
||||
<Button color='error' onClick={() => setServerErrorMessage('')}>
|
||||
<Icon icon='mdi:close' />
|
||||
</Button>
|
||||
</Alert>
|
||||
)}
|
||||
<div className='flex justify-center gap-4'>
|
||||
<Button
|
||||
type='reset'
|
||||
|
||||
@@ -91,7 +91,7 @@ const InventoryProductDetail = ({
|
||||
<td>:</td>
|
||||
<td>
|
||||
{inventoryProduct?.tax
|
||||
? formatCurrency(inventoryProduct?.tax)
|
||||
? formatNumber(inventoryProduct?.tax) + '%'
|
||||
: '-'}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -16,7 +16,7 @@ import { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector';
|
||||
import { TableToolbar } from '@/components/table/TableToolbar';
|
||||
import { ROWS_OPTIONS } from '@/config/constant';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { cn, formatCurrency, formatDate } from '@/lib/helper';
|
||||
import { cn, formatCurrency, formatDate, formatTitleCase } from '@/lib/helper';
|
||||
import {
|
||||
MarketingApi,
|
||||
SalesOrderApi,
|
||||
@@ -33,6 +33,7 @@ import RequirePermission from '@/components/helper/RequirePermission';
|
||||
import { useAuth } from '@/services/hooks/useAuth';
|
||||
import { CustomerApi, ProductApi } from '@/services/api/master-data';
|
||||
import { MARKETING_APPROVAL_LINE } from '@/config/approval-line';
|
||||
import Badge from '@/components/Badge';
|
||||
|
||||
const RowsOptionsMenu = ({
|
||||
type = 'dropdown',
|
||||
@@ -520,8 +521,53 @@ const MarketingTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'latest_approval.step_name',
|
||||
accessorKey: 'approval.step_name',
|
||||
header: 'Status',
|
||||
cell: (props) => {
|
||||
const approval = props.row.original.latest_approval;
|
||||
const isRejected = approval?.action == 'REJECTED';
|
||||
const isApproved = approval?.action == 'APPROVED';
|
||||
return (
|
||||
<Badge
|
||||
variant='soft'
|
||||
className={{
|
||||
badge:
|
||||
'rounded-lg px-2 w-full flex flex-row justify-start whitespace-nowrap',
|
||||
}}
|
||||
color={
|
||||
isRejected
|
||||
? 'error'
|
||||
: isApproved
|
||||
? approval?.step_number == 1
|
||||
? 'neutral'
|
||||
: approval?.step_number == 2
|
||||
? 'primary'
|
||||
: approval?.step_number == 3
|
||||
? 'success'
|
||||
: 'neutral'
|
||||
: 'neutral'
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
icon='mdi:circle'
|
||||
width={12}
|
||||
height={12}
|
||||
color={
|
||||
approval?.step_number == 1
|
||||
? 'neutral'
|
||||
: approval?.step_number == 2
|
||||
? 'primary'
|
||||
: approval?.step_number == 3
|
||||
? 'success'
|
||||
: 'neutral'
|
||||
}
|
||||
/>
|
||||
{isRejected
|
||||
? 'Ditolak'
|
||||
: formatTitleCase(approval?.step_name || '')}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'customer.name',
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
formatCurrency,
|
||||
formatDate,
|
||||
formatNumber,
|
||||
formatTitleCase,
|
||||
formatVechicleNumber,
|
||||
} from '@/lib/helper';
|
||||
import {
|
||||
@@ -34,6 +35,7 @@ import toast from 'react-hot-toast';
|
||||
import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport';
|
||||
import DeliveryOrderExport from '@/components/pages/marketing/pdf/DeliveryOrderExport';
|
||||
import RequirePermission from '@/components/helper/RequirePermission';
|
||||
import Badge from '@/components/Badge';
|
||||
|
||||
const MarketingDetail = ({
|
||||
initialValues,
|
||||
@@ -121,6 +123,10 @@ const MarketingDetail = ({
|
||||
);
|
||||
};
|
||||
|
||||
const approval = initialValues?.latest_approval;
|
||||
const isRejected = approval?.action == 'REJECTED';
|
||||
const isApproved = approval?.action == 'APPROVED';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex flex-col w-full gap-4'>
|
||||
@@ -230,7 +236,46 @@ const MarketingDetail = ({
|
||||
<tr>
|
||||
<td className='font-semibold'>Status</td>
|
||||
<td>:</td>
|
||||
<td>{initialValues?.latest_approval?.step_name}</td>
|
||||
<td>
|
||||
<Badge
|
||||
variant='soft'
|
||||
className={{
|
||||
badge:
|
||||
'rounded-lg px-2 w-fit flex flex-row justify-start whitespace-nowrap',
|
||||
}}
|
||||
color={
|
||||
isRejected
|
||||
? 'error'
|
||||
: isApproved
|
||||
? approval?.step_number == 1
|
||||
? 'neutral'
|
||||
: approval?.step_number == 2
|
||||
? 'primary'
|
||||
: approval?.step_number == 3
|
||||
? 'success'
|
||||
: 'neutral'
|
||||
: 'neutral'
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
icon='mdi:circle'
|
||||
width={12}
|
||||
height={12}
|
||||
color={
|
||||
approval?.step_number == 1
|
||||
? 'neutral'
|
||||
: approval?.step_number == 2
|
||||
? 'primary'
|
||||
: approval?.step_number == 3
|
||||
? 'success'
|
||||
: 'neutral'
|
||||
}
|
||||
/>
|
||||
{isRejected
|
||||
? 'Ditolak'
|
||||
: formatTitleCase(approval?.step_name || '')}
|
||||
</Badge>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='font-semibold'>Tanggal Penjualan</td>
|
||||
|
||||
@@ -621,7 +621,9 @@ const MarketingForm = ({
|
||||
isClearable
|
||||
placeholder='Pilih Pelanggan'
|
||||
isDisabled={
|
||||
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||
formType === 'add_deliver' ||
|
||||
formType === 'edit_deliver' ||
|
||||
formType === 'edit'
|
||||
}
|
||||
/>
|
||||
<DateInput
|
||||
|
||||
Reference in New Issue
Block a user