학회 비용 환급
동일한 행에서 두 개의 스프레드시트를 생성하고, 각각 동일한 합계를 가지며, 인용된 모든 영수증을 <conference folder>/החזרים/קבלות/에 저장합니다:
- SENT 파일
<conference folder>/החזרים/<full name> הוצאות.xlsx- 재무 부서에 제출되는 유일한 파일입니다. B열סעיף= 예산 항목 범주, 영수증 시트, 은행 블록, 환율이 포함됩니다. 예산 대비 실제 비교는 없습니다. - INTERNAL 파일
<conference folder>/החזרים/<full name> הוצאות - פנימי.xlsx- 사용자의 로컬 복사본으로, 첨부하거나 보내지 않습니다. B열השירות= 각 항목의 내용(예: "קפה", "רכבת שדה–עיר"),הערות뒤에סעיף범주 열, 그리고 예산 비교 테이블이 포함됩니다.
두 파일 모두 히브리어이며 오른쪽에서 왼쪽으로 작성됩니다. 사용자와는 영어로 대화합니다. 레이아웃은 번들로 제공된 assets/claim-template.xlsx(레이블만 있음)에서 가져옵니다. 사용자가 스프레드시트를 제공하지 않습니다.
프로필(전체 이름 및 은행 정보). ~/.config/conference-reimbursement/profile.json 읽기 ({"full_name": "...", "bank": {"בנק": "...", "סניף": "...", "מספר חשבון": "..."}}). 파일이 없거나 불완전하면 AskUserQuestion 도구로 누락된 필드를 요청하고(사용자가 직접 값을 입력), 권한 600으로 파일을 저장합니다. 파일은 해당 위치에만 유지하며, 저장소나 프로젝트 폴더 외부에 둡니다. 커밋하지 말고, 채팅이나 보고서에 은행 정보를 출력하지 말고(대신 "bank details: from profile"이라고 표시), 스크래치패드의 bank 키에만 복사합니다.
모든 질문은 AskUserQuestion 도구를 통해 사용자에게 한 번에 하나씩 묻고, 권장 옵션을 먼저 제시합니다.
모드 선택
- 모드 A — 전체 청구. 승인된 예산 양식 PDF, 은행 정보(프로필), 영수증 폴더 및 메일함 접근이 모두 가능합니다. 1-7단계를 실행합니다.
- 모드 B — 부분 입력. 위 항목 중 하나 이상이 누락된 경우. 동일한 단계를 실행하고 누락된 부분은 제외하며, 절대 임의로 생성하지 않습니다:
- 사용자가 은행 정보 제공을 거부함 →
bank생략; 스크립트는 빈 레이블 셀을 작성하고 "bank details missing — fill by hand" 경고를 표시하며 보고합니다; - 메일함 접근 불가 → 사용자가
קבלות/에 넣은 파일만 사용; 이메일을 검색하지 않았다고 보고; 7단계에서 이메일 본문을 초안 작성 대신 출력합니다; - 예산 양식 없음 →
budget생략; INTERNAL 파일은 예산 테이블 없이 작성되며 승인 금액과 비교가 없습니다.
- 사용자가 은행 정보 제공을 거부함 →
"수동 완료" 보고서에 모든 모드 B 누락 사항을 나열합니다.
1. 입력 수집(읽기 전용)
- 승인된 예산. 출장 폴더(
*טופס נסיעות*)에서 여비 예산 양식 PDF를 엽니다. 직접 읽습니다; 양식은 기관마다 다릅니다. 각 승인 항목(일비 אש״ל, 항공권 טיסה, 호텔, 보험, 등록, 기타)을 USD로 기록하고 출장 날짜를 기록합니다. - 프로필. 위에서 설명한 대로 전체 이름과 은행 정보를 로드합니다(처음에만 요청).
- 실물 영수증.
קבלות/폴더를 나열하고 모든 이미지를 읽습니다(HEIC는 먼저 변환, 3단계). 날짜, 공급자, 금액, 통화, 카드 마지막 4자리 및 식사 인원 수를 기록합니다. - 이메일 영수증. 예약 날짜부터 귀국 날짜 + 약 2주 동안의 메일함을 검색하고, 사용자의 여행 레이블 또는 폴더를 확인합니다. 모든 범주 쿼리를 한 번에 실행합니다 —
references/email-sources.md를 먼저 읽으십시오. 사용자가 나열한 것 이상을 살펴봅니다: 발견되지 않은 비용을 찾는 것이 업무의 일부이며, 발견된 각 항목을 제안합니다. - 다른 출장 제외. 기간 내의 모든 금융 이체와 항공권 예약을 열고 학회, 경로 및 날짜와 일치하는지 확인합니다. 각 제외 사항을 보고서에 기록합니다.
2. 정책 결정 질문
해당되는 것만 질문하며, 권장 옵션을 먼저 제시합니다. 이 기본값은 과거 청구 중 하나에서 가져온 것으로, 제안일 뿐 기관 규칙이 아닙니다.
- 공유 호텔 예약 → 본인 방만(권장) / 전체 예약.
- 공유 식사 → 전체 청구서 / 본인 몫만. 선택된 항목을 담당자에게 표시합니다.
- 환율 → 귀국일의 Bank of Israel 대표 환율, 통화당 하나의 환율(권장) / 각 영수증 날짜의 환율.
- 공유 항목(두 사람을 포함하는 포스터 인보이스) → 메모와 함께 사용자의 지분 청구.
- 항공권과 함께 구매한 추가 항목(좌석, 수하물, 보험) → 항공권 항목 내에 포함(권장).
3. 영수증을 PDF로 저장
- 이메일 첨부 파일. 메일 커넥터가 메시지 텍스트는 반환하지만 첨부 파일은 반환하지 않는 경우, 먼저 첨부 파일을 가져올 수 있는지 다시 확인하고, 불가능하면 브라우저 자동화를 통해 다운로드합니다(메시지를 열고 첨부 파일 다운로드 아이콘을 클릭한 후
~/Downloads에서 파일을 이동). 브라우저 자동화가 불가능하면 사용자에게 다운로드하거나קבלות/에 넣도록 요청합니다. - 첨부 파일이 없는 이메일(주문 확인) → PDF로 인쇄합니다.
- 각 파일을
<what> <provider> <document number>.pdf형식으로 히브리어로 이름을 지정합니다. - HEIC 사진 → 원본 옆에 PDF 복사본을 추가하고 원본은 수정하지 않습니다. macOS:
sips -s format pdf IN.heic --out IN.pdf. 다른 플랫폼에서는 pillow-heif가 설치된 Pillow를 사용하거나, 설치되지 않은 경우 사용자에게 사진을 PDF 또는 JPEG로 내보내도록 요청합니다. 스프레드시트의 영수증 시트를 위해 모든 사진과 스크린샷을 영수증 기본 이름으로 JPEG로 변환하여 스크래치패드에 저장합니다(원본은 절대 수정하지 않음):sips -s format jpeg -s formatOptions 70 -Z 1400 IN --out "<receipt base name>.jpg". - 저장된 모든 PDF를 읽습니다. 금액은 이메일 텍스트가 아닌 문서에서 가져옵니다. 차이가 있으면 문서를 사용하고 차이점을 표시합니다.
4. 스프레드시트 작성
-
사용된 모든 외화에 대해 선택한 날짜의 Bank of Israel 대표 환율(boi.org.il)을 가져옵니다. 환율 레이블에 날짜를 넣습니다:
שער יציג בנק ישראל, <dd.mm.yyyy>. 메모리나 이전 청구의 환율을 재사용하지 마십시오. -
스크래치패드에 spec JSON을 작성합니다. 스키마, 레이아웃 및 모드 B 동작:
references/spec-format.md; 합성된 작업 예제:references/example-spec.json. 프로필에서bank를 설정합니다.template은 제외합니다: 번들 템플릿이 기본값입니다. -
행 규칙:
- 날짜별로 정렬된 영수증당 하나의 행;
- 금액은 정확히 하나의 키에: 원래 통화(
usd,eur, 또는rates에도 있는 추가 코드) 또는ils; receipt=קבלות/의 파일 기본 이름(여러 개는+로 연결);note는 담당자가 의문을 제기할 수 있는 모든 것을 설명(공유 청구서, 반 인보이스, 호텔 인보이스에서 분리된 항목);line=budget에 정확히 철자된 예산 항목 이름; SENT 파일의 B열에는 이 항목이 표시됨(범주만, "coffee" 또는 "dinner" 아님 — 담당자는 승인 범주를 봄), INTERNAL 파일의סעיף열과 예산 테이블에서 사용됨;service= 항목에 대한 간단한 히브리어 설명("קפה", "ארוחת ערב", "רכבת שדה–עיר"); INTERNAL 파일의 B열에만 표시됨(생략 시 범주가 표시됨);- 학회 만찬을 포함한 식사 → 일비 항목;
- 호텔 인보이스의 레스토랑 요금 → 별도의 식사 행, 호텔 행은 감소.
receipt_images= 3단계의 JPEG(이번 출장 사진 및 스크린샷만).קבלות시트에 행당 5개씩, 각각 파일 기본 이름을 캡션 셀로 갖습니다. 이메일로 받은 PDF는 포함되지 않습니다. 7단계에서 zip 파일에 포함됩니다.
-
실행:
python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/build_claim.py" spec.json한 번 실행으로 두 파일이 모두 작성됩니다.
output(SENT),output_internal,total_ILS,total_USD및warnings가 포함된 JSON을 출력합니다. 예산 항목에 대한 모든 경고를 수정하고, 모드 B 경고를 보고서에 포함시킵니다.output_internal은 기본적으로.xlsx앞에- פנימי가 붙은 SENT 경로입니다. 로컬 복사본을 다른 곳에 두려면 spec에서 설정합니다. -
스크립트는
"overwrite": true가 설정되지 않으면 출력 파일을 덮어쓰지 않습니다. 사용자가 수동으로 편집한 파일에는 절대 설정하지 말고, 새 이름을 쓰거나 질문합니다.
5. 확인
완료는 실행 및 확인되었음을 의미합니다. 먼저 references/pitfalls.md를 읽으십시오.
-
검사 실행:
python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/check_claim.py" spec.jsontotal/total_internal: 스크립트의 Python 합계가 LibreOffice 재계산 후 각 파일의סה״כ בש״ח셀과 일치함(0.01 ₪ 이내), 따라서 두 파일이 동일한 합계를 가짐;sent_no_budget: SENT 파일에 예산 비교 테이블이 없음;receipts: 인용된 모든 파일이קבלות/에 존재함;budget: 모든 행의 항목이 예산 항목이며 INTERNAL 파일의 예산 테이블 실제 합계가total_ILS / USD rate와 일치함.
not_run검사는 실행되지 않음으로 보고하고, 통과로 보고하지 마십시오. -
독립 감사: SENT 스프레드시트와 영수증 폴더만 사용하여 서브 에이전트를 시작합니다(자신의 결론은 제외). 각 행의 금액, 통화, 날짜 및 파일을 영수증과 대조하여 확인하고, 재무 담당자가 의문을 제기할 수 있는 모든 것을 나열하도록 요청합니다. 실제 오류는 수정하고 나머지는 보고합니다.
6. 보고
다음 순서로 보고:
- 두 파일 경로(SENT, 첨부용; INTERNAL, 로컬 전용), 행 수, 총 ₪ 및 ≈ USD 대 승인 총액.
- 추가된 영수증(사용자 목록 이상 검색으로 발견된 것 포함).
- 사용된 환율, 출처 및 날짜.
- 예산 초과 항목: 테이블(항목, 승인액, 실제액, 차액).
- 출처 간 불일치(이메일 대 문서).
- 제외 사항(다른 출장에 속한 항목).
- 담당자 플래그(
references/pitfalls.md에서). - 수동 완료 항목(모드 B 누락, 스크립트 경고).
- 질문 없이 결정된 사항.
7. 재무 담당자에게 이메일 초안 작성
먼저 references/email-draft.md를 읽고 순서대로 따르십시오. SENT 파일(output, <full name> הוצאות.xlsx)만 사용하고 첨부합니다. INTERNAL - פנימי 파일은 절대 첨부, 업로드 또는 인용하지 마십시오 — email_summary.py에서 거부합니다. 요약:
- 사용자의 이전 청구 스레드(보낸 편지함, 약 2년 전, 답변 포함)를 읽고 스타일과 제목 패턴을 복사합니다.
- 질문: 은행 정보 포함 여부; 예산 또는 환율 라인(기본값: 둘 다 없음); 동행자 BCC(기본값: 아니요; 주소를 임의로 생성하지 마십시오).
scripts/zip_ereceipts.py spec.json→ 전자 영수증 PDF의קבלות אלקטרוניות.zip(UTF-8 이름, macOSzip명령 사용 금지). 사진과 스크린샷은 대신קבלות시트에 있습니다.scripts/email_summary.py spec.json …→ RTL HTML 본문("היי ," / "מה שלומך? :)" … "תודה רבה!"), 각 영수증 위치를 설명하는 קבלה 열이 포함된 요약 테이블, 스프레드시트에서 읽은 은행 정보.total_ILS가 빌드의 합계와 일치하는지 확인하고,rounding_diff가 있으면 언급합니다.- Gmail
create_draft를htmlBody와 함께 먼저 호출합니다. 그런 다음 Chrome의 Claude를 통해 SENT 스프레드시트와 zip 파일을 첨부합니다(초안의 작성 파일 입력에file_upload사용)하고 두 칩을 확인합니다 — 커넥터는 첨부 파일을 호출에서 base64로만 사용하고update_draft는 첨부 파일을 삭제합니다. 절대 보내지 마십시오. 사용자에게 초안 링크를 제공합니다.
공식
- 행:
ILS_i = amount_i × rate[cur_i], 또는 ₪ 금액 자체. - 합계:
T = Σ ILS_i; 달러로T / rate[USD]. - 예산 항목 ℓ당(INTERNAL 파일):
actual_ℓ = Σ_{line_i = ℓ} ILS_i / rate[USD];diff_ℓ = approved_ℓ − actual_ℓ, 음수는 예산 초과를 의미합니다. 모든 행의 항목이 예산에 있을 때Σ_ℓ actual_ℓ = T / rate[USD]입니다.
예: 환율 USD 4.00, EUR 4.50; 등록 $500, 호텔 €600, 택시 ₪200 → 2,000 + 2,700 + 200 = 4,900 ₪ = $1,225.
판단 사항
- 호텔 자체 인보이스가 예약 사이트 확인보다 우선합니다(세금 문서임).
- 은행 정보는 로컬 프로필에서 spec의
bank키로 가져오며, 스크립트가 레이블별로 작성합니다. AskUserQuestion을 통해서만 요청하고, 산문으로 묻거나 echo하지 마십시오. - 이 출장에 속하는 이전 부분 환급 → 해당 행을 이미 청구된 것으로 표시합니다.
- 사용자 기관의 규칙이 정책 질문을 결정합니다. 규칙을 주장하지 말고 질문하십시오.
참고
references/email-sources.md— 범주별 메일함 쿼리 및 확인할 사항(1.4단계).references/spec-format.md— spec 키, 두 파일 레이아웃, 스크립트 출력, 모드 B 동작(4단계).references/example-spec.json— 합성된 전체 spec(4단계).references/pitfalls.md— 이전에 발견된 실패 사례 및 담당자 플래그 체크리스트(5-6단계).references/email-draft.md— 이메일 초안: 이전 스레드, 문구, 첨부 파일(7단계).