Skip to main content

Catalog & Search Requirements

หน้านี้รวม Functional Requirements, Acceptance Criteria และ Business Rule Matrix สำหรับ QA/BA
อ้างอิง: PriceEstimationService.cs, QuoteOrchestrator.cs, AddOnService.cs, Catalog validators


As a ลูกค้า (Guest หรือ Member)
I want to ค้นหารถเช่าที่ว่างในช่วงวันและสาขาที่ต้องการ
So that ฉันเห็นรถที่พร้อมใช้งานพร้อมราคาที่ถูกต้อง

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1ระบุ pickup/return branch, pickup/return datetime ที่ถูกต้องแสดงรายการรถที่ว่าง พร้อม local metadata (ชื่อ, รูป, เกียร์, เชื้อเพลิง)
AC2Pickup branch ไม่พบในระบบError: "Pickup branch with code X not found"
AC3Pickup branch status = inactiveError: "Pickup branch with code X is not active"
AC4Return branch ไม่พบในระบบError: "Return branch with code X not found"
AC5Return branch status = inactiveError: "Return branch with code X is not active"
AC6Filter TransmissionTypeแสดงเฉพาะรถที่ ModelTransmissionDesc ตรงกับค่าที่ filter
AC7Filter FuelTypeแสดงเฉพาะรถที่ ModelFuelDesc ตรงกับค่าที่ filter
AC8Filter MinPrice / MaxPriceแสดงเฉพาะรถที่ pricePerDay อยู่ในช่วงที่กำหนด
AC9Filter CarGroupแสดงเฉพาะ car group ที่ระบุ
AC10CarAvailable = 0 จาก CarProรถนั้นไม่แสดง หรือแสดงว่าไม่ว่าง
AC11Promotion code ส่งมาแต่ CarPro ตอบ invalid cdpFallback ค้นหาโดยไม่ส่ง CDP; ตั้ง IsInvalidPromotionCode = true
AC12CarPro timeout/error (ไม่ใช่ invalid cdp)แสดง error ให้ลูกค้า

Business Rules

BR#Ruleตัวอย่าง
BR-C01-1Branch validation ใช้ BranchCarProSync (ไม่ใช่ Branch table โดยตรง)Branch BKK01 ต้องอยู่ใน BranchCarProSync
BR-C01-2pricePerDay = TotalAmount / SoldDays (จาก CarPro response)CarPro ส่ง 3,000 / 3 วัน → 1,000/วัน
BR-C01-3Filter Price เทียบกับ pricePerDay ไม่ใช่ totalMaxPrice 1,500 → กรองรถที่ราคา/วัน ≤ 1,500
BR-C01-4ถ้า CarPro fallback ยังล้มเหลว → throw errorไม่แสดงผลลัพธ์ที่ผิดพลาด

US-C02: ดู Price Quote

As a ลูกค้า
I want to ดูราคาสรุปรวม add-on, เชื้อเพลิง, OWR ก่อนจอง
So that ฉันเห็นราคาที่แน่นอนก่อนยืนยัน

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1ขอ quote โดยไม่มี add-onแสดงราคารถ + VAT + grand total
AC2เลือก add-on type PerCarราคา add-on = price × 1 (ไม่คูณวัน หรือจำนวนคน)
AC3เลือก add-on type PerDriverUnder21YearsOldราคา = price × จำนวน driver อายุน้อยกว่า 21
AC4เลือก add-on type PerDriverMoreThanOrEqual3 กับ 2 driverคิดราคา 1 unit (minimum 1)
AC5เลือก add-on type PerDriverMoreThanOrEqual3 กับ 4 driverคิดราคา 2 unit (driver ที่ 3 และ 4)
AC6add-on มี rate calculate = DayRateราคา = price × จำนวนวันเช่า
AC7เลือก root add-on (bundle) + ลูกทุกตัวคิดราคา root อย่างเดียว
AC8เลือก root add-on + ลูกบางตัวคิดราคา root + ลูกที่เลือก
AC9ไม่เลือก root แต่เลือกลูกคิดราคาเฉพาะลูกที่เลือก
AC10add-on มี IsMaximumRate = true และคำนวณเกินcap ที่ MaximumRate
AC11add-on มี IsIncludedItem = trueไม่คิดราคาเพิ่ม (รวมอยู่แล้ว)
AC12OWR (One-Way Rental) ต่างสาขาแสดงราคา OWR จาก OneWayRentalService

Business Rules — Add-on Pricing

BR#Ruleตัวอย่าง
BR-C02-1PerCar → คิดครั้งเดียวไม่ขึ้นกับวันหรือคนขับPDW 500 → คิด 500
BR-C02-2PerDriverUnder21YearsOld → คูณจำนวน driver อายุ < 21ราคา 200/คน, driver อายุต่ำกว่า 21 = 2 คน → 400
BR-C02-3PerDriverMoreThanOrEqual3 → คิดตั้งแต่คนที่ 3 แต่ minimum = 1 unit2 driver → คิด 1 unit; 5 driver → คิด 3 unit
BR-C02-4DayRate → คูณ daysRentalราคา 100/วัน, เช่า 3 วัน → 300
BR-C02-5OneTimeRate → คิดครั้งเดียว ไม่คูณวันค่าส่งรถ 200 → คิด 200 เสมอ
BR-C02-6Bundle: Root selected + ALL children → คิดแค่ rootRoot 500 covers ทุก child
BR-C02-7Bundle: Root selected + SOME children → คิด root + selected childrenRoot 500 + child C ที่เลือก 100 = 600
BR-C02-8Bundle: Root NOT selected → คิดแค่ selected childrenไม่มี root, child A 100 + child B 200 = 300
BR-C02-9IsSpecifyQuantity = true → ไม่คิดราคาใน calculatorInsurance specify-quantity ราคาคำนวณแยก
BR-C02-10MaximumRate capคำนวณได้ 1,500 แต่ MaximumRate = 1,000 → คิด 1,000

VAT คำนวณอย่างไร

รายการสูตรตัวอย่าง
Car VATtotalIncVAT − (totalIncVAT / 1.07)3,210 − (3,210 / 1.07) = 210
Add-on VATtotalAddonPrice × 0.07Add-on 500 × 0.07 = 35
Grand TotaltotalIncVAT + totalAddonPrice + addonVat3,210 + 500 + 35 = 3,745

US-C03: จัดการ Master Data — Car (Backoffice)

As a Staff ที่มี permission setting:car:*
I want to เพิ่ม แก้ไข และจัดการข้อมูลรถ
So that ข้อมูลรถในระบบถูกต้องและแสดงผลต่อลูกค้าได้อย่างเหมาะสม

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1เพิ่ม car ใหม่พร้อมข้อมูลครบCar ถูกบันทึกและแสดงในระบบ
AC2ปิดใช้งาน car (inactive)Car ไม่แสดงในผลการค้นหา
AC3Staff ไม่มี permissionปุ่ม action ไม่แสดง, API ตอบ 403
AC4Sync ข้อมูล car group กับ CarProCarCarProSync ถูกอัปเดต

US-C04: จัดการ Promotion/CDP (Backoffice)

As a Staff ที่มี permission setting:promotion:*
I want to จัดการโปรโมชั่น CDP
So that ลูกค้าสามารถใช้โปรโมชั่นได้ถูกต้อง

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1สร้าง promotion ที่ validPromotion ถูกบันทึก และ CDP code ส่งไป CarPro ได้
AC2Promotion หมดอายุลูกค้าใช้ promotion ไม่ได้, แสดง error IsInvalidPromotionCode
AC3CDP code ไม่ valid จาก CarProFallback ค้นหาใหม่โดยไม่ส่ง CDP
AC4Staff ไม่มี permissionAPI ตอบ 403

US-C05: จัดการ Add-on (Backoffice)

As a Staff ที่มี permission setting:add-on:*
I want to จัดการ add-on products และ pricing
So that ราคา add-on ที่ลูกค้าเห็นถูกต้อง

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1เพิ่ม add-on ที่มี PriceRateType = PerCarแสดงในหน้า booking step 3 พร้อมราคาคงที่
AC2เพิ่ม add-on ที่มี PriceRateType = PerDriverUnder21YearsOldราคาคำนวณตามจำนวน driver อายุน้อยกว่า 21
AC3ตั้ง add-on เป็น IsIncludedItem = trueไม่คิดราคาเพิ่ม (remark ว่า included)
AC4ตั้ง add-on เป็น inactiveไม่แสดงในหน้า booking
AC5กำหนด ParentId ให้ add-onadd-on เป็น child ของ parent (bundle tree)

US-C06: จัดการ Branch และ OWR (Backoffice)

As a Staff ที่มี permission setting:branch:* / setting:owr:*
I want to จัดการสาขาและราคา One-Way Rental
So that ลูกค้าเห็นสาขาที่ถูกต้องและราคา OWR ที่แม่นยำ

Acceptance Criteria

#เงื่อนไขผลลัพธ์ที่คาดหวัง
AC1Branch activeแสดงในตัวเลือกสาขาของหน้าค้นหา
AC2Branch inactiveไม่แสดงในตัวเลือก / search ไม่ได้
AC3กำหนด OWR price ระหว่างสาขา A → Bแสดงราคา OWR ในหน้า quote เมื่อ pickup ≠ return
AC4ไม่มี OWR setup ระหว่าง A → BOWR price = 0 หรือไม่แสดง

IDRuleค่า / สูตร
BR-C-01Branch validation ใช้ BranchCarProSyncต้องพบและ Active
BR-C-02pricePerDay = TotalAmount / SoldDaysจาก CarPro
BR-C-03Filter price เทียบกับ pricePerDayไม่ใช่ total
BR-C-04CDP fallback เมื่อ VarianceReason มี "invalid cdp"ค้นหาซ้ำไม่ส่ง CDP
BR-C-05Add-on PerCarราคาคงที่ × 1
BR-C-06Add-on PerDriverUnder21ราคา × จำนวน driver อายุ < 21
BR-C-07Add-on PerDriverMoreThanOrEqual3คิดตั้งแต่คนที่ 3; minimum 1 unit
BR-C-08Add-on DayRate× daysRental
BR-C-09Add-on OneTimeRate× 1
BR-C-10Bundle: Root + All childrenคิดแค่ root
BR-C-11Bundle: Root + Some childrenroot + selected
BR-C-12IsIncludedItem = trueไม่คิดราคา
BR-C-13MaximumRate capcap ที่ maximum เมื่อคำนวณเกิน
BR-C-14Car VATtotalIncVAT − (totalIncVAT / 1.07)
BR-C-15Add-on VATtotalAddon × 0.07
BR-C-16Grand totalcarIncVAT + addon + addonVAT
BR-C-17Rounding2 ตำแหน่ง MidpointRounding.AwayFromZero