Skip to content

PRD: Mẫu biên lai

ModuleCommerce (CORE-03)PRD IDPRD-RCP-001
StatusShippedOwnerCommerce squad
Date2026-06-15Versionv1.0
Packages@nx/commerce · @nx/core · apps/sale-rendererURDRCP

TL;DR

Cho phép merchant thiết kế chính xác biên lai in của mình trông ra sao - theo từng merchant hoặc từng kênh bán, và theo từng ngôn ngữ. Một mẫu là một bố cục có tên, có thứ tự dựng từ bộ khối cố định (text, line, image, bảng dòng hàng, barcode, QR, và grid cho các hàng cạnh nhau), mỗi khối gắn với dữ liệu đơn hàng trực tiếp và mang style riêng. Bố cục được kiểm tra khi lưu dựa trên bộ khối, nên một biên lai sai định dạng không bao giờ tới được máy in. Đúng một mẫu là mặc định cho mỗi ngôn ngữ theo từng merchant hoặc kênh - đặt mặc định mới sẽ tự gỡ mặc định cũ - và khi in, mẫu được chọn render thành ảnh raster đơn sắc vừa khổ giấy in nhiệt 58mm hoặc 80mm.

1. Context & Problem

Mỗi lượt bán đều kết thúc bằng một biên lai in, nhưng không phải merchant nào cũng muốn cùng một mẫu. Quán cà phê muốn logo và mã QR cho chương trình loyalty; quầy bán lẻ muốn barcode và bảng dòng hàng gọn; địa điểm đa ngôn ngữ muốn biên lai tiếng Việt ở kênh này và tiếng Anh ở kênh khác. Cố định một bố cục biên lai duy nhất ép tất cả họ dùng chung một tờ.

Không có bề mặt mẫu, merchant không thể đổi phần đầu, sắp xếp lại các phần, thêm barcode hay in sang ngôn ngữ thứ hai mà không cần can thiệp kỹ thuật. Cũng không có nơi an toàn để lưu các bố cục này: một blob tự do sẽ để lọt một biên lai sai định dạng - một cột không có field, một grid không bao giờ kết thúc - và làm kẹt máy in đúng lúc tệ nhất, giữa lúc thanh toán.

Increment này trao cho Commerce một thực thể mẫu biên lai hạng nhất: có tên, theo phạm vi merchant hoặc kênh bán, theo ngôn ngữ, dựng từ bộ khối cố định và được kiểm tra, với một mặc định cho mỗi ngôn ngữ, và render đúng ảnh raster mà máy in nhiệt mong đợi.

2. Goals & Non-Goals

Goals

  • Một mẫu biên lai có tên theo phạm vi merchant hoặc kênh bán, trong ngôn ngữ đã chọn.
  • Bố cục dựng từ một bộ khối cố định - text, line, image, bảng dòng hàng, barcode, QR, và grid cho các hàng cạnh nhau.
  • Kiểm tra bố cục ở mỗi lần lưu - một mẫu không hợp lệ với bộ khối bị từ chối trước khi lưu.
  • Một mặc định cho mỗi (principal, locale) - đặt mặc định sẽ tự gỡ mặc định trước đó cho phạm vi và ngôn ngữ đó.
  • Các khối gắn với dữ liệu đơn hàng trực tiếp (field, dòng hàng) được phân giải khi in, với định dạng số / tiền tệ / ngày theo từng field.
  • Render mẫu thành ảnh raster đơn sắc vừa khổ giấy in nhiệt 58mm hoặc 80mm.
  • Vòng đời đầy đủ - tạo, sửa, liệt kê/lọc, trạng thái (Activated / Deactivated / Archived), soft-delete - theo phạm vi merchant.

Non-Goals

  • Một trình soạn thảo WYSIWYG kéo-thả - trình dựng mẫu là một bề mặt client; PRD này đặc tả hợp đồng mẫu và việc render, không phải canvas soạn thảo.
  • Bố cục và phát hành hóa đơn điện tử / hóa đơn thuế pháp lý - hóa đơn tài khóa do Tax & Invoice chi phối, không phải các mẫu in này.
  • Lựa chọn truyền tải / driver máy in (USB, Bluetooth, mạng) - mẫu tạo ra ảnh raster; đưa nó tới thiết bị là việc của renderer.
  • Biên lai email / PDF - increment này nhắm in nhiệt.
  • Chia sẻ mẫu giữa các merchant hay một chợ mẫu toàn cục.

3. Success Metrics

Chỉ sốMục tiêu / tín hiệu
An toàn bố cụcMột bố cục sai định dạng (thiếu field, sai loại khối) bị từ chối khi lưu - không mẫu sai nào tới máy in
Toàn vẹn mặc địnhMỗi (merchant-hoặc-kênh, locale) có tối đa một mẫu mặc định tại mọi thời điểm
Bao phủ phạm viMột mẫu gắn được với merchant hoặc một kênh bán cụ thể, trong ngôn ngữ đã chọn
Độ trung thực renderMột mẫu render thành raster đúng bề rộng theo khổ giấy (58mm hoặc 80mm)
Gắn dữ liệuField đơn hàng và dòng hàng xuất hiện trên tờ in qua binding field và định dạng đã khai báo

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
Chủ / Quản lýThiết kế biên lai - thương hiệu, các phần, barcode/QR - và đặt mặc định theo từng ngôn ngữ
Người vận hành kênhCho một kênh bán cụ thể bố cục biên lai riêng
Thu ngânIn một biên lai đúng, dễ đọc khi thanh toán mà không cần cấu hình gì

Kịch bản lõi: chủ thiết kế một biên lai 80mm cho merchant - một ảnh logo, tên cửa hàng căn giữa, một đường phân tách nét đứt, một bảng dòng hàng (tên · sl · giá), một grid tổng tiền, và một mã QR gắn với mã đơn hàng. Họ đặt nó làm mặc định cho tiếng Việt. Bố cục được kiểm tra và lưu lại. Khi thanh toán, thu ngân hoàn tất; hệ thống chọn mẫu tiếng Việt mặc định của merchant, gắn field và dòng hàng của đơn vào, và render một ảnh raster đơn sắc rộng 576px để máy in nhiệt in ra. Sau đó chủ thêm một mẫu tiếng Anh cho kênh take-away và đặt nó mặc định cho tiếng Anh - mặc định tiếng Anh trước đó của kênh đó tự được gỡ.

5. User Stories

  • chủ, tôi thiết kế biên lai từ một bộ khối cố định (text, image, đường phân tách, bảng hàng, barcode, QR), để tờ in phản ánh thương hiệu mà không cần can thiệp kỹ thuật.
  • chủ, tôi đặt một biên lai mặc định cho mỗi ngôn ngữ, để thanh toán luôn chọn được một bố cục hợp lý.
  • người vận hành kênh, tôi cho một kênh bán bố cục biên lai riêng, để tờ giao hàng khác tờ dine-in.
  • chủ, tôi gắn bảng hàng và tổng tiền với dữ liệu đơn trực tiếp, để mỗi biên lai in đúng đơn thật.
  • chủ, tôi muốn một bố cục hỏng bị từ chối khi lưu, để không phát hiện sự cố tại máy in giữa lúc bán.
  • thu ngân, tôi in một biên lai đúng mà không cần thiết lập, để thanh toán chỉ một chạm.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Một mẫu biên lai có tên gắn phạm vi merchant hoặc kênh bán, trong một locale đã chọnURD-RCP-001 · URD-RCP-004
FR-2Mỗi mẫu khai báo khổ giấy (58mm hoặc 80mm) và một cỡ chữ nềnURD-RCP-002
FR-3Tên mẫu duy nhất theo (principal, locale) - cùng tên dùng lại được giữa các ngôn ngữ và nhận biết soft-deleteURD-RCP-003
FR-4Bố cục là một danh sách khối có thứ tự từ bộ cố định: text, line, image, bảng dòng hàng, barcode, QR, gridURD-RCP-006
FR-5Bố cục được kiểm tra theo bộ khối khi tạo và cập nhật; một bố cục không hợp lệ bị từ chốiURD-RCP-007
FR-6Khối text, dòng hàng, barcode, QR gắn với field đơn hàng động phân giải khi inURD-RCP-008
FR-7Bảng dòng hàng render các cột cấu hình được (field · header · width · align · format) với hàng tiêu đề tùy chọnURD-RCP-009
FR-8Một khối grid đặt các con vào cột tỉ lệ với canh / phân bố cho các hàng cạnh nhau (tối đa 5)URD-RCP-010
FR-9Các khối mang style trình bày - canh, độ đậm, biến đổi chữ, gạch, viền, màu, paddingURD-RCP-011
FR-10Giá trị số, tiền tệ, ngày định dạng theo format đã khai báo trên khối hoặc cộtURD-RCP-012
FR-11Đúng một mẫu mặc định cho mỗi (principal, locale); đặt mặc định gỡ mặc định trước đó một cách atomicURD-RCP-005
FR-12Một mẫu render thành ảnh raster đơn sắc vừa khổ giấy (58mm → 384px, 80mm → 576px)URD-RCP-013
FR-13Mẫu mang trạng thái vòng đời (Activated / Deactivated / Archived) và được soft-deleteURD-RCP-014
FR-14Mọi thao tác theo phạm vi merchant (x-merchant-id) và được kiểm soát bởi quyền mẫu biên lai; mẫu liệt kê/lọc được theo principal, locale, trạng thái, cờ mặc địnhURD-RCP-015 · URD-RCP-016

Nội dung yêu cầu đầy đủ và tiêu chí chấp nhận nằm tại Commerce URD - RCP. PRD này dẫn chiếu thay vì lặp lại.

7. Non-Functional Requirements

Lĩnh vựcYêu cầu
Toàn vẹn bố cụcBố cục được parse nghiêm ngặt theo bộ khối cố định khi lưu; một bố cục không hợp lệ bị từ chối với lý do rõ ràng, không bao giờ lưu
Nhất quán mặc địnhĐặt mặc định và gỡ mặc định trước đó cho cùng (principal, locale) diễn ra trong một transaction atomic
Tenancy & authzMọi thao tác theo phạm vi merchant (x-merchant-id); kiểm soát bởi quyền tạo / đọc / cập nhật / xóa mẫu biên lai dưới Commerce
Đa hình phạm viMột mẫu gắn merchant hoặc kênh bán qua một tham chiếu principal đa hình duy nhất
i18nMẫu theo từng locale; một merchant hoặc kênh giữ một bộ mẫu cho mỗi ngôn ngữ và một mặc định cho mỗi ngôn ngữ
Tính xác định khi renderMột mẫu + dữ liệu đơn cho ra một ảnh raster đơn sắc xác định đúng bề rộng theo khổ giấy
Soft-deleteMẫu không bị xóa vật lý; tính duy nhất của tên và mặc định chỉ xét trên các hàng còn sống

8. UX & Flows

Soạn thảo & phân giải mặc định

In khi thanh toán

Bề mặt soạn thảo (trong cài đặt máy in của apps/sale-renderer) cho phép chủ chọn phạm vi (merchant hoặc kênh) và ngôn ngữ, chọn khổ giấy, lắp các khối có thứ tự, gắn mỗi khối với field dữ liệu, xem trước tờ in render, và đánh dấu mẫu mặc định cho ngôn ngữ đó.

9. Data & Domain

Thực thểVai trò
ReceiptTemplateMột bố cục có tên, theo locale, gắn phạm vi merchant hoặc kênh bán; mang khổ giấy, cỡ chữ nền, cờ mặc định, trạng thái, và bố cục khối
Bộ khốiTập layout cố định - text, line, image, bảng dòng hàng, barcode, QR, và grid đệ quy - mỗi khối có style riêng và (nơi cần) binding dữ liệu
Tham chiếu principalLiên kết đa hình duy nhất gắn một mẫu với merchant hoặc một kênh bán

Chỉ ở mức khái niệm - bộ khối đầy đủ, binding field, và bất biến nằm trong commerce domain model. Bố cục khối được lưu dưới dạng tài liệu có cấu trúc và kiểm tra ở mỗi lần ghi.

10. Dependencies & Assumptions

Phụ thuộc vào

  • Merchant & kênh bán (MER, SC) - principal của mẫu là một trong hai; phạm vi phải tồn tại trước.
  • Permissions (Permissions) - tạo / đọc / cập nhật / xóa mẫu biên lai được kiểm soát dưới Commerce.
  • Dữ liệu đơn / sale (Orders) - các khối gắn với field đơn và dòng hàng phân giải khi in.
  • @nx/core - thực thể mẫu, bộ khối, và tiện ích render.

Giả định

  • Merchant hoặc kênh bán mà mẫu nhắm tới đã tồn tại.
  • Renderer tại điểm bán in một ảnh raster đơn sắc ra máy in nhiệt 58mm hoặc 80mm.
  • Merchant chọn một ngôn ngữ cho mỗi mẫu; một đơn mang đủ field và dòng hàng để điền vào các khối đã gắn.

11. Risks & Open Questions

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Một bố cục sai làm kẹt máy in giữa lúc bánBố cục được kiểm tra nghiêm ngặt ở mỗi lần lưu theo bộ khối; một mẫu không hợp lệ bị từ chối trước khi lưu
Hai mặc định cho cùng phạm vi và ngôn ngữĐặt mặc định gỡ một cách atomic mặc định trước đó cho (principal, locale) đó
Sai bề rộng raster trên sai máy inMẫu khai báo khổ giấy; render định cỡ raster theo nó (58mm → 384px, 80mm → 576px)
Tên của một mẫu đã gỡ chặn việc dùng lạiTính duy nhất của tên và mặc định nhận biết soft-delete - chỉ xét trên các hàng còn sống
Không đặc tả trình soạn thảo trực quan ở đâyCó chủ đích - trình dựng là một bề mặt client; PRD này cố định hợp đồng mẫu và render, không phải canvas

12. Release Plan & Launch Criteria

Khía cạnhKế hoạch
PhaseP2 - RCP trong URD feature catalog
RolloutMọi merchant; không feature flag
MigrationKhông - thực thể mới; merchant chưa có mẫu sẽ dùng tờ mặc định dựng sẵn
Launch criteriaMẫu tạo / sửa theo phạm vi merchant hoặc kênh theo từng ngôn ngữ; một bố cục sai bị từ chối khi lưu; đúng một mặc định cho mỗi (principal, locale); một mẫu render thành raster đúng bề rộng và in khi thanh toán với dữ liệu đơn đã gắn
MonitoringTỉ lệ từ chối khi lưu theo lý do (bố cục không hợp lệ), số lần xung đột mặc định, lỗi render theo merchant

13. FAQ

Mỗi kênh bán có biên lai riêng được không? Có - một mẫu gắn phạm vi merchant hoặc một kênh bán cụ thể, nên kênh giao hàng in được tờ khác với dine-in.

Ngôn ngữ hoạt động ra sao? Mẫu theo từng locale. Một merchant hoặc kênh giữ một mẫu cho mỗi ngôn ngữ và một mặc định cho mỗi ngôn ngữ; thanh toán chọn mặc định theo ngôn ngữ của đơn.

Nếu bố cục của tôi bị hỏng thì sao? Nó bị từ chối khi bạn lưu - bố cục được kiểm tra theo bộ khối cố định, nên một cột thiếu field hay một loại khối lạ bị bắt trước khi có thể tới máy in.

Tôi có hai biên lai mặc định được không? Không cho cùng phạm vi và ngôn ngữ - đánh dấu một mẫu mặc định tự gỡ mặc định trước đó cho merchant-hoặc-kênh và locale đó.

Tôi đặt được gì lên biên lai? Text, đường phân tách (line), một ảnh (ví dụ logo), một bảng dòng hàng với cột cấu hình được, một barcode, một mã QR, và một grid cho các hàng cạnh nhau - mỗi thứ có canh, style, và binding dữ liệu riêng.

Cái này in hóa đơn thuế pháp lý chứ? Không - hóa đơn điện tử tài khóa do Tax & Invoice chi phối. Các mẫu này dành cho biên lai bán hàng in ra.

References

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.