Files
nice-app-web/src/entities/transaction/ui/all-transaction-part-cancel.tsx
Jay Sheen e067fc8d4f Add comprehensive i18n localization to transaction UI components
- Localize 23 transaction UI component files
- Add 150+ translation keys to ko.json and en.json
- Organized translations under transaction namespace:
  * transaction.bottomSheet - Bottom sheet modals
  * transaction.sections - Section titles
  * transaction.fields - Field labels (90+ keys)
  * transaction.cancel - Cancellation flows
  * transaction.handWrittenIssuance - Manual issuance forms
  * transaction.list - List actions

Updated files:
- Bottom sheets: escrow-mail-resend, cash-receipt-purpose-update
- Sections: billing-info, part-cancel-info, detail-info, issue-info,
  escrow-info, important-info, payment-info, transaction-info,
  settlement-info, merchant-info, amount-info, cancel-bank-group,
  cancel-password-group
- Lists: list-item, billing-list, cash-receipt-list
- Cancel flows: all-cancel, part-cancel, prevent-bond
- Issuance: hand-written-issuance-step1, hand-written-issuance-step2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 16:14:40 +09:00

329 lines
12 KiB
TypeScript

import { ChangeEvent, useEffect, useState } from 'react';
import { AllTransactionCancelInfoResponse } from '../model/types';
import { NumericFormat } from 'react-number-format';
import { AllTransactionCancelSectionPasswordGroup } from './section/all-transaction-cancel-section-password-group';
import { AllTransactionCancelSectionBankGroup } from './section/all-transaction-cancel-section-bank-group';
import { useTranslation } from 'react-i18next';
export interface AllTransactionPartCancelProps extends AllTransactionCancelInfoResponse {
serviceCode: string;
cancelPassword: string;
setCancelPassword: (cancelPassword: string) => void;
bankCode?: string;
setBankCode?: (BankCode: string) => void;
accountNo?: string;
setAccountNo?: (accountNo: string) => void;
accountHolder?: string;
setAccountHolder?: (accountHolder: string) => void;
cancelSupplyAmount: number;
setCancelSupplyAmount: (cancelSupplyAmount: number) => void;
cancelGoodsVat: number;
setCancelGoodsVat: (cancelGoodsVat: number) => void;
cancelTaxFreeAmount: number;
setCancelTaxFreeAmount: (cancelTaxFreeAmount: number) => void;
cancelServiceAmount: number;
setCancelServiceAmount: (cancelServiceAmount: number) => void;
requestSuccess: boolean;
totalCancelAmount: number;
setTotalCancelAmount: (totalCancelAmount: number) => void;
};
export const AllTransactionPartCancel = ({
serviceCode,
debtPreventionCancelDisplayInfo,
debtPreventionCancelRequestInfo,
goodsVat,
isCompoundTax,
isConditionalVatAutoCalcMerchant,
isNpg,
isVatAutoCalcMerchant,
isVatDisplayed,
partCancelCl,
remainAmount,
serviceAmount,
supplyAmount,
taxFreeAmount,
vatAutoCalcSummary,
cancelPassword,
setCancelPassword,
bankCode,
setBankCode,
accountNo,
setAccountNo,
accountHolder,
setAccountHolder,
cancelSupplyAmount,
setCancelSupplyAmount,
cancelGoodsVat,
setCancelGoodsVat,
cancelTaxFreeAmount,
setCancelTaxFreeAmount,
cancelServiceAmount,
setCancelServiceAmount,
requestSuccess,
totalCancelAmount,
setTotalCancelAmount
}: AllTransactionPartCancelProps) => {
const { t } = useTranslation();
const [cancelTotalCancelAmountReadonly, setCancelTotalCancelAmountReadonly] = useState<boolean>(true);
const [cancelSupplyAmountDisabled, setCancelSupplyAmountDisabled] = useState<boolean>(false);
const [cancelGoodsVatDisabled, setCancelGoodsVatDisabled] = useState<boolean>(false);
const [cancelTaxFreeAmountDisabled, setCancelTaxFreeAmountDisabled] = useState<boolean>(false);
const [cancelServiceAmountDisabled, setCancelServiceAmountDisabled] = useState<boolean>(false);
const init = () => {
if((isConditionalVatAutoCalcMerchant || isVatAutoCalcMerchant) && vatAutoCalcSummary === 0){
setCancelTotalCancelAmountReadonly(false);
}
if(remainAmount === 0){
setCancelSupplyAmountDisabled(true);
}
else{
if(isConditionalVatAutoCalcMerchant){
setCancelSupplyAmountDisabled(true);
}
else{
setCancelSupplyAmountDisabled(false);
}
}
if(goodsVat === 0){
setCancelGoodsVatDisabled(true);
}
else{
if(isConditionalVatAutoCalcMerchant){
setCancelGoodsVatDisabled(true);
}
else{
setCancelGoodsVatDisabled(false);
}
}
if(taxFreeAmount === 0){
setCancelTaxFreeAmountDisabled(true);
}
else{
if(isConditionalVatAutoCalcMerchant){
setCancelTaxFreeAmountDisabled(true);
}
else{
setCancelTaxFreeAmountDisabled(false);
}
}
if(serviceAmount === 0){
setCancelServiceAmountDisabled(true);
}
else{
if(isConditionalVatAutoCalcMerchant){
setCancelServiceAmountDisabled(true);
}
else{
setCancelServiceAmountDisabled(false);
}
}
};
const onChangeToTotalCancelAmount = (val: number) => {
setTotalCancelAmount(val);
if(isVatAutoCalcMerchant){
if(isVatDisplayed){
let cancelSupplyAmountVal = val;
let cancelGoodsVatVal = 0;
setCancelSupplyAmount(cancelSupplyAmountVal);
setCancelGoodsVat(cancelGoodsVatVal);
}
else{
let cancelSupplyAmountVal = Math.round(val / 1.1);
let cancelGoodsVatVal = val - cancelSupplyAmountVal;
setCancelSupplyAmount(cancelSupplyAmountVal);
setCancelGoodsVat(cancelGoodsVatVal);
}
}
else{
let cancelSupplyAmountVal = Math.round(val / 1.1);
let cancelGoodsVatVal = val - cancelSupplyAmountVal;
setCancelSupplyAmount(cancelSupplyAmountVal);
setCancelGoodsVat(cancelGoodsVatVal);
}
};
const onChangeCancelSupplyAmount = (val: number) => {
setCancelSupplyAmount(val);
if((isConditionalVatAutoCalcMerchant || isVatAutoCalcMerchant) && vatAutoCalcSummary === 0){
setTotalCancelAmount(val + cancelGoodsVat + cancelTaxFreeAmount + cancelServiceAmount);
}
};
const onChangeCancelGoodsVat = (val: number) => {
setCancelGoodsVat(val);
if((isConditionalVatAutoCalcMerchant || isVatAutoCalcMerchant) && vatAutoCalcSummary === 0){
setTotalCancelAmount(cancelSupplyAmount + val + cancelTaxFreeAmount + cancelServiceAmount);
}
};
const onChangeCancelTaxFreeAmount = (val: number) => {
setCancelTaxFreeAmount(val);
if((isConditionalVatAutoCalcMerchant || isVatAutoCalcMerchant) && vatAutoCalcSummary === 0){
setTotalCancelAmount(cancelSupplyAmount + cancelGoodsVat + val + cancelServiceAmount);
}
};
const onChangeCancelServiceAmount = (val: number) => {
setCancelServiceAmount(val);
if((isConditionalVatAutoCalcMerchant || isVatAutoCalcMerchant) && vatAutoCalcSummary === 0){
setTotalCancelAmount(cancelSupplyAmount + cancelGoodsVat + cancelTaxFreeAmount + val);
}
};
useEffect(() => {
init();
});
return (
<>
<div className="amount-info">
<ul className="amount-list">
<li className="amount-item">
<span className="label">·&nbsp;&nbsp;{t('transaction.fields.totalBalance')}</span>
<span className="value">
<NumericFormat
value={ remainAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</span>
</li>
<li className="amount-item">
<span className="label">·&nbsp;&nbsp;{t('transaction.fields.totalCancelAmount')}</span>
<span className="value">
<NumericFormat
value={ totalCancelAmount }
displayType="input"
allowNegative={ false }
max={ remainAmount }
readOnly={ cancelTotalCancelAmountReadonly }
onChange={(e: ChangeEvent<HTMLInputElement>) => onChangeToTotalCancelAmount(parseInt(e.target.value)) }
></NumericFormat>
</span>
</li>
</ul>
</div>
{ !!isCompoundTax &&
<div className="tb_both">
<table className="partial-cancel-table">
<colgroup>
<col width="30%" />
<col width="30%" />
<col width="40%" />
</colgroup>
<thead>
<tr>
<th className="header-empty"></th>
<th className="header-balance">{t('transaction.cancel.partCancel.balance')}</th>
<th className="header-cancel">{t('transaction.cancel.partCancel.cancelAmount')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className="row-label">{t('transaction.cancel.partCancel.taxableAmount')}</td>
<td className="row-balance">
<NumericFormat
value={ supplyAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</td>
<td className="row-cancel">
<NumericFormat
className="cancel-input"
value={ cancelSupplyAmount }
allowNegative={ false }
displayType="input"
disabled={ cancelSupplyAmountDisabled }
onChange={(e: ChangeEvent<HTMLInputElement>) => onChangeCancelSupplyAmount(parseInt(e.target.value)) }
></NumericFormat>
</td>
</tr>
<tr>
<td className="row-label">{t('transaction.cancel.partCancel.taxAmount')}</td>
<td className="row-balance">
<NumericFormat
value={ goodsVat }
thousandSeparator
displayType="text"
></NumericFormat>
</td>
<td className="row-cancel">
<NumericFormat
className="cancel-input"
value={ cancelGoodsVat }
allowNegative={ false }
displayType="input"
disabled={ cancelGoodsVatDisabled }
onChange={(e: ChangeEvent<HTMLInputElement>) => onChangeCancelGoodsVat(parseInt(e.target.value)) }
></NumericFormat>
</td>
</tr>
<tr>
<td className="row-label">{t('transaction.cancel.partCancel.taxFree')}</td>
<td className="row-balance">
<NumericFormat
value={ taxFreeAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</td>
<td className="row-cancel">
<NumericFormat
className="cancel-input"
value={ cancelTaxFreeAmount }
allowNegative={ false }
displayType="input"
disabled={ cancelTaxFreeAmountDisabled }
onChange={(e: ChangeEvent<HTMLInputElement>) => onChangeCancelTaxFreeAmount(parseInt(e.target.value)) }
></NumericFormat>
</td>
</tr>
<tr>
<td className="row-label">{t('transaction.cancel.partCancel.serviceFee')}</td>
<td className="row-balance">
<NumericFormat
value={ serviceAmount }
thousandSeparator
displayType="text"
></NumericFormat>
</td>
<td className="row-cancel">
<NumericFormat
className="cancel-input"
value={ cancelServiceAmount }
allowNegative={ false }
displayType="input"
disabled={ cancelServiceAmountDisabled }
onChange={(e: ChangeEvent<HTMLInputElement>) => onChangeCancelServiceAmount(parseInt(e.target.value)) }
></NumericFormat>
</td>
</tr>
</tbody>
</table>
</div>
}
<div className="form-section">
<AllTransactionCancelSectionPasswordGroup
cancelPassword={ cancelPassword }
setCancelPassword={ setCancelPassword }
requestSuccess={ requestSuccess }
></AllTransactionCancelSectionPasswordGroup>
{ serviceCode === '03' &&
<AllTransactionCancelSectionBankGroup
bankCode={ bankCode }
setBankCode={ setBankCode }
accountNo={ accountNo }
setAccountNo={ setAccountNo }
accountHolder={ accountHolder }
setAccountHolder={ setAccountHolder }
></AllTransactionCancelSectionBankGroup>
}
</div>
</>
);
};