Vận hành chung

Phương thức thanh toán

Xem bản Markdown

Danh mục dùng chung cho mọi sản phẩm: khai các phương thức thanh toán của tổ chức (tiền mặt, chuyển khoản, thẻ, ví điện tử...) một chỗ, các màn thu tiền chỉ việc chọn.

Khai phương thức

Mỗi phương thức gồm tên tự đặt, loại chuẩn hoá và thứ tự hiển thị. Tên là chữ khách thấy trên màn thu tiền (ví dụ "Chuyển khoản VCB"), còn loại giúp báo cáo gom đúng bản chất dòng tiền dù tên đặt kiểu gì. Phương thức tắt hoạt động sẽ không hiện ở màn thu tiền nhưng chứng từ cũ đã thu bằng phương thức đó vẫn giữ nguyên.

Ghi chú cho dev sản phẩm khi nối

Bảng saas_payment_methods chỉ là danh mục theo công ty; giao dịch của sản phẩm trỏ mềm payment_method_id vào đây, không khoá ngoại. Lấy danh sách cho màn thu tiền qua scope PaymentMethod::activeForCompany($companyId). Nhóm menu đổi qua filter saas_payment_method_navigation_group. Phần riêng từng sản phẩm (chi nhánh áp dụng, cấu hình cổng thanh toán online) ở lại gói chức năng sản phẩm.

Công ty vừa lập thì gọi PaymentMethod::seedDefaultsFor($companyId) để có sẵn hai dòng Tiền mặt và Chuyển khoản. Gọi lại nhiều lần không sinh dòng trùng, và không đụng tới phương thức công ty đã tự sửa.

Phiếu thu và loại phiếu

Model chứng từ nào nhận tiền thì gắn trait ReceivesPayments. Mỗi lần khách trả là một dòng trong saas_payments, cột kind cho biết đó là loại nào:

Giá trị Nghĩa Ảnh hưởng tới số đã thu
payment khách trả tiền, đây là mặc định cộng vào
deposit đặt cọc trước cộng vào, và đếm riêng qua getDepositAmount()
refund trả lại tiền cho khách trừ ra

Số tiền luôn ghi số dương, dấu nằm ở loại phiếu. getPaidAmount() đã tự trừ phần hoàn nên sản phẩm không phải nhớ trừ.

Cột amount là số nguyên không âm, đây là quyết định chứ không phải sót. Sổ tiền chỉ nhận số dương, chiều tiền do loại phiếu nói. Gặp dữ liệu cũ có chứng từ mang số âm, ví dụ hoá đơn nhập từ phần mềm khác, thì đừng đổi kiểu cột: dựng lại thành phiếu refund số dương, hoặc để sản phẩm xử bằng chứng từ ghi có của mình rồi mới ghi phiếu thu sang đây. Ghi thẳng số âm là cơ sở dữ liệu chối, và nó chối đúng.

Sản phẩm nào từ trước đã có ô khai tài khoản ngân hàng riêng thì để tài khoản khai ở đây đè lên ô cũ, ô cũ chỉ còn là đường lùi cho công ty chưa bật gói. Hai chỗ khai lệch nhau là khách chuyển vào một nơi còn cổng ngồi soi nơi khác: tiền về thật mà sổ vẫn báo chưa thu.

Cột kind là chuỗi trần, cố ý không đúc sang enum, vì gói dùng chung không biết trước sản phẩm nào cần thêm loại nào. Sản phẩm nào trước đây đúc enum ở bảng riêng thì phải so bằng chuỗi khi chuyển sang đây: whereIn('kind', [PaymentKind::Deposit]) không khớp dòng nào và tiền cọc đọc ra bằng không, trong khi không có lỗi nào báo. Dùng hằng số Payment::KIND_DEPOSIT cho chắc.

Số tiền có dấu đọc bằng thuộc tính $payment->signed_amount, không phải hàm.

seedDefaultsFor() đặt tên phương thức theo ngôn ngữ đang dùng, nên chỗ nào cần tra lại thì tra theo type (PaymentMethod::TYPE_CASH, TYPE_BANK_TRANSFER), đừng tra theo tên.

Đừng ném lỗi trong hook creating của Payment. Khi tiền về từ cổng, phiếu thu được ghi bên trong một giao dịch cơ sở dữ liệu, nên ném lỗi ở đó là huỷ cả lượt ghi nhận và đồng tiền ấy rơi ra ngoài sổ trong khi nhà cung cấp vẫn gọi lại. Muốn chặn thu lố hay chặn chứng từ đã huỷ thì chặn ở phiếu ghi tay, còn đường tự động cứ để tiền vào sổ rồi xếp vào mục chưa khớp.

Phiếu ghi tay mà bên gọi quên created_by thì gói tự điền người đang đăng nhập, vì chứng từ tiền phải có người lập; phiếu cổng tự ghi thì để trống.

Sổ Khoản thu chỉ lấy chứng từ tiền vào

Màn Thanh toán › Khoản thu là sổ phiếu thu của công ty. Bảng saas_payments chở cả tiền mình trả người khác (cọc đơn mua trả nhà cung cấp) cùng loại phiếu payment, deposit, nên sổ chỉ lấy phiếu gắn loại chứng từ đã khai tiền vào qua móc saas_payment_payable_types:

add_filter('saas_payment_payable_types', fn (array $types) => $types + [
    (new Invoice)->getMorphClass() => [
        'label' => __('Invoice'),
        'direction' => 'in',
        'number' => fn (Invoice $doc): ?string => $doc->number,
        'number_column' => 'number',
        'party' => fn (Invoice $doc): ?string => $doc->customer?->name,
        'path' => fn (Invoice $doc): ?string => '/app/' . $doc->company_id . '/invoices/' . $doc->getKey(),
    ],
]);
  • Không ghi direction thì coi là tiền vào; ghi out là tiền ra, không vào sổ.
  • Loại chưa khai thì phiếu không vào sổ, ô số, tệp xuất, cả sổ ở panel. Thà vắng một phiếu (khai là về) còn hơn cộng tiền trả nhà cung cấp thành tiền thu.
  • Khai ở gói giữ lớp của tờ, đừng khai ở gói vệ tinh: gói tắt thì lời khai tắt theo, phiếu của loại ấy vắng khỏi sổ.
  • Tự cộng tiền trên saas_payments thì lọc payable_type hoặc đi qua scope Payment::onIncomingDocuments(); cộng trần cả bảng là tiền trả nhà cung cấp bị đếm thành tiền bán.

Ô tìm của sổ nhận cả số tờ và tên bên kia

Gõ số chứng từ vào ô tìm của sổ Khoản thu hay Phiếu chi là ra mọi phiếu gắn tờ ấy: gõ HD-0120 ra bốn phiếu của hoá đơn đó, gõ số đơn mua ra các phiếu chi của đơn. Gõ tên khách hàng hay tên nhà cung cấp cũng ra phiếu của các tờ mang tên ấy. Ô tìm vẫn nhận số phiếu và mã giao dịch như trước.

  • Số hiệu tờ đọc ở cột number_column của bảng gốc, mặc định là number; bảng nào đặt tên cột khác thì khai lại trong lời khai loại chứng từ.
  • Tên bên kia đọc qua party_relation (quan hệ tới khách hàng hay nhà cung cấp) và cột party_name_column, mặc định name. Không khai quan hệ thì sổ chỉ tìm theo số tờ.
  • Bên kia đã xoá mềm vẫn tìm ra, vì cột Khách hoặc người nộp của sổ vẫn bày tên họ.
  • Loại chứng từ chưa nạp lớp (gói đang tắt), bảng không có cột ấy hay không có quan hệ ấy thì phần đó vắng khỏi phép tìm, sổ vẫn chạy bình thường.

Số phiếu và tờ in theo chiều tiền

  • Phiếu gắn chứng từ tiền vào đi dãy PT (payment). Phiếu gắn chứng từ khai out (đơn mua trả nhà cung cấp) đi dãy PC chung với phiếu chi của gói Chi phí (expense), chủ sản phẩm chốt 15/09/2026. Loại chưa khai vẫn đi dãy PT, nên sản phẩm muốn phiếu trả nhà cung cấp mang số PC thì phải khai loại tờ của mình với direction out. Phiếu đã có số giữ nguyên số cũ.
  • Ba loại phiếu của một chiều vẫn đi chung một dãy: tiền trả, tiền cọc, trả lại.
  • Tờ in theo chiều tiền thật ($payment->paysOut()): tiền rời công ty in phiếu chi mẫu 02-TT (trả nhà cung cấp, trả lại tiền khách), tiền vào in phiếu thu mẫu 01-TT (khách trả, nhà cung cấp trả lại tiền).

Phân quyền

Nhóm quyền Phương thức thanh toán cấp cho vai trò Quản lý khi tạo tổ chức mới; tổ chức có sẵn thì chủ tổ chức vào Phân quyền tự tick.

Tài khoản nhận tiền

Màn Tài khoản nhận tiền giữ các tài khoản ngân hàng công ty dùng để nhận tiền của khách. Nó phục vụ việc in thông tin chuyển khoản lên hoá đơn, sinh mã QR chuyển khoản, và về sau là đối chiếu tiền vào khi bật cổng thanh toán tự động.

Ngân hàng chọn từ danh mục dùng chung, không gõ tay. Hệ nhận diện ngân hàng bằng mã BIN nên ngân hàng có đổi tên thì tài khoản của bạn vẫn trỏ đúng chỗ.

  • Số tài khoản: chỉ gồm chữ cái và chữ số, không có khoảng trắng, vì thư báo tiền về của ngân hàng cũng ghi liền như vậy, để lệch một dấu cách là đối chiếu trượt.
  • Chủ tài khoản: ghi đúng như ngân hàng hiển thị, viết không dấu.
  • Tên gọi: đặt cho dễ phân biệt khi có nhiều tài khoản, thường là tên chi nhánh.
  • Tài khoản mặc định: dùng khi chứng từ không chỉ định tài khoản nào. Mỗi công ty chỉ có một tài khoản mặc định, đặt cái mới là cái cũ tự nhường chỗ.

Công ty nhiều chi nhánh khai mỗi nơi một tài khoản đều được, không giới hạn số lượng.

Tài khoản đã xoá vẫn nằm trong thùng rác nên phiếu thu cũ không mất dấu vết; muốn ẩn khỏi màn thu tiền mà giữ nguyên dữ liệu thì tắt Đang hoạt động.

Mục tài liệu