상세 수정

This commit is contained in:
focp212@naver.com
2025-11-03 20:57:55 +09:00
parent 344e5c324a
commit d2b477e7bd
38 changed files with 1569 additions and 256 deletions

View File

@@ -51,7 +51,8 @@ export interface VatReturnListResponse extends DefaulResponsePagination {
};
export interface VatReturnListContent {
id?: number
id?: number;
taxInvoiceNumber?: string;
companyName?: string;
mid?: string;
issueDate?: string;
@@ -61,15 +62,22 @@ export interface VatReturnListContent {
export interface ListDateGroupProps {
date?: string;
items?: Array<VatReturnListContent>
}
items?: Array<VatReturnListContent>;
setDetailData?: (detailData: DetailData) => void;
};
export interface DetailData {
taxInvoiceNumber: string;
detailOn: boolean;
};
export interface ListItemProps {
id?: number;
taxInvoiceNumber?: string;
companyName?: string;
mid?: string;
issueDate?: string;
paymentMethod?: string;
amount?: number;
setDetailData?: (detailData: DetailData) => void;
}
export interface VatReturnDetailParams {
taxInvoiceNumber?: string;

View File

@@ -0,0 +1,162 @@
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { motion } from 'framer-motion';
import { PATHS } from '@/shared/constants/paths';
import { useLocation } from 'react-router';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { useVatReturnDetailMutation } from '@/entities/vat-return/api/use-vat-return-detail-mutation';
import { HeaderType } from '@/entities/common/model/types';
import {
Breakdown,
VatReturnBreakdownParams,
VatReturnBreakdownResponse,
VatReturnDetailParams,
VatReturnDetailResponse
} from '@/entities/vat-return/model/types';
import {
useSetOnBack,
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode
} from '@/widgets/sub-layout/use-sub-layout';
import { SupplierSection } from '@/entities/vat-return/ui/section/supplier-section';
import { ReceiverSection } from '@/entities/vat-return/ui/section/receiver-section';
import { IssueSection } from '@/entities/vat-return/ui/section/issue-section';
import { AmountSection } from '@/entities/vat-return/ui/section/amount-section';
import { useVatReturnTaxInvoiceMutation } from '@/entities/vat-return/api/use-vat-return-tax-invoice-mutation';
import { VatReturnListDetailBottomSheet } from '@/entities/vat-return/ui/list-detail-bottom-sheet';
import { useVatReturnBreakdownMutation } from '@/entities/vat-return/api/use-vat-return-breakdown-mutation';
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
export interface TaxInvoiceDetailProps {
detailOn: boolean;
setDetailOn: (detailOn: boolean) => void;
taxInvoiceNumber: string;
};
export const TaxInvoiceDetail = ({
detailOn,
setDetailOn,
taxInvoiceNumber
}: TaxInvoiceDetailProps) => {
const { t } = useTranslation();
const { navigate } = useNavigate();
const location = useLocation();
// taxInvoiceNumber = 'TAX202506300001';
const [openAmount, setOpenAmount] = useState<boolean>(false);
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
const [detail, setDetail] = useState<VatReturnDetailResponse>({});
const [breakdown, setBreakdown] = useState<Array<Breakdown>>([]);
useSetHeaderTitle(t('vatReturn.taxInvoiceDetail'));
useSetHeaderType(HeaderType.RightClose);
useSetOnBack(() => {
navigate(PATHS.vatReturn.list);
});
useSetFooterMode(false);
const { mutateAsync: vatReturnTaxInvoice } = useVatReturnTaxInvoiceMutation();
const { mutateAsync: vatReturnDetail } = useVatReturnDetailMutation();
const { mutateAsync: vatReturnBreakdown } = useVatReturnBreakdownMutation();
const callTaxInvoice = () => {
if(taxInvoiceNumber){
let params: VatReturnDetailParams = {
taxInvoiceNumber: taxInvoiceNumber,
};
vatReturnDetail(params).then((rs: VatReturnDetailResponse) => {
setDetail(rs);
});
}
};
const callVatReturnBreakdown = async() => {
let params: VatReturnBreakdownParams = {
taxInvoiceNumber: taxInvoiceNumber,
};
vatReturnBreakdown(params).then((rs: VatReturnBreakdownResponse) => {
setBreakdown(rs.breakdown);
});
};
const onClickToOpenBottomSheet = () => {
setBottomSheetOn(true);
};
const onClickToClose = () => {
setDetailOn(false);
};
useEffect(() => {
if(!!detailOn && taxInvoiceNumber){
callTaxInvoice();
callVatReturnBreakdown();
}
}, [detailOn]);
return (
<>
<motion.div
className="full-menu-modal"
initial="hidden"
animate={ (detailOn)? 'visible': 'hidden' }
variants={ DetailMotionVariants }
transition={ DetailMotionDuration }
style={ DetailMotionStyle }
>
<div className="full-menu-container pdw-16">
<div className="full-menu-header">
<div className="full-menu-title center">{ t('transaction.detailTitle') }</div>
<div className="full-menu-actions">
<FullMenuClose
addClass="full-menu-close"
onClickToCallback={ onClickToClose }
></FullMenuClose>
</div>
</div>
<div className="tab-pane sub active">
<div className="option-list">
<div className="txn-detail">
<AmountSection
detail={ detail }
></AmountSection>
<div className="txn-divider minus"></div>
<IssueSection
detail={ detail }
></IssueSection>
<div className="txn-divider minus"></div>
<ReceiverSection
detail={ detail }
></ReceiverSection>
<div className="txn-divider"></div>
<SupplierSection
detail={ detail }
></SupplierSection>
</div>
</div>
</div>
</div>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={ onClickToOpenBottomSheet }
>{t('vatReturn.viewDetails')}</button>
</div>
</motion.div>
{ !!bottomSheetOn &&
<VatReturnListDetailBottomSheet
bottomSheetOn={ bottomSheetOn }
setBottomSheetOn={ setBottomSheetOn }
breakdown={ breakdown }
transactionAmount={ detail?.transactionAmount }
supplyAmount={ detail?.supplyAmount }
vatAmount={ detail?.vatAmount }
totalAmount={ detail?.totalAmount }
></VatReturnListDetailBottomSheet>
}
</>
)
};

View File

@@ -5,7 +5,8 @@ import { ListItem } from './list-item';
export const ListDateGroup = ({
date,
items
items,
setDetailData
}: ListDateGroupProps) => {
moment.locale('ko');
const getStateDate = () => {
@@ -21,12 +22,13 @@ export const ListDateGroup = ({
rs.push(
<ListItem
key={ key }
id={ items[i]?.id || 0 }
taxInvoiceNumber={ items[i]?.taxInvoiceNumber || '' }
companyName={ items[i]?.companyName || '' }
mid={ items[i]?.mid || '' }
issueDate={ items[i]?.issueDate || '' }
paymentMethod={ items[i]?.paymentMethod || '' }
amount={ items[i]?.amount || 0 }
setDetailData={ setDetailData }
></ListItem>
)
}

View File

@@ -1,27 +1,25 @@
import { NumericFormat } from 'react-number-format';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ListItemProps } from '../model/types';
import moment from 'moment';
export const ListItem = ({
id,
taxInvoiceNumber,
companyName,
mid,
issueDate,
paymentMethod,
amount
amount,
setDetailData
}: ListItemProps) => {
const { t, i18n } = useTranslation();
const { navigate } = useNavigate();
const onClickToNavigate = () => {
navigate(PATHS.vatReturn.detail, {
state: {
taxInvoiceNumber: id
}
});
if(setDetailData && taxInvoiceNumber){
setDetailData({
taxInvoiceNumber: taxInvoiceNumber,
detailOn: true
});
}
};
return (

View File

@@ -7,6 +7,7 @@ import { SortTypeBox } from '@/entities/common/ui/sort-type-box';
import { DefaultRequestPagination, SortTypeKeys } from '@/entities/common/model/types';
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
import {
DetailData,
VatReturnListContent,
VatReturnListParams,
VatReturnListResponse,
@@ -18,6 +19,7 @@ import { ListDateGroup } from './list-date-group';
import { useStore } from '@/shared/model/store';
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
import useIntersectionObserver from '@/widgets/intersection-observer';
import { TaxInvoiceDetail } from './detail/tax-invoice-detail';
export const ListWrap = () => {
const { t } = useTranslation();
@@ -36,7 +38,10 @@ export const ListWrap = () => {
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
const [detailOn, setDetailOn] = useState<boolean>(false);
const [detailTaxInvoiceNumber, setDetailTaxInvoiceNumber] = useState<string>('');
const { mutateAsync: vatReturnList } = useVatReturnListMutation();
const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
entries.forEach((entry: IntersectionObserverEntry) => {
if(entry.isIntersecting){
@@ -122,6 +127,11 @@ export const ListWrap = () => {
mid, startMonth, endMonth,
receiptType, targetType, sortType
]);
const setDetailData = (detailData: DetailData) => {
setDetailOn(detailData.detailOn);
setDetailTaxInvoiceNumber(detailData.taxInvoiceNumber);
};
const getListDateGroup = () => {
let rs = [];
@@ -144,6 +154,7 @@ export const ListWrap = () => {
key={ date + '-' + i }
date={ date }
items={ list }
setDetailData={ setDetailData }
></ListDateGroup>
);
}
@@ -160,6 +171,7 @@ export const ListWrap = () => {
key={ date + '-last' }
date={ date }
items={ list }
setDetailData={ setDetailData }
></ListDateGroup>
);
}
@@ -220,6 +232,12 @@ export const ListWrap = () => {
setReceiptType={ setReceiptType }
setTargetType={ setTargetType }
></ListFilter>
<TaxInvoiceDetail
detailOn={ detailOn }
setDetailOn={ setDetailOn }
taxInvoiceNumber={ detailTaxInvoiceNumber }
>
</TaxInvoiceDetail>
{ !!emailBottomSheetOn &&
<EmailBottomSheet
bottomSheetOn={ emailBottomSheetOn }