หน้านี้ ต่างจาก deep-dive (ที่มาจาก FD) — เป็นความรู้ที่ พิสูจน์เองกับมือ ตอนทำ FUT: สถาปัตยกรรมที่ยืนยันแล้ว, defect 3 ตัวพร้อมหลักฐาน controlled experiment, ระบบ unit test 9 TC, ทักษะ post/อ่าน document และ correction ของความเข้าใจเดิม · ทุกจุดติดป้ายชัดว่า confirmed / inference / open · ชื่อเพื่อนร่วมทีมในต้นฉบับถูกแทนด้วย role
ZTAXB_R01 · main program SAPLZTAXA_R01 · enhancement ของ standard S_P00_07000134 (RFIDYYWT Generic WHT) · CoCd TH01 THR03 (P.N.D. 3/53/54 Attachment) — FD ไม่ได้ระบุ (gap) · AP2 ไม่ใช่ตัวใช้งานKURSF@T (WHT/ภงด.54) · Fx on posting date = TCURR@T-1 (VAT36/ภพ.36)KTOSL='WIT') เป็นสมอ · VAT36 เป็นผู้โดยสาร · 1 แถว = เย็บสูงสุด 4 ใบด้วย clearing (AUGBL)M(post FI) · B(selling≈BOT) · G(buying) · ZTH/ZOM(custom)ZTAXB_R01 (main program SAPLZTAXA_R01) = Reconciliation Report ภงด.54 ↔ ภพ.36 · เป็น enhancement ของ standard S_P00_07000134 (RFIDYYWT — Generic Withholding Tax Reporting) สำหรับ CoCd TH01 TH · เพิ่ม Profit Center (validate CEPC) + Recovery Indicator (validate T8JJ) ใน Further Selections + column ฝั่ง VAT36
RFIDYYWT เป็น เครื่องยนต์กลางตัวเดียว serve WHT reporting หลายประเทศ — ความต่างทั้งหมดย้ายไปเป็น config Process Type + Output Group · โปรแกรมเป็นแค่คนทำตามสูตรOutput group เป็น config ระดับ engine ไม่ใช่ระดับรายงาน — ทุก group ของ TH โผล่ใน F4 ของทุกโปรแกรมบน RFIDYYWT · “กดได้” ≠ “ใช่ของเรา” · 1 group = 1 สูตร (อ่านจากไหน + ผลิต List/Forms/Files + render แบบไหน)
| Group | Description (F4) | สถานะ |
|---|---|---|
R03 | Attachment P.N.D. 3, 53 and 54 — Vendors, Original Documents | Official ของ RPT-1 — team lead ยืนยัน (วาจา) 02.08 |
AP2 | WHT Certificate for Thailand & Form No. 54 | ไม่ใช่ตัวใช้งาน — สาย certificate (เคยเข้าใจผิดจากคำว่า “Form 54”) |
E08 | Attachment P.N.D. 1 Kor & E-Filing | คนละกระบวนการ (ภงด.1ก) · render เป็น classic list |
CER | เหมือน AP2 เป๊ะ | Open — group ซ้ำ/legacy? ถาม config owner ก่อน UAT |
E01–E10, E1K, E2K | Attachment + E-Filing แยกตามแบบ ภงด. | สูตรของ objects ตระกูล text file (TAX-ENH-1/077/079) |
| Column | FD step | Source | วันที่ | Serve |
|---|---|---|---|---|
| Fx on TaxPmt | 22 | BKPF-KURSF จาก payment doc ที่ post แล้ว | T (วันจ่าย) | WHT / ภงด.54 |
| Fx on Posting date | 28 | รายงานเปิด TCURR เอง GDATU=BUDAT−1 | T-1 | VAT36 / ภพ.36 |
ที่มาของสองโลก: post เข้า GL ใช้ rate M @ T (หลักบัญชี ค่ากลาง ณ วันเกิดรายการ) · แต่เกณฑ์สรรพากรไทยใช้ rate BOT วันทำการก่อนหน้า (T-1 ≈ เลน B) — ช่องว่าง M@T ↔ B@T-1 คือเหตุผลการมีอยู่ของ TAX-ENH-2 (post ส่วนต่างปรับ WHT) และการที่ RPT-1 ต้องโชว์ 2 FX column เทียบกัน
รายงาน เกาะเส้น WHT ที่จุดจ่าย (ACDOCA KTOSL='WIT') เป็นสมอ · VAT36 เป็นผู้โดยสาร:
1 แถว = เย็บสูงสุด 4 ใบ: (1) Invoice จาก FB60 → base, VAT36 lines, invoice currency, PC/RI · (2) Payment จาก F-53 → WHT line, KURSF, วัน T · (3) VAT36 doc 9xxxxxxxxx ที่ ZTAXA_R02 สร้าง · (4) WHT FX adj doc (type SW) ที่ ZTAXA_R03 สร้าง · ตัวเย็บ = clearing (BSAK/BSEG-AUGBL) ที่เกิดตอน activate open item ใน F-53
ลำดับ business: (01) AP posting → (02) ZTAXA_R03/TAX-ENH-2 → (03) ZTAXA_R02/TAX-ENH-3 → (04) RPT-1 · ประโยค KT sheet (“report generated after E032 & E040”) = ลำดับงาน user สิ้นเดือน ไม่ใช่เงื่อนไขทางเทคนิค
OB08/TCURR เก็บแบบ valid-from (แต่ละบรรทัดมีผล “ตั้งแต่วันนั้นจนกว่าจะมีบรรทัดใหม่”) · standard หา rate ด้วย ล่าสุดที่ ≤ วัน posting · เสาร์อาทิตย์/วันหยุดไม่มี rate ใหม่ → ใช้บรรทัดวันทำการล่าสุด (พิสูจน์แล้ว: จ่ายอาทิตย์ 02.08 ระบบดึง 32.57230 ของศุกร์ 31.07)
Rate type = เลนขนานในตารางเดียว: M=middle (post FI ถูกล็อคเลนนี้) · B=selling (≈BOT ฝั่งขาย) · G=buying · custom ZTH (TAX-ENH-2 ฝั่ง LC3) / ZOM (RPT-2 Oman)
GDATU=BUDAT−1 · ถ้า Z-code เขียน exact match แทน ≤ fallback → payment วันจันทร์/หลังวันหยุดจะได้ Fx on posting date = blank (BUDAT−1=อาทิตย์ ไม่มี GDATU) · อาการเหมือน TC-003 แต่คนละเหตุ · พิสูจน์ฟรีด้วย “การทดลองวันจันทร์” · ฝั่ง GL posting พิสูจน์แล้วว่าใช้ ≤ · เหลือฝั่ง report1 defect 1 ticket — คนละชั้น อย่ายำรวม (report logic vs GL posting vs rendering)
Scope ยืนยัน: เกิดเฉพาะ currency case 1 (invoice สกุลที่สาม GBP/EUR → payment USD) และเฉพาะ payment ที่ มี WHT line · case 2 (USD→THB) / case 3 (THB invoice) ไม่โดน · root cause อยู่ ฝั่ง posting ไม่ใช่รายงาน — RPT-1 เป็นกระจก read-only
Owner: fix = GL team · config = Config owner · comms routing = Comms lead · Acceptance criterion: bank outgoing line converts at the payment document’s date
เงื่อนไข: rate M USD→THB วัน invoice (24.07 = 32.34140) ต้องต่างจากวันจ่าย (02.08 = 32.57230), delta = 0.23090 · ถ้า rate 2 วันเท่ากัน bug ล่องหน (บทเรียนเดียวกับ F6 ของ RPT-2 ที่ flat rate ใน DEV บังไว้)
คู่หลัก (มี WHT): invoice 2004326539 GBP 1,000, V2, backdate 24.07, vendor line 44,060.10 THB · payment 8084322489 USD 1,140.19 (=85% ของ 1,341.40 หลังหัก WHT 15%), จ่าย 02.08
| บรรทัด (doc 502) | USD | THB (LC) | Rate แฝง | ตัดสิน |
|---|---|---|---|---|
| Bank (A102X003) | 1,140.19 | 43,679.45 | 38.31 — ไม่มีจริงใน TCURR ทุก type | ❌ พัง |
| Vendor (clear) | 1,341.40 | 44,060.10 | มูลค่าวัน invoice ยกทั้งก้อน | ✅ ปกติ |
| WHT Pay PND54 | 201.21 | 6,553.86 | 32.5723 = rate วันจ่าย | ✅ ถูก |
| RealizedFX (2 บรรทัด) | 0.00 | 6,173.21 + (15.24-) | ตัวโปะที่ระบบ post เอง | อาการตาม |
ที่ถูกต้อง: bank = 1,140.19 × 32.5723 ≈ 37,138.6 → GL เพี้ยน ≈ 6,540.9 THB
สมมติฐานที่ตัดออก: (1) rate type ผิด → USD ทุก type ตระกูล 32.x, 38.31 ไม่ match · (2) rate ไม่มีในตาราง → OB08 ครบทุกวันทำการ · (3) ขั้นตอน post ผิด → control ขั้นตอนเดียวกันออกถูก · ทิศทางหลักฐาน: program logic ของ clearing/WHT path (ฝั่ง b) > config (ฝั่ง a) เพราะ config ผิดจะกระทบทุกใบ ไม่เลือกเฉพาะใบมี WHT
ความผิดปกติของ 457 อยู่คนละจุด: การแปลง GBP→USD (vendor 1,354.90 / bank net 1,151.67) ใช้ cross rate ของ 07.07 ทั้งที่จ่าย 14.07 · สอดคล้องกลไกกับ 502: ทั้งคู่ยอดถูก derive จากมูลค่า ณ วันเก่า แทนแปลงจริง ณ วันจ่าย — แค่คนละมิติ (457 เพี้ยนเลน USD, 502 เพี้ยนเลน THB) · การ map กลไกต่อใบเป็นงาน triage ของ GL team · หน้าที่เรา = ส่งเลข observed ครบ
C_PC11 / RI CP — ไหลเข้า profit center เดียวกับที่ RPT-1 และ TC-005 answer key อ่าน = เหตุผลต้องแก้ที่ posting ไม่ใช่ปัดที่รายงานอาการ: invoice THB + payment FC → “FX on posting date” blank และ VAT36 base/amt (THB) = 0.00 ทั้งคู่ (หลักฐานแรก: doc 2004322073 / VAT36 9004322999, 31.07)
กลไก: FD step 28 case 2 บอก “ไม่ต้อง convert” แต่ dev implement เป็น SELECT TCURR ทุกกรณีโดยไม่มี same-currency guard — ไม่มีใครเมนเทน rate THB→THB → SELECT ไม่เจอ → rate ค้าง initial → domino: THB columns = FC×0 = 0.00 (สองอาการ สาเหตุเดียว)
Expected หลัง fix (confirm โดย SI functional 31.07): FX on posting date = 1.00000, VAT36 THB = ยอด DC ตรง ๆ · Proposed fix: ถ้า BKPF-WAERS = THB → hard-set rate = 1.00000 แล้วข้าม TCURR fetch
อาการ: untick “Company Codes” ใน List Sections → short dump ใน SAPLZTAXA_R01 · Reproduce ยืนยันบนทั้ง R03 (official path!) และ AP2 · E08 (classic list) ไม่เป็น
กลไก: โปรแกรมถูกแปลงจาก classic list (WRITE — 4 sections ต่อกันในม้วนเดียว ตัดอิสระ) เป็น ALV (1 grid:1 จอ ต้องมีโครงสร้างของแต่ละ section) แบบครึ่ง ๆ กลาง ๆ · code path ALV assume ว่า section ครบ · untick → โครงสร้างไม่ถูกสร้าง แต่ code ยังอ้างถึง → field symbol ไม่ assign → dump · พังทั้ง R03+AP2 = จุดพังอยู่ โค้ดส่วนกลางของ render ไม่ใช่ logic เฉพาะ group
ทุก TC self-contained: post เอกสารใหม่เอง บน master data ที่ proven · ยอดมาตรฐาน base 1,000 / WHT 15%=150 / VAT36 7%=70 · ใช้ posting date เดียวกันทุกใบเป็น isolation key (E032 เลือกด้วย period → วันเดียวร่วมทำให้ write ครอบเฉพาะจักรวาลเรา ใน shared client)
| Set | TC | Invoice | Payment | WHT/VAT36 | บทบาท |
|---|---|---|---|---|---|
| A | TC-002 | THB | THB | ✓/✓ | No-conversion; E032 pass-through (zero adj) |
| B | TC-003 | THB | USD | ✓/✓ | Reproduce defect FX blank |
| C | TC-004 | USD | THB | ✓/✓ | Invoice-currency conv @T-1; side-evidence 163211 |
| D | TC-001 | EUR/GBP (post หลัง fix) | USD | ✓/✓ | Case 1 full chain |
| E | TC-008 | THB | THB | ✓/✗ | PND54-ไม่มี-VAT36 (ว่างโดย design) |
| F | TC-006 | THB | USD | ✓/✓ | E032 transition (ต้องจ่าย FC ไม่งั้นไม่มี FX diff) |
| G | TC-007 | THB | USD | ✓/✓ | E040 transition (VAT36 Doc No. ก่อน/หลัง) |
| H | TC-009 | THB | THB | ✗/✓ | Negative — ต้องไม่โผล่ |
Stage บังคับ 5 ขั้น: (1) Post ทั้งหมดยกเว้น D → (2) Baselines + read-only ทั้งหมด ก่อน update run ใด ๆ → (3) Chain writes: E032 test→update (=TC-006), R030 test→update ราย doc (=TC-007 + เติม TC-002/004) → (4) Post-chain verifications → (5) Gated: TC-001 หลัง GL fix / TC-003 retest หลัง report fix
KTOSL='WIT' อยู่มุมนี้)| รายการ | สถานะ |
|---|---|
Doc set A (2004326537 THB 12,345 + payment) | ✅ post ครบคู่ — TC-002 พร้อม run บน R03 |
Repro pair (2004326539 + 8084322489) | ✅ post — ป้าย DEFECT-REPRO ห้ามเป็น TC-001; รอ run R03 เป็น observation |
| Control pair (GBP no-WHT + USD payment) | ⚠️ ยืนยัน post จบ + เก็บเลข doc + capture ขา bank (×32.5723) · ใช้เป็น mini TC-009 FC |
| TC-005 baseline (116 records, 30.07) | ⚠️ re-verify บน R03 + re-export answer key หลัง Stage 1 (population เปลี่ยน) |
| Doc sets B, C, E, F, G, H | ⏳ ยังไม่ post — pattern พร้อม (B/F/G=THB→USD, C=USD→THB) |
| Doc set D (TC-001) | 🔒 Gate: ห้าม post จนกว่า 163211 fix transport |
TAXR074_FUT_Execution_Workbook_TC001-TC009_v2.xlsx · Client_FUT_..._TAX-RPT-1_...xlsx (template ทางการ 9 TC, 50 steps) · DEFECT_REPRO_TKT-02_Summary_20260802.xlsx — ทั้งสามไฟล์ยังเขียน AP2 ต้องอัปเดตเป็น R03 (งานค้างอันดับต้น)| # | คำถาม | สถานะ |
|---|---|---|
| 1 | ทำไม wrong-date เกิดเฉพาะ payment ที่มี WHT line | ตอบแล้ว ด้วยคู่ control/repro |
| 2 | Fx on TaxPmt (T) vs E032 (T-1) — ค่าไหนยื่นจริง / E032 ต้อง run ก่อน RPT-1? | ครึ่งแรก เปิด · ครึ่งหลัง ตอบ (business order ไม่ใช่เทคนิค) |
| 3 | Step 28 อ่าน TCURR exact GDATU=BUDAT−1 หรือ ≤ fallback | GL พิสูจน์ ≤ แล้ว · report รอ “ทดลองวันจันทร์” เปิด |
| 4 | OB08 maintenance timing + เจ้าของหลัง go-live | เปิด · TCURR = client-wide ห้ามเมนเทนเองโดยไม่ประกาศ |
| 5 | Handover artifacts + ABAP dev contact ของ RPT-1 | เปิด · สำคัญขึ้นเพราะ TC-003 fix ต้องมี dev contact |
| ใหม่ | Official output group | R03 (วาจา) — ตอกหมุดเป็นลายลักษณ์อักษร |
| ใหม่ | AP2 vs CER description ซ้ำ | เปิด — ถาม config owner ก่อน UAT |
ส่วน 1–5 คือสิ่งที่พิสูจน์ช่วง 31.07–02.08 · ส่วนนี้คือสิ่งที่เกิดหลังจากนั้น: RPT-1 ผ่าน review 11-Sep · R03 ถูกใช้เป็น output group ทางการ · split lines (TKT-01) กลับมาทำต่อ 2-Oct
| # | Issue | หลักฐาน / ตัวอย่าง | Next |
|---|---|---|---|
| 1 | Multi-invoice payment (14-Sep): รายงาน resolve AP voucher ตัวเดียวแล้ว stamp ทุกแถว | 8084322636 (THB, 3 vendors) · 8084322637 (USD, vendor เดียว, 6 invoices รวมเป็น 2 WHT sets) | Dev fix ต่อแถว: BSAK-LIFNR = WT_ACCO + match WITH_ITEM ของ invoice (vendor + type + code) · กฎแบ่งยอด = D3 |
| 2 | คอลัมน์ WHT Rate โชว์ 15% สำหรับ code 44 ที่ post 10% | — | เช็ก T059Z |
| 3 | FD gap: steps 17/18 บอก KTOSL = WIT แต่ไม่มีการเลือกบรรทัด · step 34 ใช้ KTOSL = XST | claim เดิมว่า step 33 ไม่มี KTOSL — ถอนแล้ว | FD v0.2 / CR (G3) |
| 4 | TKT-01 split lines: WHT@payment หยิบ ACDOCA WIT record แรกแม้เป็น 0.00 | 2004328305 (5A/39, 3 WIT lines 90/45/15) · 2004327460 (USD, WIT 10/5) · 2004328295 / 8084322641 | ส่ง expected-result workbook แล้ว (หนึ่งแถวต่อ WIT line ที่ HSL ≠ 0) · เทียบไอเดีย “high-precision portion” ของ senior กับ WIT-ratio · partial payment รอยืนยัน |
| 5 | TKT-02 (GL): invoice สกุลที่สาม (GBP/EUR) → จ่าย USD มี WHT — bank line ใช้ rate วัน invoice | คู่ control / repro ส่วน 2 | Acceptance = bank line ใช้วันที่ของ payment doc · บล็อก TC-001 |
| 6 | GL-ENH-1: WITH_ITEM ไม่ถูก update ด้วยบรรทัด WHT ของ GL ตอน post | 8084322568 aux 38,000.70 / 5,700.11 vs GL 38,108.97 / 5,716.35 (adj 8084322578) · 8084322545 same-day gap 4.57 | ประสานกับ ENH-2 owner (dual-write) |
| 7 | 5G doc 8084322612 (5G/B8) อยู่ใน WITH_ITEM แต่ไม่ออก R03 | — | SE16N ZCAX_P01 WHT_TYPE_PND54 → BAdI → form-name condition → standard DS FM |
| Doc(s) | ใช้พิสูจน์อะไร |
|---|---|
581 / 5184 | EUR→USD ผ่าน ENH-2 · step-28 = 38.03240 |
558 / 4943 | same-day gap |
552 / 4882 | USD→THB · กับดัก Sunday fallback (ดูถูกเพราะบังเอิญ) |
568 / 5069 | ratio-vs-table discriminator · step-28 = 32.72500 |
580 | LC3 fail (“Balance in Hard currency USDTH”) |
611 | GBP→USD · step-28 = 44.14480 |
5473 | multi-PC |
4941 + 5690 | 5A docs |
8084322636 / 650 | multi-invoice payment |
2004328305 / 2004328295 | split lines |