현금영수증 수기 발행 완료

This commit is contained in:
focp212@naver.com
2025-10-24 10:28:34 +09:00
parent c2041f918f
commit 9348656db0
12 changed files with 117 additions and 97 deletions

View File

@@ -54,7 +54,7 @@ export const CashReceiptHandWrittenIssuanceStep1 = ({
className="error" className="error"
type="text" type="text"
value={ businessNumber } value={ businessNumber }
disabled={ true } readOnly={ true }
/> />
</div> </div>
</div> </div>

View File

@@ -1,37 +1,40 @@
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
import { useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { useSetOnBack } from '@/widgets/sub-layout/use-sub-layout';
import { ProcessStep } from '../model/types'; import { ProcessStep } from '../model/types';
import { NumericFormat } from 'react-number-format';
export interface CashReceiptHandWrittenIssuanceStep2Props { export interface CashReceiptHandWrittenIssuanceStep2Props {
setProcessStep: (processStep: ProcessStep) => void; setProcessStep: (processStep: ProcessStep) => void;
issueAmount: number;
supplyAmount: number; supplyAmount: number;
vatAmount: number; vatAmount: number;
taxFreeAmount: number; taxFreeAmount: number;
serviceCharge: number; serviceCharge: number;
setIssueAmount: (issueAmount: number) => void;
setSupplyAmount: (supplyAmount: number) => void; setSupplyAmount: (supplyAmount: number) => void;
setVatAmount: (vatAmount: number) => void; setVatAmount: (vatAmount: number) => void;
setTaxFreeAmount: (taxFreeAmount: number) => void; setTaxFreeAmount: (taxFreeAmount: number) => void;
setServiceCharge: (serviceCharge: number) => void; setServiceCharge: (serviceCharge: number) => void;
onClickToVatCalculate: () => void;
}; };
export const CashReceiptHandWrittenIssuanceStep2 = ({ export const CashReceiptHandWrittenIssuanceStep2 = ({
setProcessStep, setProcessStep,
issueAmount,
supplyAmount, supplyAmount,
vatAmount, vatAmount,
taxFreeAmount, taxFreeAmount,
serviceCharge, serviceCharge,
setIssueAmount,
setSupplyAmount, setSupplyAmount,
setVatAmount, setVatAmount,
setTaxFreeAmount, setTaxFreeAmount,
setServiceCharge setServiceCharge,
onClickToVatCalculate
}: CashReceiptHandWrittenIssuanceStep2Props) => { }: CashReceiptHandWrittenIssuanceStep2Props) => {
useSetOnBack(() => { useSetOnBack(() => {
setProcessStep(ProcessStep.One); setProcessStep(ProcessStep.One);
}); });
const onClickToVatCalculate = () => {
};
return ( return (
<> <>
<h2 className="issue-title"> </h2> <h2 className="issue-title"> </h2>
@@ -41,15 +44,16 @@ export const CashReceiptHandWrittenIssuanceStep2 = ({
<div className="issue-label"></div> <div className="issue-label"></div>
<div className="issue-field"> <div className="issue-field">
<div className="seg-buttons"> <div className="seg-buttons">
<input <NumericFormat
type="text" value={ issueAmount }
value="555,555,555" allowNegative={ false }
readOnly={ true } displayType="input"
/> onChange={ (e: ChangeEvent<HTMLInputElement>) => setIssueAmount(parseInt(e.target.value)) }
></NumericFormat>
<button <button
className="btn-40 btn-white" className="btn-40 btn-white"
type="button" type="button"
onClick={ () => onClickToVatCalculate() } onClick={ onClickToVatCalculate }
>VAT자동계산</button> >VAT자동계산</button>
</div> </div>
</div> </div>
@@ -58,49 +62,45 @@ export const CashReceiptHandWrittenIssuanceStep2 = ({
<div className="issue-row"> <div className="issue-row">
<div className="issue-label"></div> <div className="issue-label"></div>
<div className="issue-field"> <div className="issue-field">
<input <NumericFormat
className="error"
type="text"
placeholder=""
value={ supplyAmount } value={ supplyAmount }
allowNegative={ false }
displayType="input"
onChange={ (e: ChangeEvent<HTMLInputElement>) => setSupplyAmount(parseInt(e.target.value)) } onChange={ (e: ChangeEvent<HTMLInputElement>) => setSupplyAmount(parseInt(e.target.value)) }
/> ></NumericFormat>
</div> </div>
</div> </div>
<div className="issue-row"> <div className="issue-row">
<div className="issue-label">VAT</div> <div className="issue-label">VAT</div>
<div className="issue-field"> <div className="issue-field">
<input <NumericFormat
className="error"
type="text"
placeholder=""
value={ vatAmount } value={ vatAmount }
allowNegative={ false }
displayType="input"
onChange={ (e: ChangeEvent<HTMLInputElement>) => setVatAmount(parseInt(e.target.value)) } onChange={ (e: ChangeEvent<HTMLInputElement>) => setVatAmount(parseInt(e.target.value)) }
/> ></NumericFormat>
</div> </div>
</div> </div>
<div className="issue-row"> <div className="issue-row">
<div className="issue-label"></div> <div className="issue-label"></div>
<div className="issue-field"> <div className="issue-field">
<input <NumericFormat
className="error"
type="text"
placeholder=""
value={ taxFreeAmount } value={ taxFreeAmount }
allowNegative={ false }
displayType="input"
onChange={ (e: ChangeEvent<HTMLInputElement>) => setTaxFreeAmount(parseInt(e.target.value)) } onChange={ (e: ChangeEvent<HTMLInputElement>) => setTaxFreeAmount(parseInt(e.target.value)) }
/> ></NumericFormat>
</div> </div>
</div> </div>
<div className="issue-row"> <div className="issue-row">
<div className="issue-label"></div> <div className="issue-label"></div>
<div className="issue-field"> <div className="issue-field">
<input <NumericFormat
className="error"
type="text"
placeholder=""
value={ serviceCharge } value={ serviceCharge }
allowNegative={ false }
displayType="input"
onChange={ (e: ChangeEvent<HTMLInputElement>) => setServiceCharge(parseInt(e.target.value)) } onChange={ (e: ChangeEvent<HTMLInputElement>) => setServiceCharge(parseInt(e.target.value)) }
/> ></NumericFormat>
</div> </div>
</div> </div>
<div className="issue-note error"> <div className="issue-note error">

View File

@@ -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,
};
};

View 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,
};
};

View File

@@ -261,13 +261,13 @@ export interface ShortcutUserResponse {
usingDefault: boolean; usingDefault: boolean;
}; };
export interface BusinessPropertyByMidParams { export interface BusinessPropertyParams {
mid: string; mid: string;
}; };
export interface BusinessPropertyByMidResponse { export interface BusinessPropertyResponse {
companyNumber: string; companyNumber: string;
businessScaleTypeName: string; businessScaleTypeName: string;
}; };
export interface BusinessInfo extends BusinessPropertyByMidResponse { export interface BusinessInfo extends BusinessPropertyResponse {
}; };

View File

@@ -14,6 +14,6 @@ export const VatReturnTargetTypeBtnGroup = [
]; ];
export const VatReturnTaxBtnGroups = [ export const VatReturnTaxBtnGroups = [
{name: '과세', value: VatReturnPayTax.Tax }, {name: '과세', value: VatReturnPayTax.TAX },
{name: '면세', value: VatReturnPayTax.NoTax }, {name: '면세', value: VatReturnPayTax.NOTAX },
]; ];

View File

@@ -14,8 +14,8 @@ export enum VatReturnReceiptType {
BILL = 'BILL ' BILL = 'BILL '
}; };
export enum VatReturnPayTax { export enum VatReturnPayTax {
Tax = 'Tax', TAX = '0',
NoTax = 'NoTax' NOTAX = '1'
}; };
export enum VatReturnTargetType { export enum VatReturnTargetType {
ALL = 'ALL', ALL = 'ALL',
@@ -91,8 +91,6 @@ export interface VatReturnReferenceRequestParams {
startMonth: string; startMonth: string;
endMonth: string; endMonth: string;
taxType: string, taxType: string,
requestorName: string;
contactNumber: string;
email: string; email: string;
}; };
export interface VatReturnReferenceRequestResponse { export interface VatReturnReferenceRequestResponse {

View File

@@ -22,7 +22,7 @@ export const ReferenceWrap = () => {
const [mid, setMid] = useState<string>(userMid); const [mid, setMid] = useState<string>(userMid);
const [startDate, setStartDate] = useState<string>(moment().format('YYYYMMDD')); const [startDate, setStartDate] = useState<string>(moment().format('YYYYMMDD'));
const [endDate, setEndDate] = 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 [email, setEmail] = useState<string>(userEmail);
const [errorMsg, setErrorMsg] = useState<string>(''); const [errorMsg, setErrorMsg] = useState<string>('');
@@ -34,9 +34,7 @@ export const ReferenceWrap = () => {
startMonth: startDate, startMonth: startDate,
endMonth: endDate, endMonth: endDate,
taxType: payTax, taxType: payTax,
requestorName: '', email: email || userEmail
contactNumber: '',
email: email
} }
vatReturnReferenceRequest(params).then((rs: VatReturnReferenceRequestResponse) => { vatReturnReferenceRequest(params).then((rs: VatReturnReferenceRequestResponse) => {
setSuccessPageOn(true); setSuccessPageOn(true);

View File

@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useEffect, useState } from 'react';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { CashReceiptHandWrittenIssuanceStep1 } from '@/entities/transaction/ui/cash-receipt-hand-written-issuance-step1'; 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 { useSetFooterMode, useSetHeaderTitle, useSetHeaderType } from '@/widgets/sub-layout/use-sub-layout';
import { useCashReceiptManualIssueMutation } from '@/entities/transaction/api/use-cash-receipt-manual-issue-mutation'; import { useCashReceiptManualIssueMutation } from '@/entities/transaction/api/use-cash-receipt-manual-issue-mutation';
import { showAlert } from '@/widgets/show-alert'; import { showAlert } from '@/widgets/show-alert';
import { useStore } from '@/shared/model/store';
import { snackBar } from '@/shared/lib';
export const CashReceitHandWrittenIssuancePage = () => { export const CashReceitHandWrittenIssuancePage = () => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
let businessInfo = useStore.getState().UserStore.businessInfo;
let userMid = useStore.getState().UserStore.mid;
// 1 or 2 // 1 or 2
const [processStep, setProcessStep] = useState<ProcessStep>(ProcessStep.One); 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 [purposeType, setPurposeType] = useState<CashReceiptPurposeType>(CashReceiptPurposeType.INCOME_DEDUCTION);
const [productName, setProductName] = useState<string>(''); const [productName, setProductName] = useState<string>('');
const [buyerName, setBuyerName] = useState<string>(''); const [buyerName, setBuyerName] = useState<string>('');
const [issueNumber, setIssueNumber] = useState<string>(''); const [issueNumber, setIssueNumber] = useState<string>('');
const [email, setEmail] = useState<string>(''); const [email, setEmail] = useState<string>('');
const [phoneNumber, setPhoneNumber] = useState<string>(''); const [phoneNumber, setPhoneNumber] = useState<string>('');
const [issueAmount, setIssueAmount] = useState<number>(0);
const [supplyAmount, setSupplyAmount] = useState<number>(0); const [supplyAmount, setSupplyAmount] = useState<number>(0);
const [vatAmount, setVatAmount] = useState<number>(0); const [vatAmount, setVatAmount] = useState<number>(0);
const [taxFreeAmount, setTaxFreeAmount] = useState<number>(0); const [taxFreeAmount, setTaxFreeAmount] = useState<number>(0);
@@ -44,6 +48,7 @@ export const CashReceitHandWrittenIssuancePage = () => {
const callManualIssue = () => { const callManualIssue = () => {
let params = { let params = {
mid: userMid,
businessNumber: businessNumber, businessNumber: businessNumber,
purpose: purposeType, purpose: purposeType,
productName: productName, productName: productName,
@@ -58,41 +63,57 @@ export const CashReceitHandWrittenIssuancePage = () => {
}; };
cashReceiptManualIssue(params).then((rs) => { cashReceiptManualIssue(params).then((rs) => {
console.log(rs); console.log(rs);
alert('완료'); snackBar('수기 신청이 완료되었습니다.', function(){
navigate(PATHS.transaction.cashReceipt.list); 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 = () => { const onClickToChangeTab = () => {
if(processStep === ProcessStep.One){ if(processStep === ProcessStep.One){
if(!businessNumber){ if(!businessNumber){
showAlert('사업자 번호는 필수 입력 항목 입니다.'); showAlert('사업자 번호는 필수 입력 항목 입니다.');
return;
} }
else if(!productName){ else if(!productName){
showAlert('상품명은 필수 입력 항목 입니다.'); showAlert('상품명은 필수 입력 항목 입니다.');
return;
} }
else if(!buyerName){ else if(!buyerName){
showAlert('구매자는 필수 입력 항목 입니다.'); showAlert('구매자는 필수 입력 항목 입니다.');
return;
} }
else if(!issueNumber){ else if(!issueNumber){
showAlert('발행번호는 필수 입력 항목 입니다.'); showAlert('발행번호는 필수 입력 항목 입니다.');
return;
} }
else if(email && !checkEmail(email)){ else if(email && !checkEmail(email)){
showAlert('이메일 형식이 맞지 않습니다.'); showAlert('이메일 형식이 맞지 않습니다.');
return;
} }
else if(!phoneNumber){ else if(!phoneNumber){
showAlert('전화번호는 필수 입력 항목 입니다.'); showAlert('전화번호는 필수 입력 항목 입니다.');
return;
} }
setProcessStep(ProcessStep.Two); setProcessStep(ProcessStep.Two);
} }
else if(processStep === ProcessStep.Two){ else if(processStep === ProcessStep.Two){
if(supplyAmount <= 0){
showAlert('공급가액은 1원 이상이어야 합니다.');
return;
}
callManualIssue(); callManualIssue();
// 완료시?
//alert('완료');
// navigate(PATHS.transaction.cashReceipt.list);
} }
}; };
return ( return (
<> <>
<main> <main>
@@ -136,14 +157,17 @@ export const CashReceitHandWrittenIssuancePage = () => {
{ (processStep === ProcessStep.Two) && { (processStep === ProcessStep.Two) &&
<CashReceiptHandWrittenIssuanceStep2 <CashReceiptHandWrittenIssuanceStep2
setProcessStep={ setProcessStep } setProcessStep={ setProcessStep }
issueAmount={ issueAmount }
supplyAmount={ supplyAmount } supplyAmount={ supplyAmount }
vatAmount={ vatAmount } vatAmount={ vatAmount }
taxFreeAmount={ taxFreeAmount } taxFreeAmount={ taxFreeAmount }
serviceCharge={ serviceCharge } serviceCharge={ serviceCharge }
setIssueAmount={ setIssueAmount }
setSupplyAmount={ setSupplyAmount } setSupplyAmount={ setSupplyAmount }
setVatAmount={ setVatAmount } setVatAmount={ setVatAmount }
setTaxFreeAmount={ setTaxFreeAmount } setTaxFreeAmount={ setTaxFreeAmount }
setServiceCharge={ setServiceCharge } setServiceCharge={ setServiceCharge }
onClickToVatCalculate={ onClickToVatCalculate }
></CashReceiptHandWrittenIssuanceStep2> ></CashReceiptHandWrittenIssuanceStep2>
} }
</div> </div>

View File

@@ -60,7 +60,7 @@ export const API_URL_USER = {
}, },
// mid 로 사업자 정보 조회 // mid 로 사업자 정보 조회
businessPropertyByMid: () => { businessProperty: () => {
return `${API_BASE_URL}/api/v1/amsw/business-property/by-mid`; return `${API_BASE_URL}/api/v1/${API_URL_KEY}/business-property`;
}, },
} }

View File

@@ -1,3 +1,5 @@
import { ChangeEvent } from "react";
export interface FilterSelectProps { export interface FilterSelectProps {
title: string; title: string;
selectValue: string; selectValue: string;
@@ -18,7 +20,6 @@ export const FilterSelect = ({
<option <option
key={ `key-filter-select-${i}` } key={ `key-filter-select-${i}` }
value={ selectOptions[i]?.value } value={ selectOptions[i]?.value }
selected={ (selectValue === selectOptions[i]?.value)? true: false }
>{ selectOptions[i]?.name }</option> >{ selectOptions[i]?.name }</option>
); );
} }
@@ -33,7 +34,7 @@ export const FilterSelect = ({
<select <select
className="flex-1" className="flex-1"
value={ selectValue } value={ selectValue }
onChange={ (e: any) => selectSetter(e.target.value)} onChange={ (e: ChangeEvent<HTMLSelectElement>) => selectSetter(e.target.value)}
> >
{ getSelectOptions() } { getSelectOptions() }
</select> </select>

View File

@@ -23,10 +23,10 @@ import { useStore } from '@/shared/model/store';
import { getLocalStorage, setLocalStorage } from '@/shared/lib'; import { getLocalStorage, setLocalStorage } from '@/shared/lib';
import { StorageKeys } from '@/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
import { HomeGroupsParams, HomeGroupsResponse } from '@/entities/home/model/types'; 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 { useShortcutUserMutation } from '@/entities/user/api/use-shortcut-user-mutation';
import { useShortcutDefaultMutation } from '@/entities/user/api/use-shortcut-detault-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 { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find-authmethod-mutation';
import { useCodesSelectMutation } from '@/entities/common/api/use-codes-select-mutation'; import { useCodesSelectMutation } from '@/entities/common/api/use-codes-select-mutation';
@@ -75,7 +75,7 @@ export const SubLayout = () => {
const { mutateAsync: codesSelect} = useCodesSelectMutation(); const { mutateAsync: codesSelect} = useCodesSelectMutation();
const { mutateAsync: shortcutUser } = useShortcutUserMutation(); const { mutateAsync: shortcutUser } = useShortcutUserMutation();
const { mutateAsync: shortcutDefault } = useShortcutDefaultMutation(); const { mutateAsync: shortcutDefault } = useShortcutDefaultMutation();
const { mutateAsync: businessPropertyByMid } = useBusinessPropertyByMidMutation(); const { mutateAsync: businessProperty } = useBusinessPropertyMutation();
const { mutateAsync: findAuthMethod } = useUserFindAuthMethodMutation(); const { mutateAsync: findAuthMethod } = useUserFindAuthMethodMutation();
const wrapperClassName = 'wrapper'; const wrapperClassName = 'wrapper';
@@ -106,13 +106,13 @@ export const SubLayout = () => {
}); });
}; };
const callBusinessPropertyByMid = () => { const callBusinessProperty = () => {
if(!!mid){ if(!!mid){
let params: BusinessPropertyByMidParams = { let params: BusinessPropertyParams = {
mid: mid mid: mid
}; };
businessPropertyByMid(params).then((rs: BusinessPropertyByMidResponse) => { businessProperty(params).then((rs: BusinessPropertyResponse) => {
console.log(rs); useStore.getState().UserStore.setBusinessInfo(rs);
}); });
} }
@@ -178,7 +178,6 @@ export const SubLayout = () => {
let emails = rs.emails.map((value: any, index: any) => { let emails = rs.emails.map((value: any, index: any) => {
return value.content; return value.content;
}); });
console.log('emails -->', emails)
useStore.getState().UserStore.setUserEmails(emails); useStore.getState().UserStore.setUserEmails(emails);
let options: Array<Record<string, string>> = emails.map((value: any, index: any) => { let options: Array<Record<string, string>> = emails.map((value: any, index: any) => {
return { return {
@@ -300,7 +299,7 @@ export const SubLayout = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
if(!!mid){ if(!!mid){
// callBusinessPropertyByMid(); callBusinessProperty();
callFindAuthMethod(); callFindAuthMethod();
} }
}, [mid]); }, [mid]);