Skip to content

Commit

Permalink
Merge pull request #262 from Nexters/feature/super-admin-show-settlement
Browse files Browse the repository at this point in the history
슈퍼 어드민에서 정산 내역서 전송 페이지 수정 사항 반영
  • Loading branch information
Puterism authored Jan 14, 2025
2 parents fa25a75 + 526fc84 commit 1de1802
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,15 @@ const SettlementStatementPreviewContainer = styled.div`
height: 600px;
`;

const PreviewMessage = styled.div`
background-color: #FACBCF;
border-radius: 8px;
padding: 16px 20px;
${({ theme }) => theme.typo.b3};
color: ${({ theme }) => theme.palette.grey.g90};
margin-bottom: 32px;
`;

const TextFieldRow = styled.div`
display: flex;
gap: 8px;
Expand Down Expand Up @@ -267,6 +276,7 @@ export default {
SettlementStatementForm,
SettlementStatementFooter,
SettlementStatementPreviewContainer,
PreviewMessage,
TextFieldRow,
TextField,
Select,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ const SettlementStatementFormDialog = ({
)}
{step === 2 && (
<Styled.SettlementStatementPreviewContainer>
<Styled.PreviewMessage>
발송 전 내역서를 다시 한 번 확인해 주세요!
</Styled.PreviewMessage>
<SettlementStatementPreview
data={{
showName: watch('showName'),
Expand Down
1 change: 1 addition & 0 deletions apps/super-admin/src/constants/settlement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const BOOLTI_FEE_RATE = 0.01
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const ProgressItem = styled.li<ProgressItemProps>`
bottom: -36px;
left: 12px;
background-color: ${({ theme, active }) =>
active ? theme.palette.primary.o1 : theme.palette.grey.g20};
active ? theme.palette.primary.o1 : theme.palette.grey.g20};
width: 1px;
height: 30px;
}
Expand Down Expand Up @@ -105,6 +105,20 @@ const ProgressItemDescription = styled.span`
color: ${({ theme }) => theme.palette.grey.g70};
`;

const ProgressItemButton = styled.button`
font-size: 15px;
font-weight: 700;
line-height: 23px;
text-decoration: underline;
color: ${({ theme }) => theme.palette.grey.g70};
cursor: pointer;
&:hover, &:active {
text-decoration: underline;
color: ${({ theme }) => theme.palette.grey.g70};
}
`;

const UserInfo = styled.div`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -217,6 +231,7 @@ export default {
ProgressItemNumber,
ProgressItemTitle,
ProgressItemDescription,
ProgressItemButton,
UserInfo,
UserInfoItem,
UserInfoTitle,
Expand Down
231 changes: 127 additions & 104 deletions apps/super-admin/src/pages/SettlementPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
useAdminSettlementInfo,
useAdminShowDetail,
useAdminTicketSalesInfo,
useSuperAdminShowSettlementStatement,
} from '@boolti/api';
import { PlusIcon } from '@boolti/icon';
import { Button, useConfirm, useDialog, useToast } from '@boolti/ui';
Expand All @@ -15,6 +16,7 @@ import SettlementStatementFormDialog from '~/components/SettlementStatement/Sett

import Styled from './SettlementPage.styles';
import PageLayout from '~/components/PageLayout/PageLayout';
import { BOOLTI_FEE_RATE } from '~/constants/settlement';

const SettlementPage = () => {
const params = useParams<{ showId: string }>();
Expand All @@ -28,10 +30,82 @@ const SettlementPage = () => {
useAdminSettlementEvent(Number(params!.showId));
const { data: adminSettlementInfo } = useAdminSettlementInfo(Number(params!.showId));
const { data: adminTicketSalesInfo } = useAdminTicketSalesInfo(Number(params!.showId));
const { data: superAdminShowSettlementStatementBlob } = useSuperAdminShowSettlementStatement(Number(params!.showId))

const createSettlementStatementMutation = useAdminCreateSettlementStatement();
const settlementDoneMutation = useAdminSettlementDone();

const dialogContent = (
<SettlementStatementFormDialog
ticketSalesInfo={adminTicketSalesInfo ?? []}
initialValues={{
showName: adminShowDetail?.name ?? '',
hostName: adminShowDetail?.host.name ?? '',
accountHolder: adminSettlementInfo?.bankAccount?.bankAccountHolder ?? '',
bankCode: adminSettlementInfo?.bankAccount?.bankCode ?? '',
accountNumber: adminSettlementInfo?.bankAccount?.bankAccountNumber ?? '',
}}
onSubmit={async (data) => {
try {
if (createSettlementStatementMutation.isLoading) return;

const body = {
showName: data.showName,
hostName: data.hostName,
settlementBankInfo: {
bankCode: data.bankCode,
bankAccountNumber: data.accountNumber,
bankAccountHolder: data.accountHolder,
},
businessLicenseNumber: data.businessNumber,
salesAmount: parseInt(data.salesAmount.replace(/,/g, '')),
salesItems: data.salesItems.reduce<
{
salesTicketTypeId: number;
amount: number;
}[]
>((acc, item) => {
acc.push({
salesTicketTypeId: parseInt(item.salesTicketId.replace(/,/g, '')),
amount: parseInt(item.amount.replace(/,/g, '')),
});

return acc;
}, []),
fee: parseInt(data.fee.replace(/,/g, '')),
feeItems: [
{
feeType: 'BROKERAGE_FEE' as 'BROKERAGE_FEE' | 'PAYMENT_AGENCY_FEE',
amount: parseInt(data.brokerageFee.replace(/,/g, '')),
},
{
feeType: 'PAYMENT_AGENCY_FEE' as
| 'BROKERAGE_FEE'
| 'PAYMENT_AGENCY_FEE',
amount: parseInt(data.paymentAgencyFee.replace(/,/g, '')),
},
],
vat: parseInt(data.vat.replace(/,/g, '')),
roundAmount: parseInt(data.adjustmentAmount.replace(/,/g, '')),
roundReason: data.adjustmentReason,
};

await createSettlementStatementMutation.mutateAsync({
showId: Number(params.showId),
body,
});
await refetchAdminSettlementEvent();

toast.success('정산 내역서를 발송했어요.');
dialog.close();
} catch (error) {
console.error(error);
toast.error('정산 내역서를 생성하지 못했어요. 개발자에게 문의해주세요.');
}
}}
/>
)

return (
<PageLayout
breadscrumb="정산 관리 / 정산 내역서"
Expand All @@ -58,6 +132,22 @@ const SettlementPage = () => {
{format(adminSettlementEvent.SEND, 'yyyy-MM-dd HH:mm')}
</Styled.ProgressItemDescription>
)}
{adminSettlementEvent?.SEND && superAdminShowSettlementStatementBlob && (
<Styled.ProgressItemButton onClick={() => {
if (!adminShowDetail) return;

const downloadUrl = URL.createObjectURL(superAdminShowSettlementStatementBlob);

const anchorElement = document.createElement('a');
anchorElement.href = downloadUrl;
anchorElement.download = `불티 정산 내역서 - ${adminShowDetail.name}.pdf`;
anchorElement.click();

URL.revokeObjectURL(downloadUrl);
}}>
전송한 내역서 보기
</Styled.ProgressItemButton>
)}
</Styled.ProgressItem>
<Styled.ProgressItem active={!!adminSettlementEvent?.REQUEST}>
<Styled.ProgressItemNumber active={!!adminSettlementEvent?.REQUEST}>
Expand All @@ -78,11 +168,11 @@ const SettlementPage = () => {
</Styled.ProgressItemNumber>
<Styled.ProgressItemTitle active={!!adminSettlementEvent?.DONE}>
{adminSettlementEvent?.SEND &&
adminSettlementEvent?.REQUEST &&
!adminSettlementEvent?.DONE ? (
adminSettlementEvent?.REQUEST &&
!adminSettlementEvent?.DONE ? (
<Button
colorTheme="netural"
size="small"
size="x-small"
onClick={async () => {
const confirm = await settlementCompleteConfirm(
<Styled.ConfirmContent>
Expand Down Expand Up @@ -146,36 +236,6 @@ const SettlementPage = () => {
)}
</Styled.UserInfoContent>
</Styled.UserInfoItem>
<Styled.UserInfoItem>
<Styled.UserInfoTitle>정산 계좌</Styled.UserInfoTitle>
<Styled.UserInfoContent>
{adminSettlementInfo?.bankAccount ? (
<>
<Styled.UserInfoText>
{adminSettlementInfo.bankAccount.bankName}{' '}
{adminSettlementInfo.bankAccount.bankAccountNumber}{' '}
{adminSettlementInfo.bankAccount.bankAccountHolder}
</Styled.UserInfoText>
<Button
colorTheme="netural"
size="x-small"
onClick={async () => {
if (!adminSettlementInfo.bankAccount) return;

await navigator.clipboard.writeText(
`${adminSettlementInfo.bankAccount.bankName} ${adminSettlementInfo.bankAccount.bankAccountNumber} ${adminSettlementInfo.bankAccount.bankAccountHolder}`,
);
toast.success('계좌 정보가 복사되었습니다.');
}}
>
복사하기
</Button>
</>
) : (
<Styled.UserInfoText>-</Styled.UserInfoText>
)}
</Styled.UserInfoContent>
</Styled.UserInfoItem>
<Styled.UserInfoItem>
<Styled.UserInfoTitle>통장 사본</Styled.UserInfoTitle>
<Styled.UserInfoContent>
Expand Down Expand Up @@ -248,6 +308,18 @@ const SettlementPage = () => {
</Styled.TableItem>
<Styled.TableItem></Styled.TableItem>
</Styled.TableRow>
<Styled.TableRow>
<Styled.TableItem>불티 수수료</Styled.TableItem>
<Styled.TableItem></Styled.TableItem>
<Styled.TableItem></Styled.TableItem>
<Styled.TableItem></Styled.TableItem>
<Styled.TableItem align="right">
{((adminTicketSalesInfo ?? []).reduce<number>((acc, cur) => acc + cur.amount, 0) * BOOLTI_FEE_RATE)
.toLocaleString()}
</Styled.TableItem>
<Styled.TableItem></Styled.TableItem>
</Styled.TableRow>
</Styled.TableBody>
</Styled.Table>
</Styled.Section>
Expand All @@ -257,81 +329,12 @@ const SettlementPage = () => {
<Styled.Section>
<Button
type="button"
size="medium"
size="bold"
colorTheme="netural"
onClick={() => {
dialog.open({
title: '정산 내역서 생성하기',
content: (
<SettlementStatementFormDialog
ticketSalesInfo={adminTicketSalesInfo ?? []}
initialValues={{
showName: adminShowDetail?.name ?? '',
hostName: adminShowDetail?.host.name ?? '',
accountHolder: adminSettlementInfo?.bankAccount?.bankAccountHolder ?? '',
bankCode: adminSettlementInfo?.bankAccount?.bankCode ?? '',
accountNumber: adminSettlementInfo?.bankAccount?.bankAccountNumber ?? '',
}}
onSubmit={async (data) => {
try {
if (createSettlementStatementMutation.isLoading) return;

const body = {
showName: data.showName,
hostName: data.hostName,
settlementBankInfo: {
bankCode: data.bankCode,
bankAccountNumber: data.accountNumber,
bankAccountHolder: data.accountHolder,
},
businessLicenseNumber: data.businessNumber,
salesAmount: parseInt(data.salesAmount.replace(/,/g, '')),
salesItems: data.salesItems.reduce<
{
salesTicketTypeId: number;
amount: number;
}[]
>((acc, item) => {
acc.push({
salesTicketTypeId: parseInt(item.salesTicketId.replace(/,/g, '')),
amount: parseInt(item.amount.replace(/,/g, '')),
});

return acc;
}, []),
fee: parseInt(data.fee.replace(/,/g, '')),
feeItems: [
{
feeType: 'BROKERAGE_FEE' as 'BROKERAGE_FEE' | 'PAYMENT_AGENCY_FEE',
amount: parseInt(data.brokerageFee.replace(/,/g, '')),
},
{
feeType: 'PAYMENT_AGENCY_FEE' as
| 'BROKERAGE_FEE'
| 'PAYMENT_AGENCY_FEE',
amount: parseInt(data.paymentAgencyFee.replace(/,/g, '')),
},
],
vat: parseInt(data.vat.replace(/,/g, '')),
roundAmount: parseInt(data.adjustmentAmount.replace(/,/g, '')),
roundReason: data.adjustmentReason,
};

await createSettlementStatementMutation.mutateAsync({
showId: Number(params.showId),
body,
});
await refetchAdminSettlementEvent();

toast.success('정산 내역서를 발송했어요.');
dialog.close();
} catch (error) {
console.error(error);
toast.error('정산 내역서를 생성하지 못했어요. 개발자에게 문의해주세요.');
}
}}
/>
),
content: dialogContent,
isAuto: true,
});
}}
Expand All @@ -341,6 +344,26 @@ const SettlementPage = () => {
</Button>
</Styled.Section>
)}
{adminSettlementEvent?.SEND &&
!adminSettlementEvent?.REQUEST &&
!adminSettlementEvent?.DONE && (
<Styled.Section>
<Button
type="button"
size="bold"
colorTheme="line"
onClick={() => {
dialog.open({
title: '정산 내역서 생성하기',
content: dialogContent,
isAuto: true,
});
}}>
<PlusIcon />
내역서 재생성하기
</Button>
</Styled.Section>
)}
</PageLayout>
);
};
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import useCastTeamList from './useCastTeamList';
import useAdminTicketList from './useAdminTicketList';
import useAdminSalesTicketList from './useAdminSalesTicketList';
import useAdminReservationSummaryV2 from './useAdminReservationSummaryV2';
import useSuperAdminShowSettlementStatement from './useSuperAdminShowSettlementStatement';

export {
useCastTeamList,
Expand Down Expand Up @@ -84,4 +85,5 @@ export {
useSuperAdminSalesTicketList,
useSuperAdminInvitationTicketList,
useSuperAdminInvitationCodeList,
useSuperAdminShowSettlementStatement,
};
Loading

0 comments on commit 1de1802

Please sign in to comment.