This commit is contained in:
focp212@naver.com
2025-11-10 16:48:39 +09:00
parent bcd4e17edf
commit 0290725c0b
6 changed files with 145 additions and 151 deletions

View File

@@ -1,5 +1,4 @@
import moment from 'moment';
import { NumericFormat } from 'react-number-format';
import { useTranslation } from 'react-i18next';
import { AdditionalServiceCategory, DetailInfoSectionKeys } from '../../model/types';
import { DetailInfoSectionProps } from '../../model/types';

View File

@@ -6,16 +6,31 @@ import { toPng } from 'html-to-image';
import { useTranslation } from 'react-i18next';
import '@/shared/ui/assets/css/style-tax-invoice.css';
import { useEffect } from 'react';
import { NumericFormat } from 'react-number-format';
import { AmountInfo, CustomerInfo, IssueInfo, MerchantInfo, ProductInfo, TransactionInfo } from '@/entities/transaction/model/types';
import moment from 'moment';
export interface TaxInoviceSampleProps {
taxInvoiceOn: boolean;
setTaxInvoiceOn: (taxInvoiceOn: boolean) => void;
export interface CashReceiptSampleProps {
cashReceiptSampleOn: boolean;
setCashReceiptSampleOn: (taxInvoiceOn: boolean) => void;
merchantInfo?: MerchantInfo;
issueInfo?: IssueInfo;
amountInfo?: AmountInfo;
transactionInfo?: TransactionInfo;
customerInfo?: CustomerInfo;
productInfo?: ProductInfo;
};
export const TaxInvoiceSample = ({
taxInvoiceOn,
setTaxInvoiceOn
}: TaxInoviceSampleProps) => {
export const CashReceiptSample = ({
cashReceiptSampleOn,
setCashReceiptSampleOn,
merchantInfo,
issueInfo,
amountInfo,
transactionInfo,
customerInfo,
productInfo
}: CashReceiptSampleProps) => {
const { t } = useTranslation();
const downloadImage = () => {
@@ -31,14 +46,26 @@ export const TaxInvoiceSample = ({
});
};
const onClickToClose = () => {
setTaxInvoiceOn(false);
setCashReceiptSampleOn(false);
};
const getDateTime = () => {
let date = '';
let time = '';
if(!!issueInfo?.issueDate){
date = moment(issueInfo?.issueDate).format('YYYY.MM.DD');
}
if(!!issueInfo?.issueDate && !!issueInfo?.issueTime){
time = moment(issueInfo?.issueDate+' '+issueInfo?.issueTime).format('HH:mm:ss');
}
return date + ' | ' + time;
};
useEffect(() => {
if(!!taxInvoiceOn){
if(!!cashReceiptSampleOn){
downloadImage();
}
}, [taxInvoiceOn]);
}, [cashReceiptSampleOn]);
return (
@@ -46,51 +73,11 @@ export const TaxInvoiceSample = ({
<motion.div
className="bottomsheet mail-page"
initial="hidden"
animate={ (taxInvoiceOn)? 'hidden': 'hidden' }
animate={ (cashReceiptSampleOn)? 'hidden': 'hidden' }
variants={ FilterMotionVariants }
transition={ FilterMotionDuration }
>
<div className="wrap">
<div className="header">
<div className="header-top">
<img
className="logo"
src={ IMAGE_ROOT + '/mail_nicepay_logo.svg' }
alt="NICEPAY"
/>
<img
className="close-ic"
src={ IMAGE_ROOT + '/ico_close.svg' }
alt="닫기"
/>
</div>
<div className="email-row">
<div className="label"> </div>
<input
className="input40"
type="email"
placeholder="test@abc.com"
aria-label="수신 이메일 주소 입력"
/>
<a
className="btn btn-dark"
style={{ width: '46px' }}
></a>
<a className="btn btn-primary"></a>
</div>
<div className="divider"></div>
<div className="title-row">
<div className="title"> </div>
<select
className="select-outline"
aria-label="작업 선택"
>
<option value="cancel"></option>
<option value="reprint"></option>
</select>
</div>
</div>
<div id="image-section">
<div className="section">
<div className="head">
@@ -111,27 +98,27 @@ export const TaxInvoiceSample = ({
</div>
<div className="row">
<div className="k"></div>
<div className="v"> </div>
<div className="v">{ merchantInfo?.merchantName }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"></div>
<div className="v">{ merchantInfo?.representativeName }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">815-81-00527</div>
<div className="v">{ merchantInfo?.businessNumber }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">1661-7335</div>
<div className="v">{ merchantInfo?.phoneNumber }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"> 217 11</div>
<div className="v">{ merchantInfo?.address }</div>
</div>
<div className="row">
<div className="k">URL</div>
<div className="v">home.nicepay.co.kr</div>
<div className="v"></div>
</div>
</div>
<div className="divider"></div>
@@ -157,102 +144,90 @@ export const TaxInvoiceSample = ({
</div>
<div className="amount-row">
<div className="k"> </div>
<div className="v">4,552,000</div>
<div className="v">
<NumericFormat
value={ amountInfo?.amount }
thousandSeparator
displayType="text"
></NumericFormat>
</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">343,940</div>
<div className="k"></div>
<div className="v">
<NumericFormat
value={ amountInfo?.supplyAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">343,940</div>
<div className="v">
<NumericFormat
value={ amountInfo?.vatAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">
<NumericFormat
value={ amountInfo?.taxFreeAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">
<NumericFormat
value={ amountInfo?.serviceAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</div>
</div>
<div className="row split"></div>
<div className="row">
<div className="k"></div>
<div className="v"></div>
<div className="k"></div>
<div className="v">{ transactionInfo?.paymentMethod }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">489023******0070</div>
<div className="k"></div>
<div className="v">{ issueInfo?.issueNumber }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">*</div>
<div className="k"></div>
<div className="v">{ customerInfo?.customerName }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"></div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"></div>
</div>
<div className="row">
<div className="k">/</div>
<div className="v"></div>
<div className="v">{ productInfo?.productName }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">14219606</div>
<div className="v">{ issueInfo?.approvalNumber }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">2025.09.22 | 11:32:29</div>
<div className="v">{ getDateTime() }</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">2025.09.22 | 23:10:16</div>
</div>
</div>
<div className="divider"></div>
<div className="section">
<div className="head">
<div className="icon">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
>
<path d="M18.4004 0.849609C18.8129 0.849821 19.1502 1.18707 19.1504 1.59961V18.4004C19.1502 18.8129 18.8129 19.1502 18.4004 19.1504H1.59961C1.18707 19.1502 0.849821 18.8129 0.849609 18.4004V11.2002C0.849609 10.7875 1.18694 10.4504 1.59961 10.4502H8.0498V1.59961C8.05002 1.18701 8.38718 0.849716 8.7998 0.849609H18.4004ZM9.5498 17.6504H17.6504V2.34961H9.5498V17.6504ZM2.34961 17.6504H8.0498V11.9502H2.34961V17.6504Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M12.5496 4.44922V6.5498H11.0496V4.44922H12.5496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M16.1496 4.44922V6.5498H14.6496V4.44922H16.1496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M12.5496 7.44922V9.5498H11.0496V7.44922H12.5496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M16.1496 7.44922V9.5498H14.6496V7.44922H16.1496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M12.5496 10.4492V12.5498H11.0496V10.4492H12.5496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M16.1496 10.4492V12.5498H14.6496V10.4492H16.1496Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
<path d="M6.15039 13.8496V15.1504H3.84961V13.8496H6.15039Z" fill="#2D3436" stroke="#2D3436" strokeWidth="0.3"/>
</svg>
</div>
<div className="h-title"> </div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"> </div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"></div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">815-81-00527</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v">1661-0808</div>
</div>
<div className="row">
<div className="k"></div>
<div className="v"> 28 25 (3)</div>
<div className="k"></div>
<div className="v">{ issueInfo?.purpose }</div>
</div>
</div>
</div>
<div className="notice"> NICE로 .<br />* 46 .<br />( 33 2 .)</div>
<div className="notice">
* 126 3 121 3 , .<br />
* 2 .<br />
* 126-1-1
</div>
</div>
</motion.div>
</>

View File

@@ -375,6 +375,7 @@ export interface AmountInfo {
simplePaymentServiceCode?: string;
buyerName?: string;
vatAmount?: number;
};
export interface ImportantInfo {
moid?: string;
@@ -467,6 +468,9 @@ export interface TransactionInfo {
cashReceiptIssue?: string;
transactionDateTime?: string;
transactionAmount?: number;
tid?: string;
merchantTid?: string;
paymentMethod?: string;
};
export interface SettlementInfo {
approvalSettlementDate?: string;
@@ -548,7 +552,14 @@ export interface MerchantInfo {
companyName?: string;
gid?: string;
aid?: string;
}
merchantName?: string;
businessNumber?: string;
representativeName?: string;
address?: string;
phoneNumber?: string;
subMallName?: string;
subMallBusinessNumber?: string;
};
export interface DetailResponse {
amount?: number;

View File

@@ -1,14 +1,14 @@
import moment from 'moment';
import { useTranslation } from 'react-i18next';
import { SectionTitleArrow } from '@/entities/common/ui/section-title-arrow';
import { CashReceiptReceiptDownloadParams, CashReceiptReceiptDownloadResponse, InfoSectionKeys, InfoSectionProps, TransactionCategory } from '../../model/types';
import { AmountInfo, CashReceiptReceiptDownloadParams, CashReceiptReceiptDownloadResponse, CustomerInfo, InfoSectionKeys, InfoSectionProps, IssueInfo, MerchantInfo, ProductInfo, TransactionCategory, TransactionInfo } from '../../model/types';
import { SlideDown } from 'react-slidedown';
import 'react-slidedown/lib/slidedown.css';
import { snackBar } from '@/shared/lib';
import { useCashReceiptReceiptDownloadMutation } from '../../api/use-cash-receipt-receipt-download-mutation';
import { useState } from 'react';
import { DownloadBottomSheet, DownloadSelectedMode } from '@/entities/common/ui/download-bottom-sheet';
import { TaxInvoiceSample } from '@/entities/common/ui/tax-invoice-sample';
import { CashReceiptSample } from '@/entities/common/ui/cash-receipt-sample';
export const AmountInfoSection = ({
transactionCategory,
@@ -23,7 +23,14 @@ export const AmountInfoSection = ({
const { mutateAsync: cashReceiptReceiptDownload } = useCashReceiptReceiptDownloadMutation();
const [downloadBottomSheetOn, setDownloadBottomSheetOn] = useState<boolean>(false);
const [taxInvoiceOn, setTaxInvoiceOn] = useState<boolean>(false);
const [cashReceiptSampleOn, setCashReceiptSampleOn] = useState<boolean>(false);
const [receiptIssueInfo, setReceiptIssueInfo] = useState<IssueInfo>({});
const [receiptMerchantInfo, setReceiptMerchantInfo] = useState<MerchantInfo>({});
const [receiptTransactionInfo, setReceiptTransactionInfo] = useState<TransactionInfo>({});
const [receiptAmountInfo, setReceiptAmountInfo] = useState<AmountInfo>({});
const [receiptCustomerInfo, setReceiptCustomerInfo] = useState<CustomerInfo>();
const [receiptProductInfo, setReceiptProductInfo] = useState<ProductInfo>();
let newAmountInfo: Record<string, any> | undefined = amountInfo;
const subItems: Record<string, Record<string, string>> = {
@@ -196,15 +203,19 @@ export const AmountInfoSection = ({
selectedMode: DownloadSelectedMode,
userEmail?: string
) => {
console.log(selectedMode, userEmail, tid)
if(!!tid){
let params: CashReceiptReceiptDownloadParams = {
tid: tid
};
cashReceiptReceiptDownload(params).then((rs: CashReceiptReceiptDownloadResponse) => {
console.log(rs);
setReceiptIssueInfo(rs?.issueInfo);
setReceiptMerchantInfo(rs?.merchantInfo);
setReceiptTransactionInfo(rs?.transactionInfo);
setReceiptAmountInfo(rs?.amountInfo);
setReceiptCustomerInfo(rs?.customerInfo);
setReceiptProductInfo(rs?.productInfo);
if(selectedMode === DownloadSelectedMode.IMAGE){
setTaxInvoiceOn(true);
setCashReceiptSampleOn(true);
}
else if(selectedMode === DownloadSelectedMode.EMAIL){
snackBar('거래확인서 다운 성공');
@@ -431,10 +442,16 @@ export const AmountInfoSection = ({
></DownloadBottomSheet>
}
{
<TaxInvoiceSample
taxInvoiceOn={ taxInvoiceOn }
setTaxInvoiceOn={ setTaxInvoiceOn }
></TaxInvoiceSample>
<CashReceiptSample
cashReceiptSampleOn={ cashReceiptSampleOn }
setCashReceiptSampleOn={ setCashReceiptSampleOn }
merchantInfo={ receiptMerchantInfo }
issueInfo={ receiptIssueInfo }
amountInfo={ receiptAmountInfo }
transactionInfo={ receiptTransactionInfo }
customerInfo={ receiptCustomerInfo }
productInfo={ receiptProductInfo }
></CashReceiptSample>
}
</>
);

View File

@@ -53,13 +53,6 @@ export const TaxInvoiceDetail = ({
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();
@@ -121,7 +114,7 @@ export const TaxInvoiceDetail = ({
>
<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-title center">{ t('vatReturn.taxInvoiceDetail') }</div>
<div className="full-menu-actions">
<FullMenuClose
addClass="full-menu-close"
@@ -129,7 +122,7 @@ export const TaxInvoiceDetail = ({
></FullMenuClose>
</div>
</div>
<div className="option-list">
<div className="option-list pb-86">
<div className="txn-detail">
<AmountSection
detail={ detail }

View File

@@ -248,8 +248,7 @@ export const ListWrap = () => {
detailOn={ detailOn }
setDetailOn={ setDetailOn }
taxInvoiceNumber={ detailTaxInvoiceNumber }
>
</TaxInvoiceDetail>
></TaxInvoiceDetail>
{ !!downloadBottomSheetOn &&
<DownloadBottomSheet
bottomSheetOn={ downloadBottomSheetOn }