-
Notifications
You must be signed in to change notification settings - Fork 0
[버그] 보스 분배금 로직이 잘못되었던 문제 수정 #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,33 +2,89 @@ export type DistributionResult = { | |
| id: string | ||
| name: string | ||
| ratio: number | ||
| amount: number | ||
| transferAmount: number // 입력 금액 (송금액) | ||
| finalReceivedAmount: number // 실수령액 | ||
| } | ||
|
|
||
| type Member = { id: string; name: string; ratio: number } | ||
| type Mode = 'MANUAL' | 'EQUAL' | ||
|
|
||
| const normalizeMembers = (members: Member[], mode: Mode): Member[] => { | ||
| if (mode === 'EQUAL') { | ||
| const equalRatio = 100 / members.length | ||
| return members.map((m) => ({ ...m, ratio: equalRatio })) | ||
| } | ||
| return members | ||
| } | ||
|
|
||
| const calculateFairBaseProfit = ( | ||
| totalProfit: number, | ||
| ownerRatio: number, | ||
| feeRate: number, | ||
| ): number => { | ||
| const r = feeRate / 100 | ||
| const wOwner = ownerRatio / 100 | ||
|
|
||
| const denominator = wOwner + (1 - wOwner) / (1 - r) | ||
|
|
||
| if (denominator <= 0) return 0 | ||
| return totalProfit / denominator | ||
| } | ||
|
|
||
| const computeMemberShare = ( | ||
| member: Member, | ||
| fairBaseProfit: number, | ||
| feeRate: number, | ||
| isOwner: boolean, | ||
| ): DistributionResult => { | ||
| const r = feeRate / 100 | ||
| const w = member.ratio / 100 | ||
|
|
||
| const targetFinal = Math.floor(fairBaseProfit * w) | ||
|
|
||
| if (isOwner) { | ||
| return { | ||
| ...member, | ||
| transferAmount: 0, | ||
| finalReceivedAmount: targetFinal, | ||
| } | ||
| } | ||
|
|
||
| const transfer = Math.floor(targetFinal / (1 - r)) | ||
| const finalReceived = Math.floor(transfer * (1 - r)) | ||
|
|
||
| return { | ||
| ...member, | ||
| transferAmount: transfer, | ||
| finalReceivedAmount: finalReceived, | ||
| } | ||
| } | ||
|
|
||
| export const distributeProfitByPercent = ( | ||
| totalProfit: number, | ||
| feeRate: number, | ||
| members: Member[], | ||
| mode: Mode, | ||
| ) => { | ||
| const memberCount = members.length | ||
| ): DistributionResult[] => { | ||
| const normalizedMembers = normalizeMembers(members, mode) | ||
|
|
||
| const fee = memberCount >= 2 ? Math.floor((totalProfit * feeRate) / 100) : 0 | ||
| const distributable = totalProfit - fee | ||
| const activeOwnerIndex = 0 | ||
| const ownerMember = normalizedMembers[activeOwnerIndex] | ||
|
|
||
| const results: DistributionResult[] = members.map((m) => ({ | ||
| ...m, | ||
| amount: | ||
| mode === 'MANUAL' | ||
| ? Math.floor((distributable * m.ratio) / 100) | ||
| : Math.floor(distributable / memberCount), | ||
| })) | ||
| const fairBaseProfit = calculateFairBaseProfit( | ||
| totalProfit, | ||
| ownerMember.ratio, | ||
| feeRate, | ||
| ) | ||
|
|
||
| const distributed = results.reduce((sum, r) => sum + r.amount, 0) | ||
| const remainder = distributable - distributed | ||
| const results = normalizedMembers.map((member, idx) => | ||
| computeMemberShare( | ||
| member, | ||
| fairBaseProfit, | ||
| feeRate, | ||
| idx === activeOwnerIndex, // isOwner check | ||
| ), | ||
| ) | ||
|
|
||
| return { results, remainder } | ||
| return results | ||
| } | ||
|
Comment on lines
63
to
90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 함수는 더 단순하고 견고하게 리팩토링할 수 있습니다. 현재
export const distributeProfitByPercent = (
totalProfit: number,
feeRate: number,
members: Member[],
): DistributionResult[] => {
if (members.length === 0) {
return [];
}
const activeOwnerIndex = 0;
const ownerMember = members[activeOwnerIndex];
const fairBaseProfit = calculateFairBaseProfit(
totalProfit,
ownerMember.ratio,
feeRate,
);
const results = members.map((member, idx) =>
computeMemberShare(
member,
fairBaseProfit,
feeRate,
idx === activeOwnerIndex, // isOwner check
),
);
return results;
}; |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
분배 주체인 파티장이 항상 배열의 첫 번째(
index 0) 멤버라고 가정하고 있습니다. 이는 유연하지 못한 설계이며, 향후 멤버 순서를 변경하거나 다른 파티장을 지정하는 기능이 추가될 경우 버그를 유발할 수 있습니다. 파티장의 ID를 함수에 전달하거나Member타입에isOwner같은 플래그를 추가하여 명시적으로 파티장을 식별하는 것이 더 견고한 접근 방식입니다.