현금영수증 수기 발행 완료
This commit is contained in:
@@ -54,7 +54,7 @@ export const CashReceiptHandWrittenIssuanceStep1 = ({
|
||||
className="error"
|
||||
type="text"
|
||||
value={ businessNumber }
|
||||
disabled={ true }
|
||||
readOnly={ true }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,37 +1,40 @@
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useSetOnBack } from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { ProcessStep } from '../model/types';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
|
||||
export interface CashReceiptHandWrittenIssuanceStep2Props {
|
||||
setProcessStep: (processStep: ProcessStep) => void;
|
||||
issueAmount: number;
|
||||
supplyAmount: number;
|
||||
vatAmount: number;
|
||||
taxFreeAmount: number;
|
||||
serviceCharge: number;
|
||||
setIssueAmount: (issueAmount: number) => void;
|
||||
setSupplyAmount: (supplyAmount: number) => void;
|
||||
setVatAmount: (vatAmount: number) => void;
|
||||
setTaxFreeAmount: (taxFreeAmount: number) => void;
|
||||
setServiceCharge: (serviceCharge: number) => void;
|
||||
onClickToVatCalculate: () => void;
|
||||
};
|
||||
export const CashReceiptHandWrittenIssuanceStep2 = ({
|
||||
setProcessStep,
|
||||
issueAmount,
|
||||
supplyAmount,
|
||||
vatAmount,
|
||||
taxFreeAmount,
|
||||
serviceCharge,
|
||||
setIssueAmount,
|
||||
setSupplyAmount,
|
||||
setVatAmount,
|
||||
setTaxFreeAmount,
|
||||
setServiceCharge
|
||||
setServiceCharge,
|
||||
onClickToVatCalculate
|
||||
}: CashReceiptHandWrittenIssuanceStep2Props) => {
|
||||
useSetOnBack(() => {
|
||||
setProcessStep(ProcessStep.One);
|
||||
});
|
||||
|
||||
const onClickToVatCalculate = () => {
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="issue-title">발행 금액 입력</h2>
|
||||
@@ -41,15 +44,16 @@ export const CashReceiptHandWrittenIssuanceStep2 = ({
|
||||
<div className="issue-label">발행금액</div>
|
||||
<div className="issue-field">
|
||||
<div className="seg-buttons">
|
||||
<input
|
||||
type="text"
|
||||
value="555,555,555"
|
||||
readOnly={ true }
|
||||
/>
|
||||
<NumericFormat
|
||||
value={ issueAmount }
|
||||
allowNegative={ false }
|
||||
displayType="input"
|
||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setIssueAmount(parseInt(e.target.value)) }
|
||||
></NumericFormat>
|
||||
<button
|
||||
className="btn-40 btn-white"
|
||||
type="button"
|
||||
onClick={ () => onClickToVatCalculate() }
|
||||
onClick={ onClickToVatCalculate }
|
||||
>VAT자동계산</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,49 +62,45 @@ export const CashReceiptHandWrittenIssuanceStep2 = ({
|
||||
<div className="issue-row">
|
||||
<div className="issue-label">공급가액</div>
|
||||
<div className="issue-field">
|
||||
<input
|
||||
className="error"
|
||||
type="text"
|
||||
placeholder=""
|
||||
<NumericFormat
|
||||
value={ supplyAmount }
|
||||
allowNegative={ false }
|
||||
displayType="input"
|
||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setSupplyAmount(parseInt(e.target.value)) }
|
||||
/>
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="issue-row">
|
||||
<div className="issue-label">VAT</div>
|
||||
<div className="issue-field">
|
||||
<input
|
||||
className="error"
|
||||
type="text"
|
||||
placeholder=""
|
||||
<NumericFormat
|
||||
value={ vatAmount }
|
||||
allowNegative={ false }
|
||||
displayType="input"
|
||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setVatAmount(parseInt(e.target.value)) }
|
||||
/>
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="issue-row">
|
||||
<div className="issue-label">면세금액</div>
|
||||
<div className="issue-field">
|
||||
<input
|
||||
className="error"
|
||||
type="text"
|
||||
placeholder=""
|
||||
<NumericFormat
|
||||
value={ taxFreeAmount }
|
||||
allowNegative={ false }
|
||||
displayType="input"
|
||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setTaxFreeAmount(parseInt(e.target.value)) }
|
||||
/>
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="issue-row">
|
||||
<div className="issue-label">봉사료</div>
|
||||
<div className="issue-field">
|
||||
<input
|
||||
className="error"
|
||||
type="text"
|
||||
placeholder=""
|
||||
<NumericFormat
|
||||
value={ serviceCharge }
|
||||
allowNegative={ false }
|
||||
displayType="input"
|
||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setServiceCharge(parseInt(e.target.value)) }
|
||||
/>
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="issue-note error">
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL_USER } from '@/shared/api/api-url-user';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { NiceAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
BusinessPropertyByMidParams,
|
||||
BusinessPropertyByMidResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const businessPropertyByMid = (params: BusinessPropertyByMidParams) => {
|
||||
return resultify(
|
||||
axios.post<BusinessPropertyByMidResponse>(API_URL_USER.businessPropertyByMid(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useBusinessPropertyByMidMutation = (options?: UseMutationOptions<BusinessPropertyByMidResponse, NiceAxiosError, BusinessPropertyByMidParams>) => {
|
||||
const mutation = useMutation<BusinessPropertyByMidResponse, NiceAxiosError, BusinessPropertyByMidParams>({
|
||||
...options,
|
||||
mutationFn: (params: BusinessPropertyByMidParams) => businessPropertyByMid(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
29
src/entities/user/api/use-business-property-mutation.ts
Normal file
29
src/entities/user/api/use-business-property-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL_USER } from '@/shared/api/api-url-user';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { NiceAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
BusinessPropertyParams,
|
||||
BusinessPropertyResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const businessProperty = (params: BusinessPropertyParams) => {
|
||||
return resultify(
|
||||
axios.post<BusinessPropertyResponse>(API_URL_USER.businessProperty(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useBusinessPropertyMutation = (options?: UseMutationOptions<BusinessPropertyResponse, NiceAxiosError, BusinessPropertyParams>) => {
|
||||
const mutation = useMutation<BusinessPropertyResponse, NiceAxiosError, BusinessPropertyParams>({
|
||||
...options,
|
||||
mutationFn: (params: BusinessPropertyParams) => businessProperty(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -261,13 +261,13 @@ export interface ShortcutUserResponse {
|
||||
usingDefault: boolean;
|
||||
};
|
||||
|
||||
export interface BusinessPropertyByMidParams {
|
||||
export interface BusinessPropertyParams {
|
||||
mid: string;
|
||||
};
|
||||
export interface BusinessPropertyByMidResponse {
|
||||
export interface BusinessPropertyResponse {
|
||||
companyNumber: string;
|
||||
businessScaleTypeName: string;
|
||||
};
|
||||
export interface BusinessInfo extends BusinessPropertyByMidResponse {
|
||||
export interface BusinessInfo extends BusinessPropertyResponse {
|
||||
|
||||
};
|
||||
@@ -14,6 +14,6 @@ export const VatReturnTargetTypeBtnGroup = [
|
||||
];
|
||||
|
||||
export const VatReturnTaxBtnGroups = [
|
||||
{name: '과세', value: VatReturnPayTax.Tax },
|
||||
{name: '면세', value: VatReturnPayTax.NoTax },
|
||||
{name: '과세', value: VatReturnPayTax.TAX },
|
||||
{name: '면세', value: VatReturnPayTax.NOTAX },
|
||||
];
|
||||
@@ -14,8 +14,8 @@ export enum VatReturnReceiptType {
|
||||
BILL = 'BILL '
|
||||
};
|
||||
export enum VatReturnPayTax {
|
||||
Tax = 'Tax',
|
||||
NoTax = 'NoTax'
|
||||
TAX = '0',
|
||||
NOTAX = '1'
|
||||
};
|
||||
export enum VatReturnTargetType {
|
||||
ALL = 'ALL',
|
||||
@@ -91,8 +91,6 @@ export interface VatReturnReferenceRequestParams {
|
||||
startMonth: string;
|
||||
endMonth: string;
|
||||
taxType: string,
|
||||
requestorName: string;
|
||||
contactNumber: string;
|
||||
email: string;
|
||||
};
|
||||
export interface VatReturnReferenceRequestResponse {
|
||||
|
||||
@@ -22,7 +22,7 @@ export const ReferenceWrap = () => {
|
||||
const [mid, setMid] = useState<string>(userMid);
|
||||
const [startDate, setStartDate] = useState<string>(moment().format('YYYYMMDD'));
|
||||
const [endDate, setEndDate] = useState<string>(moment().format('YYYYMMDD'));
|
||||
const [payTax, setPayTax] = useState<VatReturnPayTax>(VatReturnPayTax.Tax);
|
||||
const [payTax, setPayTax] = useState<VatReturnPayTax>(VatReturnPayTax.TAX);
|
||||
const [email, setEmail] = useState<string>(userEmail);
|
||||
const [errorMsg, setErrorMsg] = useState<string>('');
|
||||
|
||||
@@ -34,9 +34,7 @@ export const ReferenceWrap = () => {
|
||||
startMonth: startDate,
|
||||
endMonth: endDate,
|
||||
taxType: payTax,
|
||||
requestorName: '',
|
||||
contactNumber: '',
|
||||
email: email
|
||||
email: email || userEmail
|
||||
}
|
||||
vatReturnReferenceRequest(params).then((rs: VatReturnReferenceRequestResponse) => {
|
||||
setSuccessPageOn(true);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { CashReceiptHandWrittenIssuanceStep1 } from '@/entities/transaction/ui/cash-receipt-hand-written-issuance-step1';
|
||||
@@ -8,19 +8,23 @@ import { HeaderType} from '@/entities/common/model/types';
|
||||
import { useSetFooterMode, useSetHeaderTitle, useSetHeaderType } from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useCashReceiptManualIssueMutation } from '@/entities/transaction/api/use-cash-receipt-manual-issue-mutation';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
|
||||
export const CashReceitHandWrittenIssuancePage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
let businessInfo = useStore.getState().UserStore.businessInfo;
|
||||
let userMid = useStore.getState().UserStore.mid;
|
||||
// 1 or 2
|
||||
const [processStep, setProcessStep] = useState<ProcessStep>(ProcessStep.One);
|
||||
const [businessNumber, setBusinessNumber] = useState<string>('');
|
||||
const [businessNumber, setBusinessNumber] = useState<string>(businessInfo.companyNumber);
|
||||
const [purposeType, setPurposeType] = useState<CashReceiptPurposeType>(CashReceiptPurposeType.INCOME_DEDUCTION);
|
||||
const [productName, setProductName] = useState<string>('');
|
||||
const [buyerName, setBuyerName] = useState<string>('');
|
||||
const [issueNumber, setIssueNumber] = useState<string>('');
|
||||
const [email, setEmail] = useState<string>('');
|
||||
const [phoneNumber, setPhoneNumber] = useState<string>('');
|
||||
const [issueAmount, setIssueAmount] = useState<number>(0);
|
||||
const [supplyAmount, setSupplyAmount] = useState<number>(0);
|
||||
const [vatAmount, setVatAmount] = useState<number>(0);
|
||||
const [taxFreeAmount, setTaxFreeAmount] = useState<number>(0);
|
||||
@@ -44,6 +48,7 @@ export const CashReceitHandWrittenIssuancePage = () => {
|
||||
|
||||
const callManualIssue = () => {
|
||||
let params = {
|
||||
mid: userMid,
|
||||
businessNumber: businessNumber,
|
||||
purpose: purposeType,
|
||||
productName: productName,
|
||||
@@ -58,41 +63,57 @@ export const CashReceitHandWrittenIssuancePage = () => {
|
||||
};
|
||||
cashReceiptManualIssue(params).then((rs) => {
|
||||
console.log(rs);
|
||||
alert('완료');
|
||||
navigate(PATHS.transaction.cashReceipt.list);
|
||||
snackBar('수기 신청이 완료되었습니다.', function(){
|
||||
navigate(PATHS.transaction.cashReceipt.list);
|
||||
}, 3000);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToVatCalculate = () => {
|
||||
let amount = parseInt((issueAmount / 11 * 10).toFixed(0));
|
||||
let vat = issueAmount - amount;
|
||||
setSupplyAmount(amount);
|
||||
setVatAmount(vat);
|
||||
};
|
||||
|
||||
const onClickToChangeTab = () => {
|
||||
if(processStep === ProcessStep.One){
|
||||
if(!businessNumber){
|
||||
showAlert('사업자 번호는 필수 입력 항목 입니다.');
|
||||
return;
|
||||
}
|
||||
else if(!productName){
|
||||
showAlert('상품명은 필수 입력 항목 입니다.');
|
||||
return;
|
||||
}
|
||||
else if(!buyerName){
|
||||
showAlert('구매자는 필수 입력 항목 입니다.');
|
||||
return;
|
||||
}
|
||||
else if(!issueNumber){
|
||||
showAlert('발행번호는 필수 입력 항목 입니다.');
|
||||
return;
|
||||
}
|
||||
else if(email && !checkEmail(email)){
|
||||
showAlert('이메일 형식이 맞지 않습니다.');
|
||||
return;
|
||||
}
|
||||
else if(!phoneNumber){
|
||||
showAlert('전화번호는 필수 입력 항목 입니다.');
|
||||
return;
|
||||
}
|
||||
setProcessStep(ProcessStep.Two);
|
||||
}
|
||||
else if(processStep === ProcessStep.Two){
|
||||
if(supplyAmount <= 0){
|
||||
showAlert('공급가액은 1원 이상이어야 합니다.');
|
||||
return;
|
||||
}
|
||||
callManualIssue();
|
||||
// 완료시?
|
||||
//alert('완료');
|
||||
// navigate(PATHS.transaction.cashReceipt.list);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
@@ -136,14 +157,17 @@ export const CashReceitHandWrittenIssuancePage = () => {
|
||||
{ (processStep === ProcessStep.Two) &&
|
||||
<CashReceiptHandWrittenIssuanceStep2
|
||||
setProcessStep={ setProcessStep }
|
||||
issueAmount={ issueAmount }
|
||||
supplyAmount={ supplyAmount }
|
||||
vatAmount={ vatAmount }
|
||||
taxFreeAmount={ taxFreeAmount }
|
||||
serviceCharge={ serviceCharge }
|
||||
setIssueAmount={ setIssueAmount }
|
||||
setSupplyAmount={ setSupplyAmount }
|
||||
setVatAmount={ setVatAmount }
|
||||
setTaxFreeAmount={ setTaxFreeAmount }
|
||||
setServiceCharge={ setServiceCharge }
|
||||
onClickToVatCalculate={ onClickToVatCalculate }
|
||||
></CashReceiptHandWrittenIssuanceStep2>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -60,7 +60,7 @@ export const API_URL_USER = {
|
||||
},
|
||||
|
||||
// mid 로 사업자 정보 조회
|
||||
businessPropertyByMid: () => {
|
||||
return `${API_BASE_URL}/api/v1/amsw/business-property/by-mid`;
|
||||
businessProperty: () => {
|
||||
return `${API_BASE_URL}/api/v1/${API_URL_KEY}/business-property`;
|
||||
},
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ChangeEvent } from "react";
|
||||
|
||||
export interface FilterSelectProps {
|
||||
title: string;
|
||||
selectValue: string;
|
||||
@@ -18,7 +20,6 @@ export const FilterSelect = ({
|
||||
<option
|
||||
key={ `key-filter-select-${i}` }
|
||||
value={ selectOptions[i]?.value }
|
||||
selected={ (selectValue === selectOptions[i]?.value)? true: false }
|
||||
>{ selectOptions[i]?.name }</option>
|
||||
);
|
||||
}
|
||||
@@ -33,7 +34,7 @@ export const FilterSelect = ({
|
||||
<select
|
||||
className="flex-1"
|
||||
value={ selectValue }
|
||||
onChange={ (e: any) => selectSetter(e.target.value)}
|
||||
onChange={ (e: ChangeEvent<HTMLSelectElement>) => selectSetter(e.target.value)}
|
||||
>
|
||||
{ getSelectOptions() }
|
||||
</select>
|
||||
|
||||
@@ -23,10 +23,10 @@ import { useStore } from '@/shared/model/store';
|
||||
import { getLocalStorage, setLocalStorage } from '@/shared/lib';
|
||||
import { StorageKeys } from '@/shared/constants/local-storage';
|
||||
import { HomeGroupsParams, HomeGroupsResponse } from '@/entities/home/model/types';
|
||||
import { BusinessPropertyByMidParams, BusinessPropertyByMidResponse, LoginResponse, ShortcutUserParams, ShortcutUserResponse, UserFindAuthMethodParams, UserFindAuthMethodResponse } from '@/entities/user/model/types';
|
||||
import { BusinessPropertyParams, BusinessPropertyResponse, LoginResponse, ShortcutUserParams, ShortcutUserResponse, UserFindAuthMethodParams, UserFindAuthMethodResponse } from '@/entities/user/model/types';
|
||||
import { useShortcutUserMutation } from '@/entities/user/api/use-shortcut-user-mutation';
|
||||
import { useShortcutDefaultMutation } from '@/entities/user/api/use-shortcut-detault-mutation';
|
||||
import { useBusinessPropertyByMidMutation } from '@/entities/user/api/use-business-property-by-mid-mutation';
|
||||
import { useBusinessPropertyMutation } from '@/entities/user/api/use-business-property-mutation';
|
||||
import { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find-authmethod-mutation';
|
||||
import { useCodesSelectMutation } from '@/entities/common/api/use-codes-select-mutation';
|
||||
|
||||
@@ -75,7 +75,7 @@ export const SubLayout = () => {
|
||||
const { mutateAsync: codesSelect} = useCodesSelectMutation();
|
||||
const { mutateAsync: shortcutUser } = useShortcutUserMutation();
|
||||
const { mutateAsync: shortcutDefault } = useShortcutDefaultMutation();
|
||||
const { mutateAsync: businessPropertyByMid } = useBusinessPropertyByMidMutation();
|
||||
const { mutateAsync: businessProperty } = useBusinessPropertyMutation();
|
||||
const { mutateAsync: findAuthMethod } = useUserFindAuthMethodMutation();
|
||||
|
||||
const wrapperClassName = 'wrapper';
|
||||
@@ -106,13 +106,13 @@ export const SubLayout = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const callBusinessPropertyByMid = () => {
|
||||
const callBusinessProperty = () => {
|
||||
if(!!mid){
|
||||
let params: BusinessPropertyByMidParams = {
|
||||
let params: BusinessPropertyParams = {
|
||||
mid: mid
|
||||
};
|
||||
businessPropertyByMid(params).then((rs: BusinessPropertyByMidResponse) => {
|
||||
console.log(rs);
|
||||
businessProperty(params).then((rs: BusinessPropertyResponse) => {
|
||||
useStore.getState().UserStore.setBusinessInfo(rs);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -178,7 +178,6 @@ export const SubLayout = () => {
|
||||
let emails = rs.emails.map((value: any, index: any) => {
|
||||
return value.content;
|
||||
});
|
||||
console.log('emails -->', emails)
|
||||
useStore.getState().UserStore.setUserEmails(emails);
|
||||
let options: Array<Record<string, string>> = emails.map((value: any, index: any) => {
|
||||
return {
|
||||
@@ -300,7 +299,7 @@ export const SubLayout = () => {
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if(!!mid){
|
||||
// callBusinessPropertyByMid();
|
||||
callBusinessProperty();
|
||||
callFindAuthMethod();
|
||||
}
|
||||
}, [mid]);
|
||||
|
||||
Reference in New Issue
Block a user