영업판매실적 조회 절차
데이터 정의는 Sales Data 테이블 명세 및 KPI 정의가 정본
이 문서는 “어떻게 조회·계산하는가”(경로·규칙)를 다룬다. 각 컬럼이 무엇을 의미하는가(데이터 사전)와 KPI 정의(매출액·수주건수 등)는 Sales Data 테이블 명세 및 KPI 정의가 정본이다 — 매출/영업 계산 전 그 문서를 반드시 함께 본다.
Key Insight
판매실적 숫자는 절대 Wiki 프로즈로 캐시하지 않는다. 매번 Google Sheets 원본을 커넥터로 직접(live) 조회해서 계산하고, 대신 “어떻게 계산하는가”(필터 규칙·용어 의미·주의사항)만 이 가이드에 영구 지식으로 쌓는다. 이유:
Sales Data시트는 16,811행(2026-08-04 기준)이 실시간으로 누적되는 원장이라, 위키에 요약을 컴파일해두면 만든 순간부터 낡은 정보가 된다.
Bias Check
이 가이드의 필터 규칙·용어 정의는 05_SalesReport 볼트의 Data Catalog(Power BI tmdl 원본 분석)와 2026-08-04 실측 데이터 대조로 검증했지만, 리베이트 스킴이 회사별로 어떻게 배정되는지·
Damaged/Clearance/Salesman필드가 왜 대부분 결측인지는 확인되지 않았다(아래 Open Questions 참고) —confidence: high는 “계산 절차”에 대한 것이고 “비즈니스 해석”까지 자동으로 high인 것은 아니다.
Overview
언제 이 가이드를 쓰는가: 매출·주문·딜러·제품·리베이트 실적에 대한 어떤 질문이든(예: “이번 달 매출 어때?”, “HWD 요즘 왜 줄었어?”, “35% 스킴 딜러 리스트”) 이 절차를 먼저 따른다.
핵심 원칙: 00_TAB_프로젝트_선언문 원칙 #3(“Vault에 없는 숫자나 사실을 지어내지 말 것”)을 지키는 유일한 방법은 매번 원본을 직접 보는 것이다. 이 시트는 사람이 계속 입력을 추가하는 살아있는 원장이라, 어제 컴파일한 요약이 오늘은 틀린 숫자일 수 있다.
데이터 원천
| 항목 | 값 |
|---|---|
| 파일 | Google Sheets “Turbo Air” |
| 파일 ID | 1VOpjK9aDUuVmwkAouzGu-X_mZvGRlyhKbTDP1D6FU3Q |
| 시트(탭) | Sales Data |
| URL | https://docs.google.com/spreadsheets/d/1VOpjK9aDUuVmwkAouzGu-X_mZvGRlyhKbTDP1D6FU3Q/edit?gid=1998781497#gid=1998781497 |
| 접근 방법 | Google Drive 커넥터 (search_files / get_file_metadata / read_file_content / download_file_content) — 파일 ID를 알고 있으므로 검색 없이 바로 조회 가능 |
| 접근 권한 | David 계정에 공유되어 있어 공개(public) 전환 없이도 커넥터로 직접 읽을 수 있음(확인됨, 2026-08-04) |
실전 주의사항 (2026-08-04 실측으로 확인됨)
read_file_content를 파일 ID로 바로 호출하면 여러 탭 중 하나(활성/첫 탭)만 반환된다 — “Turbo Air” 파일은TA_Order,Sales Data,Stock,Dealer등 30개 이상의 탭이 있고,Sales Data가 목표 탭이면 이 방법으로는 못 얻을 수 있다.- 권장 방법:
download_file_content(fileId, exportMimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")로 전체 워크북을 xlsx로 받은 뒤, 로컬에서openpyxl/pandas로Sales Data시트만 열어 파싱한다. 결과가 커서(5MB+ base64) 토큰 한도를 넘기면 도구가 자동으로 로컬 파일에 저장해주므로, 그 파일을 다시 파이썬으로 읽으면 된다. - 시트 헤더(1행)는
No.,State,Status,Order date,Order No,P/O No,Company,Salesman,Required\nby,Model,SN,Damaged,Clearance,Inv Date,Inv No,Delivery,TA$ Exc,RRP,DC rate,Sales,Freight Cost,Freight,Extra,TA$,Sales Note,KK boucher,Tax등이다.
접근 경로 2 — turboairbrain.uk/ask 의 자동 라이브 조회 (서비스 계정, 2026-08-05 추가)
위 “Google Drive 커넥터” 경로는 Claude Desktop/Code처럼 MCP 도구가 붙어있는 클라이언트 세션에서만 쓸 수 있다. turboairbrain.uk/ask는 Cloudflare Worker가 Anthropic Messages API를 순수 HTTPS로 직접 호출하는 별도 구조라 그 커넥터가 없다 — 대신 Google 서비스 계정(tab-wiki-sheets-reader@turboair-brain.iam.gserviceaccount.com, Viewer 권한으로 이 시트에 공유됨)으로 Google Sheets API를 직접 호출한다.
| 항목 | Google Drive 커넥터 (기존) | 서비스 계정 (신규) |
|---|---|---|
| 사용 위치 | Claude Desktop/Code 세션 | turboairbrain.uk/ask (Cloudflare Worker) |
| 인증 방식 | 클라이언트에 내장된 MCP 커넥터 | JWT-bearer OAuth2 (Worker가 직접 구현, Web Crypto API) |
| 조회 방식 | xlsx 전체 export 후 로컬 파싱 | Sheets API values.get으로 Sales Data 탭만 직접 fetch |
| 트리거 | 담당자가 세션에서 수동 요청 | 질문에 매출/판매/영업/딜러 등 키워드가 있으면 자동 |
| 집계 | 사람(에이전트)이 그때그때 계산 | Worker가 이 가이드의 “계산 규칙”과 동일한 로직으로 서버사이드 사전집계 후 Claude에 전달 |
두 경로 모두 같은 계산 규칙(아래 “계산 규칙” 섹션)을 따라야 한다 — 규칙이 바뀌면 이 문서와 functions/api/_google-sheets.js(Worker 쪽 구현) 양쪽을 함께 갱신할 것. 구현 상세는 Cloudflare Pages Function + Claude API로 Wiki 기반 Q&A 봇 만들기 §6 참고.
신규/이탈 딜러 세그멘테이션 질문 처리 (2026-08-19 추가)
Update (2026-08-19) — Nathan 매니저의 "근거 없음" 오답에서 발견된 구조적 공백을 메움
Nathan 매니저가 “NSW/VIC 2026년도 신규 업체 리스트(전년도 인보이스 ≤1건 AND 올해 ≥2건)“를 turboairbrain.uk/ask에 물었을 때, 봇이 근거 없음으로 답했다. 원인은 계산 실패가 아니라 애초에 필요한 데이터가 프롬프트에 없었던 것 — Worker가 서버사이드로 미리 집계해 Claude에 넘기는 표(§ 아래 [표1]~[표6])는 딜러별 매출 Top 5(연도별)만 포함하고, 나머지 수백 개의 소규모/신규 딜러는 애초에 등장하지 않는다. Claude Code 세션에서
05_SalesReport/sales-data.js(§ 아래 참고)를 직접 파싱해 수동으로 답했지만(해당 답변: 2026-08-19-Q-NSW-VIC-2026년도-신규-업체-리스트를-받고-싶어.-당사의-신), 같은 유형의 질문이 반복될 것이므로 /ask 봇 자체를 고쳐 자동으로 답할 수 있게 했다 — 그 결과가 이 §다.
무엇이 바뀌었나 — functions/api/_google-sheets.js
needsFullDealerBreakdown(question)(신규 함수): 질문에 “신규 업체”/“신규 딜러”/“이탈”/“휴면”/“전체 딜러”/“리스트업”/“new customer”/“churn” 등 세그멘테이션 키워드가 있으면true.isSalesQuestion()(기존 매출 키워드 감지)과는 독립적으로 판정한다 — “신규 업체 리스트 줘”처럼 “매출/판매/딜러/sales” 같은 기존 키워드가 하나도 없는 질문도 감지해야 하기 때문.ask.js의 라이브 조회 트리거를isSalesQuestion(question)단독 AND에서isSalesQuestion(question) || needsFullDealerBreakdown(question)로 변경 — 이 OR 게이트가 없으면 세그멘테이션 키워드만 있고 매출 키워드가 없는 질문은 라이브 조회 자체가 꺼져서 프롬프트에 판매 데이터가 통째로 안 들어간다(이번 사고의 1차 원인).aggregateSalesData()에dealerYearInv추가: 연도별{ company -> { invSet:Set(고유 Inv No), states:Set(State) } }. 매출 인식 화이트리스트(Status∈Credit/Invoiced/Confirmed) 통과 +Inv No발행 행만 대상이며, 같은 Inv No는 1건으로 dedup한다(라인 아이템 수가 아니라 인보이스 수).formatSalesDataForPrompt()에[표7]추가 —needsFullDealerBreakdown이true일 때만 렌더링(모든 질문에 매번 넣으면 프롬프트가 커지므로 조건부). Top-N 제한 없이, 가장 최근 2개 연도(예: 2025/2026)에 인보이스가 하나라도 있었던 전체 딜러를 딜러명·State·전년도 건수·올해 건수로 나열 — Claude가 이 표에서 “전년도 ≤1건 AND 올해 ≥2건” 같은 임의의 문턱값 조건을 직접 필터링해 답할 수 있다.
이 방식의 의도적인 한계
- 최근 2개 연도만: 딜러가 326개(NSW/VIC만도)라 전체 연도(2021~)를 다 넣으면 프롬프트가 지나치게 커진다. “3년 전 대비 이탈” 같은 질문은 여전히 Claude Code 세션에서
05_SalesReport/sales-data.js직접 파싱이 필요하다 — 이럴 땐 답변에 “최근 2개년만 자동 조회되며, 그 이전 연도는 별도 재조회가 필요하다”고 명시할 것. - 인보이스 건수 정의는 시스템 전체와 동일하게 화이트리스트 기준을 쓴다(§ 위 “계산 규칙” #1). 담당자가 “Inv No 유무만으로 세라”처럼 화이트리스트보다 느슨한 기준을 명시적으로 요청하면(2026-08-19 Nathan 요청이 실제로 이랬다), 자동 [표7]이 아니라 Claude Code 세션에서 그 지시대로 별도 재계산해야 한다 — 두 정의가 대부분 결과는 같지만 항상 같지는 않다(2026-08-19-Q-NSW-VIC-2026년도-신규-업체-리스트를-받고-싶어.-당사의-신의 Cucina Pty Ltd 사례처럼 Restocked 상태 인보이스 1건 차이가 날 수 있음).
- State는 딜러 단위로 합산 표시(예:
NSW/VIC= 그 딜러가 두 지역 모두에서 인보이스 발생) — 완전히 지역별로 분리된 두 개의 리스트가 필요하면 이 표만으로는 부족하고 추가 재계산이 필요하다.
재사용 체크리스트 — 앞으로 비슷한 “구조적 공백”을 만들지 않으려면
새로운 유형의 “전체 목록 기반 조건 필터링” 질문(예: “35% 스킴 대상 딜러 중 올해 매출 하락한 곳”, “TA QLD 제외하고 리베이트 10% 구간 넘긴 딜러”)이 또 근거 없음으로 막히면:
- 그 질문이 필요로 하는 게 **“상위 N개”가 아니라 “전체 목록 중 조건을 만족하는 항목”**인지 먼저 판단한다 — Top-5/Top-30류 표로는 원천적으로 답할 수 없는 질문 유형이다.
_google-sheets.js에 새 세그멘테이션 키워드를DEALER_SEGMENTATION_KEYWORDS에 추가하거나, 필요하면 이 §의dealerYearInv패턴처럼 **전체 목록을 조건부로만 프롬프트에 추가하는 새[표N]**을 만든다(항상 넣지 않는 것이 핵심 — 프롬프트 크기 관리).ask.js의 트리거 조건에 새 감지 함수를 OR로 반드시 연결한다(§ 위 2번 — 빠뜨리면 이번과 같은 사고가 재발한다).- 이 §에 변경 이력을 추가하고,
node --check+rebuild-site.ps1배포 후 실제 질문으로 검증한다.
계산 규칙 (Power BI Sales/Oders 팩트 테이블과 동일)
이 규칙은 05_SalesReport 볼트의 Power BI 시맨틱 모델(Sales/Oders 테이블의 Power Query)과 완전히 동일하게 재현해야 한다. 상세 스키마는 크로스볼트 참조 — 05_SalesReport (위성 볼트) 참고.
Update (2026-08-12) — 매출 인식 규칙 정정 (블랙리스트 → 화이트리스트)
이전 버전의 규칙 1은 “
Status가 빈 값/Cancelled/Hold인 행만 제외”하는 블랙리스트였다. 이 방식은 Quote·Pending·Ordered 등 아직 매출로 확정되지 않은 상태까지 매출에 포함시켜 매출액을 과대계상했다(turboairbrain.uk/ask의 Nathan 매니저 질문 답변에서 오류 발견). 담당자(David/Nathan) 확인 결과, 정확한 매출 인식 기준은Inv No발행 +Status ∈ {Credit, Invoiced, Confirmed}화이트리스트,Inv Date기준이다. 아래 #1·#3이 정본이며,functions/api/_google-sheets.js의aggregateSalesData도 이 규칙으로 함께 수정됨.
Disputed Claim (미해결, 2026-08-18 발견) —
TAB_Dashboard.html은 여전히 블랙리스트를 쓴다
05_SalesReport/TAB_Dashboard.html(자체 제작 웹 대시보드)는 위 정정 이후에도 블랙리스트 규칙(Status가 빈값·Cancelled·Hold가 아니면 Inv No 유무와 무관하게 전부 매출로 집계)을 그대로 쓴다 — 개발 당시 “라이브 Power BINew Sales Dashboard v7리포트와 정확히 수치가 일치하는 것”이 목표였고, 그 리포트가 실제로 블랙리스트로 계산되는 것을 HWD 딜러 Rebate(5%, 2026)=$12,972 라는 실측값으로 검증했다(2026-08-17-sales-dashboard-html-build-session-log).이 문서(§ 위 정정)는 “Power BI Sales/Oders 팩트 테이블”이 화이트리스트를 쓴다고 명시한다. 두 서술이 동시에 참이려면,
New Sales Dashboard v7리포트가 Sales/Oders 팩트 테이블과는 다른 DAX 측정값을 쓰고 있어야 한다 — 같은 .pbix 안에 리포트별로 다른 필터 로직이 있는 것 자체는 드문 일이 아니지만, 아직 확인되지 않은 가설이다. 다음에 Power BI 파일을 열어볼 기회가 있으면New Sales Dashboard v7이 참조하는 정확한 DAX measure/Power Query를 대조해 이 disputed 상태를 해소할 것 — 회사의 실제 공식 매출 보고 경로에 화이트리스트/블랙리스트 중 어느 쪽이 실제로 쓰이고 있는지가 걸린 문제라 가볍게 넘길 사안이 아니다. 상세: Google Sheets 연동 실시간 대시보드 구축 가이드 (TAB Dashboard 사례) §6.
- 매출 인식 필터 (화이트리스트 — 정본): 매출액은 ①
Inv No(인보이스 번호)가 발행되어 있고, ②Status가"Credit"/"Invoiced"/"Confirmed"중 하나인 행만 포함한다. 이 두 조건을 모두 만족하는 행의Sales금액을 모두 더한 값이 매출액이다.Status비교는 앞뒤 공백 제거 + 대소문자 무시로 한다(" Confirmed"표기 오류 흡수). 그 외 상태(Quote, Pending, Backorder, Ordered, Picking, Released, Restocked, Cancelled, Hold, 빈 값 등)와Inv No가 없는 행은 매출에서 제외한다."Credit"(크레딧노트/반품)은 보통Sales가 음수라, 합산하면 자연스럽게 순매출(net)이 된다 — 별도 부호 처리 불필요.
- 매출(Sales):
Sales컬럼 = 실제 판매금액.RRP= 권장 소비자가(리베이트 산정 기준액).TA$= 실제 기록된 리베이트 금액.Freight/Extra= 부대비용. 이 네 컬럼의 의미를 혼동하면 “리베이트”를 3가지 다른 숫자로 잘못 계산하게 된다.- 가격 변동 해석(중요): 매출 추세를 해석할 때는
RRP를 시기별로 함께 분석한다. 제품 가격은 고정이 아니라 인상된다 — 예: 2026-02-01부터 가격 인상(동일 모델 101개RRP중앙값 2025-082026-01 대비 2026-022026-07 +10.7%, 89% 모델 인상; 월별 RRP 중앙값 2026-014,325→2026-024,610로 계단 상승, 2026-08-12 확인). 따라서 매출액이 유지/증가해도 그것이 물량 증가가 아니라 가격 인상 때문일 수 있다 — “매출 보합인데 수주(물량)는 감소” 같은 패턴을 놓치지 않으려면 매출액·수주(물량)건수·RRP를 함께 본다.
- 가격 변동 해석(중요): 매출 추세를 해석할 때는
- 연도/월 귀속: 매출액은
Inv Date(인보이스일) 기준으로 연/월을 잡는다. “매출 인식 건수”(매출로 잡힌 행 수)도 같은 대상 행을Inv Date기준으로 센다 — 매출액과 건수가 항상 같은 집합을 가리키게 한다. - 수주건수 (매출과 별개 지표): “얼마나 많은 주문이 들어왔는가”를 보는 선행지표.
Order date(주문일) 기준으로 모든 행 수를 세되,Status가Cancelled/Hold/ 공백(blank)인 행만 제외한다(David 확정 규칙, 2026-08-12).Restocked는 매출(#1)에서는 제외되지만 수주건수에는 포함된다 — 재입고도 한때 접수된 주문이므로. 즉 포함 상태는Confirmed·Credit·Invoiced·Ordered·Picking·Released·Restocked. 고유Order No가 아니라 행(라인 아이템) 수로 센다. 아직 인보이스되지 않은 주문도 포함되므로 매출(인보이스 완료)보다 앞선 신호다. 매출건수(Inv Date, 인보이스 완료)와 수주건수(Order date, 주문 접수)는 기준·시점이 다르니 한 표에서 섞지 않는다. (Worker 구현:_google-sheets.js의aggregateSalesData가pipelineMonthly로 별도 산출.) - 지역:
State는NSW/VIC두 값만 존재한다(직접 운영 오피스: NSW 2021-01~, VIC 2023-01~). 5-a. 브랜치 판별 —Branch필드가 정본 (2026-08-19 신설): 그동안 TA QLD 식별을Company필드의 정규식 매칭(turbo\s*air\s*queensland|ta\s*qld, 아래 “중요 컨텍스트” §)으로 추정해왔는데, David가 “브랜치별 계산이 너무 복잡하다”며 Sales Data 시트에 사람이 직접 관리하는Branch컬럼(값:NSW/VIC/QLD)을 신설했다. 이제부터 브랜치 판별은Company정규식이 아니라 이Branch필드를 1차 기준으로 쓴다.- 검증(2026-08-19):
Branch가 채워진 16,528행 전체에서Branch='QLD'⟺Company정규식 매칭이 100% 일치(불일치 0건) — 기존 추정 로직이 정확했음을 재확인한 것이지, 기존 로직이 틀려서 바꾼 게 아니다. 목적은 정확도가 아니라 유지보수성(사람이 시트에서 직접 관리하는 필드가 코드에 박힌 정규식보다 다루기 쉬움). - 폴백 필요: 같은 시점 기준 약 399행(전체의 ≈2.4%)은
Branch가 아직 비어있다(시트 백필 지연) — 그중 다수가 최근 1~2개월 데이터라 “오늘의 현황” 같은 최신 스냅샷에 실질적 영향이 있다.Branch가 비어있으면 기존Company정규식으로 폴백해야 하며, 폴백 없이 그냥 넘기면 최근 데이터가 조용히 어느 브랜치에도 안 잡히는 회귀가 생긴다. Branch는 NSW/VIC/QLD 3종뿐 — QLD 일반 주문과 QLD 컨테이너 주문(Delivery=CONTAINER)의 구분은 이 필드에 없다. 그 구분은 여전히Branch='QLD'판정 위에Delivery필드를 얹어서 한다(§ Google Sheets 연동 실시간 대시보드 구축 가이드 (TAB Dashboard 사례) §1.4).- 적용 범위:
05_SalesReport/TAB_Dashboard.html(로컬 대시보드)과functions/api/_google-sheets.js(/ask봇 Worker) 양쪽 다Branch필드 우선 +Company정규식 폴백 방식으로 갱신됨(2026-08-19). 새로 만드는 어떤 브랜치별 계산도 이 순서(Branch 우선 → 폴백)를 따를 것. - 후속 확정(같은 날) —
StatevsBranch의 용도가 명확히 갈림: 시트의 blankBranch값을 전부 채운 뒤(폴백이 더 이상 필요 없어짐), David가 두 필드의 역할을 이렇게 확정했다 —State는 “제품 출고 웨어하우스 기준지역”(그 주문을 어느 오피스가 물리적으로 처리·출고했는가, TA QLD 소속 주문도 서비스한 오피스의 State로 남음),Branch는 “브랜치별 실적 계산”(매출액·수주건수·출고건수 등 KPI를 어느 브랜치 몫으로 귀속시킬지, TA QLD 소속 주문은 항상Branch='QLD'). 즉 TA QLD의 한 주문이 State=NSW·Branch=QLD로 동시에 존재할 수 있다 — 이게 버그가 아니라 두 필드가 각자 다른 질문에 답하도록 의도적으로 분리된 것이다.- 실적 KPI(매출액/수주건수/출고건수/지역별 랭킹 등)는 항상
Branch를 참조한다. 웹 대시보드의 “지역” 필터(filterState, 라벨을 “지역 (Branch)“로 정정함)·거래 내역/리베이트 테이블의 지역 컬럼·/ask봇의[표4](연도별 브랜치 매출)·[표7](딜러별 지역) 전부 이 규칙으로 갱신됨(2026-08-19). - 예외적으로 여전히
State를 쓰는 곳: (1) “NSW+VIC 합계”/“NSW+VIC-QLD” 필터(오늘의 현황 탭) — 이건 “어느 오피스를 거쳐 출고됐는가”를 묻는 웨어하우스 관점의 합계라 의도적으로 State 유지. (2) 백로그·손상재고·손상품판매·클리어런스판매 카드(“재고/클리어런스 현황” 섹션 전체) — 물리적 재고 상태를 보는 웨어하우스 관점이라 State 유지(백로그/손상재고는 애초에 Table 탭의 별도 DMG 요약표에서 오므로 Branch 개념 자체가 없음). 이 두 예외를 빼면 나머지는 전부 Branch. - 재사용 원칙: 새 KPI/필터를 추가할 때 “이게 실적(누구 몫의 매출/수주인가)을 묻는가, 웨어하우스(어디서 처리됐는가)를 묻는가”를 먼저 판단하고 그에 맞는 필드를 쓴다. 애매하면 기본값은
Branch(실적 계산이 압도적으로 더 흔한 요구이므로).
- 실적 KPI(매출액/수주건수/출고건수/지역별 랭킹 등)는 항상
- 검증(2026-08-19):
- 통화·표기: 통화는 AUD. 가격·금액(매출·단가·RRP 등 화폐 값)을 문서·표·답변에 표시할 때는 항상 숫자 앞에
$를 붙인다(예:$1,234,567,$4,610). 건수·연도·퍼센트·모델번호 등 화폐가 아닌 숫자에는$를 붙이지 않는다. (사이트 렌더링에서$는 정상 표시된다 — LaTeX 플러그인 비활성화됨, Cloudflare Pages Function + Claude API로 Wiki 기반 Q&A 봇 만들기 참고.) - 제외 상태는 지표별로 다르다: 매출(#1)은 화이트리스트(Credit/Invoiced/Confirmed)만 포함 → Restocked·Cancelled·Hold·Ordered·Picking·Released·공백 모두 제외. 수주건수(#4)는 Cancelled·Hold·공백만 제외 → Restocked 포함. 두 지표의 제외 규칙을 혼동하지 말 것(특히 Restocked: 매출 제외, 수주 포함).
- 미인보이스(백로그):
Inv Date가 빈 행(Status는Ordered/Picking/Released등)은 아직 매출로 잡히지 않은 주문이다. 매출 집계(#1)에서는 자연히 빠지지만, 수주건수(#4)에는Order date기준으로 포함된다 — 이것이 수주건수가 선행지표인 이유.
중요 컨텍스트 — “Turbo Air Queensland TA QLD”는 별도 오너십 파트너
Disputed Claim (해결됨)
이전에 05_SalesReport 볼트의 분석에서는 이 회사를 “Turbo Air 자사 QLD 지점/법인으로 추정”이라고 잘못 짐작했었다. 00_TAB_프로젝트_선언문 §2 및 회사소개서(2026-07_회사소개서)가 정답이다: TA QLD(QLD Office)는 별도 오너십의 관계사로, 사장님으로부터 QLD 지역 판매권을 구매해 운영하며 모든 제품을 우리를 통해 구매한다(딜러가 아니라 관계사이자 우리의 대형 고객사). “자사 지점”도 “일반 딜러”도 아니다.
핵심: TA QLD 매출의 월별·기간별 등락은 자사 실적 위협이 아니다. TA QLD는 컨테이너 단위 대량 오더를 하므로 매출이 해상운송·컨테이너 도착 시점에 좌우돼 특정 월에 몰리거나 비는 구조다. 따라서 (1) 경영 판단·트렌드는 항상 TA QLD 제외(exQLD) 기준으로 보고, (2) TA QLD 포함/제외 두 버전을 함께 산출하되 TA QLD 변동을 자사 영업력 신호로 오독하지 않는다.
Update (2026-08-19) — TA QLD 판별 1차 기준이
Company정규식에서Branch필드로 바뀜위 문단이 설명하는 “TA QLD”의 의미(별도 오너십 관계사, 컨테이너 대량 오더)는 그대로다. 달라진 건 어떻게 판별하는가뿐이다 — 이제 시트의
Branch필드(NSW/VIC/QLD)가 1차 기준이고,Company정규식은Branch가 비어있는 소수 행의 폴백으로만 쓴다. 상세: § 아래 “계산 규칙” 5-a.
리베이트 스킴 구조 (Scheme 35% / 41%)
판매 건수 구간에 따라 리베이트율이 계단식으로 오르는 두 스킴이 모델에 하드코딩되어 있다(2026-08-04, tmdl 압축값 직접 디코딩으로 검증):
| 구간(순 판매 건수) | 35% 스킴 | 41% 스킴 |
|---|---|---|
| 1–20 | 0% | 0% |
| 21–50 | 4% | 0% |
| 51–100 | 7% | 1% |
| 101–150 | 10% | 4% |
| 151+ | 13% | 7% |
리베이트율 × “리베이트 대상 RRP 합계”(TA$ Exc = False인 건만) = 예상 리베이트 금액. 어느 딜러가 35%/41% 중 어느 스킴 대상인지는 모델·시트에 명시되어 있지 않다 — Open Questions 참고.
크로스볼트 참조 — 05_SalesReport (위성 볼트)
전체 테이블/컬럼 스키마, 22개 측정값 DAX, 비즈니스 용어집, 최신 분석 보고서는 이 볼트에 두지 않고 위성 볼트 05_SalesReport를 그대로 참조한다(중복 보관 시 드리프트 발생 — 위 TA QLD 사례가 실제 예시).
| 문서 | 용도 | 열기 |
|---|---|---|
| Semantic Model 개요 | 17개 테이블 전체 목록·분류 | obsidian://open?vault=05_SalesReport&file=Data%20Catalog%2FSemantic%20Model.md |
| Business Glossary | 테이블/측정값 비즈니스 의미 알파벳순 사전 | obsidian://open?vault=05_SalesReport&file=Data%20Catalog%2FBusiness%20Glossary.md |
| Sales 테이블 문서 | 매출 팩트 테이블 컬럼·키·관계 | obsidian://open?vault=05_SalesReport&file=Data%20Catalog%2FTables%2FSales.md |
| Oders 테이블 문서 | 주문 팩트 테이블 컬럼·키·관계 | obsidian://open?vault=05_SalesReport&file=Data%20Catalog%2FTables%2FOders.md |
| _Measures 문서 | 22개 DAX 측정값 요약 | obsidian://open?vault=05_SalesReport&file=Data%20Catalog%2FTables%2F_Measures.md |
| 판매실적 분석보고서 (2026-08) | 2021~2026 전체 분석, 딜러/제품 트렌드, 데이터 품질 이슈 | obsidian://open?vault=05_SalesReport&file=Reports%2F판매실적 분석보고서 (2026-08).md |
Info
obsidian://링크는 이 컴퓨터에서 Obsidian으로 열 때만 동작한다(두 볼트가 별개 Obsidian vault이므로 일반[[wikilink]]로는 서로 열리지 않음). 이 볼트가 05_SalesReport의 어떤 문서를 근거로 답하든, frontmattersatelliteVaultRelated에 해당 링크를 기록한다(§CLAUDE.md“위성 데이터 볼트 연결” 참고).
Power BI 퍼블릭 대시보드 (사람용, AI 데이터소스 아님)
이 링크는 인터랙티브 대시보드라 사람이 직접 필터를 조작해 보는 용도로만 쓴다. AI는 이 iframe에서 실시간 필터 결과를 읽어올 방법이 없다 — 반드시 위 “데이터 원천”의 Google Sheets 커넥터 경로로 조회한다.
라이브 조회 vs 스냅샷 — 언제 뭘 쓰나
- 즉답이 필요한 정확한 숫자 (“이번 달 매출”, “HWD 올해 실적”) → 매번 이 가이드의 절차로 live 재계산. 캐시하지 않는다.
- 트렌드·해석·이상 신호 (“왜 HWD가 줄었나”, “35% 스킴이 41%보다 관대한가”) →
20. Wiki/25. Questions/의 Research Question이나30. Queries/의 Query Result로 위키에 축적한다. 숫자는 다시 계산해도 해석은 다시 만들 필요 없어야 한다. - “현재 기준 스냅샷”이 필요할 때 (경영 보고, 특정 시점 고정 기록) → 아래 절차로 새 raw-source를 만든다.
신규 스냅샷 생성 절차
- Google Drive 커넥터로 파일 ID
1VOpjK9aDUuVmwkAouzGu-X_mZvGRlyhKbTDP1D6FU3Q조회 (download_file_content, xlsx export). - 로컬에서
Sales Data시트만 파싱(openpyxl/pandas). - 위 “계산 규칙” 그대로 필터·집계(연도별, 해당 연도 월별, 딜러 Top 30 — 전체/최근 2개년, 제품 Top 30, TA QLD 포함/제외 비교, 백로그).
10. Raw Sources/19. TAB Project/04_영업/YYYY-MM-DD-TAB-영업-판매실적-라이브스냅샷.md로 저장.source에 파일 ID·시트명·조회 방법·조회 시각을 정확히 기록한다(과거 export처럼 “원천 시스템 미상”으로 남기지 않는다).index.md,log.md갱신.
Related
- 00_TAB_프로젝트_선언문
- 2026-08-04-TAB-영업-판매실적-라이브스냅샷-Sales-Data
- 2026-07-31-TAB-영업-딜러별-판매실적-전체-2021-2026
- 2026-07-31-TAB-영업-딜러별-판매실적-TAQLD제외-2021-2026
- Cloudflare Pages Function + Claude API로 Wiki 기반 Q&A 봇 만들기 — “접근 경로 2”(서비스 계정 자동 라이브 조회)의 Worker 쪽 구현 상세
- 2026-08-19-Q-NSW-VIC-2026년도-신규-업체-리스트를-받고-싶어.-당사의-신 — “신규/이탈 딜러 세그멘테이션 질문 처리” §를 만들게 된 원인 사례(Nathan 매니저 질문)
Sources
- Google Sheets “Turbo Air” —
Sales Data탭 (직접 조회, 2026-08-04) - 05_SalesReport 볼트 Data Catalog (Power BI tmdl 역공학 분석)
- 00_TAB_프로젝트_선언문
Open Questions
Open Question — 부분 진전 (2026-08-21)
리베이트 스킴(35%/41%) 배정이 딜러별로 어떤 기준으로 결정되는지는 여전히 시트·모델 어디에도 명시되어 있지 않다 — 이 부분은 미해결. 다만 David 확인(2026-08-21): 이 스킴의 계산 결과가 실제로 기록·추적되는 곳은 Google Sheets “TADollar 2026” 탭이다(
Final TA$/Paid/Remains딜러별 원장 + 오더별 상세) — 상세 컬럼 명세·계산 검증은 Sales Data 테이블 명세 및 KPI 정의 §6,/ask봇 연동은 같은 §6.4 참고.
Open Question
Damaged,Clearance,Salesman필드가 각각 약 59%, 59%, 97% 결측이다(공백 vsFalse명시가 혼재). 입력 프로세스 개선이 필요한지, 원래 선택적 필드인지 확인 필요.