MD-05 · 월 구매량 구간별 가격

월 구매량 구간별 가격 (전월 확정 · 업장 단위)

한 상품에 전월 확정 구매(수량·금액) 구간별 가격을 정액/정률로 설정하고, 주문 시 업장의 전월 실적으로 자동 매칭·적용해 복제코드를 제거한다.

🔴 결정 대기 가격 정교화 복제코드 제거 선행A 의존
➕ 기능 추가
무엇 — 한 상품에 전월 확정 구매(수량·금액) 구간별 가격을 정액/정률로 설정하고, 주문 시 업장의 전월 실적으로 자동 매칭·적용해 복제코드를 제거한다.📍 위치: 상품관리 › 가격 관리 › 가격수정

핵심 결정

매칭 기준
전월 확정 구매 · 업장(member) 단위 · 매월 1일 스냅샷 고정
조건
수량 OR 금액 (상품당 한 기준)
출력
정액(원) 또는 정률(%) — 정률 base = net_unit_price
폴백
미매칭 · 신규 업장 → 기본가
선행/목표
선행 「가격표 추가(선행A)」 필요 · 복제코드 제거
01

화면 — 먼저 보기

이 티켓이 실제로 어떤 화면이 되는지 먼저 봅니다

선행 「가격표 추가(선행A)」 완료 후 착수. 착수 전 확정 필요 — 경계 정의(이상/초과)·구매량 집계 범위(상품별/업장 총액)·'확정' 기준(정산 연동).
현행 화면 · 실제 캡처
현행 「가격수정」 모달 — 여기에 구간별 탭 추가
현행 「가격수정」 모달 — 여기에 구간별 탭 추가
변경안 · 제안 화면
상품관리 › 가격 관리 › 가격수정기능 추가
조건 기준 ▾🔍 히어로코드·상품명 검색구간가 설정복제코드 정리
히어로코드상품명기본가(net)구간가 🆕구간 수 🆕조건 기준 🆕최종수정
HRO-100234국산 대파 1kg3,200원설정됨3구간수량07/28 김MD
HRO-100871백설 식용유 18L42,000원미설정--07/20 이MD
HRO-101540냉장 삼겹살 1kg15,900원설정됨2구간금액07/29 박MD

▲ 가격수정 › 상품별 탭 — 구간가 목록 — 바뀌는 컬럼은 🆕 로 표시(예시 데이터)

1
구간가 설정 진입 — 가격수정 › 상품별 탭에서 상품(히어로코드) 선택 후 '구간가 설정'을 연다. 선행A 가격표 위에 구간 줄이 얹히는 구조.
2
기준·구간 입력 — 조건 기준(수량/금액)을 하나 선택하고 구간 줄을 추가한다. 각 줄에 하한/상한과 정액(원) 또는 정률(%)을 입력.
3
유효성 검증·미리보기 — 음수·역전·구간 겹침을 저장 전 차단하고, 각 구간의 적용가를 미리보기로 확인. 미매칭 폴백=기본가를 상시 표시.
4
월말 스냅샷 확정 — 매월 1일 00:00(KST) 배치가 전월 확정 구매(취소·반품 제외)를 업장×상품 단위로 집계해 restaurant_monthly_purchase에 고정.
5
주문 시 구간 매칭 — 주문 시점에 그 업장의 전월 스냅샷 실적으로 구간을 판정하고 정액/정률을 적용한다.
6
폴백 처리 — 어느 구간에도 안 걸리거나 신규 업장(전월 실적 없음)이면 기본가(net_unit_price)를 적용한다.
02

정책 / 정의

용어를 못 박고, 규칙을 명확히

용어 정의
용어정의
히어로코드 (hero_product_code)오더히어로 상품 식별 표준키. 구간가 정의·주문 매칭·기본가가 모두 이 키에 걸린다. 복제코드를 없애고 이 단일 키로 가격을 차등하는 것이 본 티켓의 목표.
넷 공급가 (net)매입 순공급가. seller_product.net_unit_price가 상품의 기본가 기준값이며, 정률 할인의 계산 base가 된다.
구간 (tier)전월 구매 실적을 수량 또는 금액 기준으로 나눈 경계 구간. 한 상품에 여러 줄로 설정되고 각 줄이 하나의 가격 규칙을 가진다.
전월 확정 구매직전 1개월간 해당 업장의 확정된(취소·반품 제외) 구매 실적. 매월 1일 스냅샷으로 고정되어 당월 주문의 구간 매칭에 사용된다.
정액 / 정률구간 출력 방식. 정액(FIXED)=적용 단가를 원 단위로 직접 지정, 정률(RATE)=기본가(net) 대비 % 할인.
기본가 (폴백)어느 구간에도 매칭되지 않거나 전월 실적이 없는 신규 업장에 적용하는 기준 가격. seller_product.net_unit_price.
복제코드지금까지 업장별 가격 차등을 위해 만들던 별도 상품 코드. 스캔 오류의 원인이며 본 기능으로 대체·제거 대상.
정책 (규칙)
#규칙비고
1매칭 기준 = 전월 확정 · 업장(member) 단위주문 시점의 직전 월 확정 구매 스냅샷으로 구간을 결정. 업장(식당=member_id) 단위로 판정.
2조건은 한 상품당 하나의 기준(수량 OR 금액)동일 상품의 구간 줄은 모두 같은 condition_type을 공유. 수량과 금액 혼합 사다리는 금지(가정).
3경계는 '이상(≥)' 기준으로 통일'100만 이상'=100만 포함. '초과(>)'가 필요한 예외만 boundary_op=GT로 개별 지정(가정 — 논의 확정 필요).
4미매칭 시 기본가 적용어느 구간에도 걸리지 않으면 net_unit_price 폴백. 0원·오류 노출 금지.
5신규 업장(전월 실적 없음) = 기본가restaurant_monthly_purchase 스냅샷이 없는 member는 무조건 기본가.
6유효성: 음수·역전·겹침 저장 차단lower_bound≥0, upper_bound>lower_bound, 구간 간 범위 중첩 금지를 저장 전 검증(CHECK+서버 검증).
7월 전환 = 매월 1일 00:00(KST) 스냅샷 고정전월 실적을 배치로 확정. 당월 내내 이 스냅샷을 참조하고 월 중 재계산하지 않음.
8확정 집계 범위 = 취소·반품 제외배송완료·정산확정 주문만 합산(가정 — '확정' 정의를 정산 기준과 맞출지 논의 필요).
9정률 계산 = net 대비 % · 원 단위 내림적용가 = net_unit_price × (1 − rate/100), 원 단위 절사(가정).
10선행 「가격표 추가(선행A)」 완료 후 착수구간 줄은 가격수정›상품별 탭의 가격표 위에 얹히는 구조. 선행A 미완 시 개발 착수 불가.
03

ERD

데이터 구조 · 관계 · DDL

product_price_tier 신규
idPK bigserial
hero_product_codeFK varchar(100)
tier_seqinteger
condition_typevarchar(10)
lower_boundbigint
upper_boundbigint
boundary_opvarchar(3)
output_typevarchar(10)
output_valuenumeric(12,3)
use_ynboolean
상품별 구간 가격 정의. 이 티켓의 핵심 신규 테이블 — 복제코드를 대체한다.
restaurant_monthly_purchase 신규
member_idPK varchar(20)
year_monthPK char(6)
hero_product_codePK varchar(100)
confirm_qtybigint
confirm_amountbigint
snapshot_attimestamp
업장×상품 전월 확정 구매 스냅샷. 매월 1일 배치로 채워 주문 시 구간 매칭에 사용.
seller_product WRITE
hero_product_codePK varchar(100)
net_unit_pricebigint
fix_price_ynboolean
tier_price_ynboolean
상품 마스터. 기본가(net_unit_price)를 READ, 목록 뱃지용 tier_price_yn 컬럼만 추가.
member_order_details_summary READ
hero_product_codevarchar(100)
member_idvarchar(20)
pricebigint
주문 상세 집계. 전월 확정 구매 스냅샷을 만드는 배치의 원천 데이터.
product_price_tier.hero_product_code = seller_product.hero_product_code (구간가 → 상품 기본가)
restaurant_monthly_purchase.hero_product_code = seller_product.hero_product_code
restaurant_monthly_purchase ← member_order_details_summary (member_id, 월별 배치 집계)
주문 매칭: restaurant_monthly_purchase(전월·member) × product_price_tier(hero) → 적용가 결정, 미매칭 시 seller_product.net_unit_price 폴백
-- ┌─────────────────────────────────────────────────────────────┐
-- │ MD-05 월 구매량 구간별 가격 — 신규 2 · 변경 1 (PostgreSQL)      │
-- └─────────────────────────────────────────────────────────────┘

-- [신규] 상품별 전월 구매량 구간 가격 정의
CREATE TABLE product_price_tier (
    id               BIGSERIAL   PRIMARY KEY,
    hero_product_code VARCHAR(100) NOT NULL,          -- 히어로코드(seller_product FK)
    tier_seq         INTEGER     NOT NULL,            -- 구간 순번(1..n, 하한 오름차순)
    condition_type   VARCHAR(10) NOT NULL,            -- 조건 기준: QTY(수량) / AMT(금액)
    lower_bound      BIGINT      NOT NULL DEFAULT 0,  -- 하한(수량=개, 금액=원)
    upper_bound      BIGINT,                          -- 상한(NULL = 무한대 ∞)
    boundary_op      VARCHAR(3)  NOT NULL DEFAULT 'GTE', -- 하한 경계: GTE(이상,≥) / GT(초과,>)
    output_type      VARCHAR(10) NOT NULL,            -- 출력: FIXED(정액,원) / RATE(정률,%)
    output_value     NUMERIC(12,3) NOT NULL,          -- 정액=적용 단가(원), 정률=할인율(예 3.000)
    use_yn           BOOLEAN     NOT NULL DEFAULT TRUE,
    created_by       VARCHAR(20),
    created_at       TIMESTAMP   NOT NULL DEFAULT now(),
    updated_by       VARCHAR(20),
    updated_at       TIMESTAMP,
    CONSTRAINT chk_bound_order CHECK (upper_bound IS NULL OR upper_bound > lower_bound), -- 역전 금지
    CONSTRAINT chk_bound_sign  CHECK (lower_bound >= 0)                                  -- 음수 금지
);
CREATE UNIQUE INDEX ux_ppt_hero_seq ON product_price_tier(hero_product_code, tier_seq) WHERE use_yn;
COMMENT ON TABLE product_price_tier IS 'MD-05 상품별 전월 구매량 구간 가격표(복제코드 대체)';

-- [신규] 업장(식당)×상품 월별 확정 구매 스냅샷 — 매월 1일 배치로 전월 고정
CREATE TABLE restaurant_monthly_purchase (
    member_id        VARCHAR(20)  NOT NULL,           -- 업장(식당) = member
    year_month       CHAR(6)      NOT NULL,           -- 대상 월 YYYYMM
    hero_product_code VARCHAR(100) NOT NULL,          -- 상품(상품별 집계)
    confirm_qty      BIGINT       NOT NULL DEFAULT 0, -- 확정 구매 수량(취소·반품 제외)
    confirm_amount   BIGINT       NOT NULL DEFAULT 0, -- 확정 구매 금액(원, VAT 제외 기준)
    snapshot_at      TIMESTAMP    NOT NULL DEFAULT now(), -- 스냅샷 확정 시각(월 전환 처리)
    PRIMARY KEY (member_id, year_month, hero_product_code)
);
COMMENT ON TABLE restaurant_monthly_purchase IS 'MD-05 전월 확정 구매 스냅샷(주문 시 구간 매칭 소스)';

-- [변경] 상품 마스터에 구간가 설정 여부 플래그 추가(목록 뱃지·필터용)
ALTER TABLE seller_product
    ADD COLUMN tier_price_yn BOOLEAN NOT NULL DEFAULT FALSE; -- 구간가 설정 여부
COMMENT ON COLUMN seller_product.tier_price_yn IS 'MD-05 구간별 가격 설정 상품 여부';
04

화면 상세 — 세부 표·규칙

목록 외 품목표·모달·규칙 등 세부 화면

구간별 가격 설정 모달
순번조건 기준하한상한경계출력 방식적용가 미리보기
1수량0개300개미만기본가-15,900원
2수량300개500개이상~미만정률3%15,423원
3수량500개이상정액14,900원14,900원
티켓 예시(전월 300개↑ → 14,900 or 3%)를 그대로 반영. 조건 기준은 표 전체 하나로 통일, 경계 기본값은 '이상(≥)'.
구간 유효성·예외 규칙표
상황처리근거
어느 구간에도 미매칭기본가(net_unit_price) 적용폴백 규칙
신규 업장(전월 실적 없음)기본가 적용전월 스냅샷 부재
하한>상한 · 음수 · 구간 겹침저장 차단(유효성 오류)역전·음수·중첩 금지
월 전환 시점(매월 1일 스냅샷 고정)과 '확정' 정의(취소·반품 제외)는 착수 전 확정 필요 항목.