모달 "적용하기" — 추가금 + 가격 정책 통합 저장
추가금 항목 체크 상태와 글로우비 특별가/기존가 비율을 저장하고 신청자별 가격을 일괄 재계산합니다.
모달 "적용하기" — 추가금 + 가격 정책 통합 저장
관리자 대시보드의 "추가금/수수료율" 모달에서 적용하기 클릭 시 호출되는 API입니다. 한 번의 트랜잭션으로 다음 세 가지를 함께 수행합니다:
Collab.currentPriceRate,Collab.quotePriceRate저장- 이 캠페인에 등록된
TB_CAMPAIGN_ADDON_FEE행들(가이드라인 출처)의is_included토글 - 기타 수수료(
MISC) 행을 요청값으로 전체 대체(replace) - 체크된 PERCENT 항목 합산(동적 글특가 비율)과 AMOUNT 항목 합산(
amountSum)을 반영해 신청자별currentPrice/quotePrice일괄 재계산
기존 PUT /ai/admin/dashboard/{campaignNo}/quote-price는 그대로 유지됩니다. 추가금 합산을 반영하지 않는 단순 비율 업데이트가 필요하면 그쪽을 사용하세요. 추가금 합산이 필요한 모달 "적용하기" 흐름은 이 API를 호출합니다.
HTTP 요청
PUT /ai/admin/dashboard/{campaignNo}/quote-price-with-addons
Authorization: Bearer {access_token}
Content-Type: application/jsonPath Parameters
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
campaignNo | Long | 예 | 캠페인 번호 |
Request Body
{
"currentPriceRate": 15,
"quotePriceRate": 50,
"includedAddonFeeTypes": ["BEFORE_AFTER", "OUTDOOR"],
"miscFees": [
{ "valueType": "PERCENT", "value": -15 },
{ "valueType": "AMOUNT", "value": 50000 }
]
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
currentPriceRate | Double | 예 | 글로우비 특별가 디폴트 비율 (%, 추가금 합산 전 베이스) |
quotePriceRate | Double | 예 | 기존가 비율 (%, 글로우비 특별가에 적용) |
includedAddonFeeTypes | Array<String> | 아니오 | 가격 계산에 포함될 AddonFeeType 코드 목록(가이드라인 출처). 비어있거나 null이면 합산 없이 베이스 비율만 적용 |
miscFees | Array | 아니오 | 기타 수수료 항목 목록. 요청 시 이 캠페인의 기존 기타 수수료를 전부 대체(replace). null/빈 배열이면 기존 기타 수수료를 모두 제거 |
miscFees[].valueType | String | 예 | PERCENT(%) / AMOUNT(원) |
miscFees[].value | Number | 예 | 값. 음수(할인) 허용 (예: -15, -50000). 라벨은 없으며 description은 "기타"로 저장 |
includedAddonFeeTypes에 명시되지 않은 캠페인 추가금 행은 is_included = false로 변경됩니다. 즉 프론트는 모달 합산 체크박스의 전체 ON 상태를 보냅니다.
체크된 항목이 캠페인에 등록되지 않은 경우(가이드라인에서 추가하지 않은 항목)는 무시됩니다 — 행이 없으면 만들지 않습니다.
miscFees는 includedAddonFeeTypes 토글과 무관합니다(항상 가격에 포함). 또한 가이드라인 sync 대상이 아니므로 sync가 기타 수수료를 생성/수정/삭제하지 않습니다.
계산 식
dynamicCurrentRate = currentPriceRate + Σ(included && PERCENT 항목 value) // 기타 수수료 PERCENT 포함
amountSum = Σ(included && AMOUNT 항목 value) // 가이드라인 AMOUNT + 기타 수수료 AMOUNT, 음수 가능
각 신청자에 대해:
currentPrice = acceptedPrice × (1 + dynamicCurrentRate / 100) + amountSum
quotePrice = currentPrice × (1 + quotePriceRate / 100) + amountSumacceptedPrice는 해당 신청자의 가장 최근 수락된 PriceNegotiation.proposedPrice입니다. 수락된 협상이 없으면 그 신청자는 스킵됩니다.
예)
acceptedPrice150,000 /currentPriceRate15% / included PERCENT 합 10% /amountSum50,000 /quotePriceRate50% →currentPrice= 150,000 × 1.25 + 50,000 = 237,500,quotePrice= 237,500 × 1.5 + 50,000 = 406,250 금액(amountSum)은 글특가·기존가 양쪽에 각각 더해집니다.
응답
성공 응답 (200 OK)
{
"status": 200,
"code": null,
"message": "추가금 + 가격 정책 저장 성공",
"data": {
"updatedCount": 12,
"updatedIds": [101, 102, 103],
"failedUpdates": [],
"message": "12건의 가격이 업데이트되었습니다. (동적 글특가 비율: 25.00%)"
}
}응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
updatedCount | Integer | 가격이 재계산된 신청 수 |
updatedIds | Array<Long> | 재계산된 신청 ID 목록 |
failedUpdates[] | Array | 재계산 실패 항목 |
failedUpdates[].applicationId | Long | 실패한 신청 ID |
failedUpdates[].error | String | 실패 사유 |
message | String | 결과 메시지 (동적 비율 포함) |
에러 응답
| 상태 코드 | 설명 |
|---|---|
400 | 존재하지 않는 캠페인입니다: {campaignNo} 또는 필수 필드 누락 |
401 | 인증 실패 |
403 | ADMIN 권한 필요 |