module Pay module Receipts def product Pay.application_name end def receipt_filename "receipt-#{created_at.strftime("%Y-%m-%d")}.pdf" end alias_method :filename, :receipt_filename def receipt receipt_pdf.render end def receipt_details [ [I18n.t("pay.receipt.number"), receipt_number], [I18n.t("pay.receipt.date"), I18n.l(created_at, format: :long)], [I18n.t("pay.receipt.payment_method"), charged_to] ] end def pdf_line_items items = [ [ "#{I18n.t("pay.line_items.description")}", "#{I18n.t("pay.line_items.quantity")}", "#{I18n.t("pay.line_items.unit_price")}", "#{I18n.t("pay.line_items.amount")}" ] ] # Unit price is stored with the line item # Negative amounts shouldn't display quantity # Sort by line_items by period_end? oldest to newest if line_items.any? line_items.each do |li| items << [li["description"], li["quantity"], Pay::Currency.format(li["unit_amount"], currency: currency), Pay::Currency.format(li["amount"], currency: currency)] Array.wrap(li["discounts"]).each do |discount_id| if (discount = total_discount_amounts.find { |d| d.dig("discount", "id") == discount_id }) items << [discount_description(discount), nil, nil, Pay::Currency.format(-discount["amount"], currency: currency)] end end end else items << [product, 1, Pay::Currency.format(amount, currency: currency), Pay::Currency.format(amount, currency: currency)] end # If no subtotal, we will display the total items << [nil, nil, I18n.t("pay.line_items.subtotal"), Pay::Currency.format(subtotal || amount, currency: currency)] # Discounts on the invoice Array.wrap(discounts).each do |discount_id| if (discount = total_discount_amounts.find { |d| d.dig("discount", "id") == discount_id }) items << [nil, nil, discount_description(discount), Pay::Currency.format(-discount["amount"], currency: currency)] end end # Tax rates Array.wrap(total_tax_amounts).each do |tax_amount| next if tax_amount["amount"].zero? items << [nil, nil, tax_description(tax_amount), Pay::Currency.format(tax_amount["amount"], currency: currency)] end items << [nil, nil, I18n.t("pay.line_items.total"), Pay::Currency.format(amount, currency: currency)] items end def discount_description(discount) coupon = discount.dig("discount", "coupon") name = coupon.dig("name") if (percent = coupon["percent_off"]) I18n.t("pay.line_items.percent_discount", name: name, percent: ActiveSupport::NumberHelper.number_to_rounded(percent, strip_insignificant_zeros: true)) else I18n.t("pay.line_items.amount_discount", name: name, amount: Pay::Currency.format(coupon["amount_off"], currency: coupon["currency"])) end end def tax_description(tax_amount) tax_rate = tax_amount["tax_rate"] percent = "#{ActiveSupport::NumberHelper.number_to_rounded(tax_rate["percentage"], strip_insignificant_zeros: true)}%" percent += " inclusive" if tax_rate["inclusive"] "#{tax_rate["display_name"]} - #{tax_rate["jurisdiction"]} (#{percent})" end def receipt_line_items line_items = pdf_line_items # Include total paid line_items << [nil, nil, I18n.t("pay.receipt.amount_paid"), Pay::Currency.format(amount, currency: currency)] if refunded? # If we have a list of individual refunds, add each entry if refunds&.any? refunds.each do |refund| next unless refund["status"] == "succeeded" refunded_at = Time.at(refund["created"]).to_date line_items << [nil, nil, I18n.t("pay.receipt.refunded_on", date: I18n.l(refunded_at, format: :long)), Pay::Currency.format(refund["amount"], currency: refund["currency"])] end else line_items << [nil, nil, I18n.t("pay.receipt.refunded"), Pay::Currency.format(amount_refunded, currency: currency)] end end line_items end def receipt_pdf(**options) defaults = { details: receipt_details, recipient: [ customer.customer_name, customer.email, customer.owner.try(:extra_billing_info) ], company: { name: Pay.business_name, address: Pay.business_address, email: Pay.support_email.address, logo: Pay.business_logo }, line_items: receipt_line_items } ::Receipts::Receipt.new(defaults.deep_merge(options)) end def invoice_filename "invoice-#{created_at.strftime("%Y-%m-%d")}.pdf" end def invoice invoice_pdf.render end def invoice_details [ [I18n.t("pay.invoice.number"), invoice_number], [I18n.t("pay.invoice.date"), I18n.l(created_at, format: :long)], [I18n.t("pay.invoice.payment_method"), charged_to] ] end def invoice_pdf(**options) defaults = { details: invoice_details, recipient: [ customer.customer_name, customer.email, customer.owner.try(:extra_billing_info) ], company: { name: Pay.business_name, address: Pay.business_address, email: Pay.support_email.address, logo: Pay.business_logo }, line_items: pdf_line_items } ::Receipts::Invoice.new(defaults.deep_merge(options)) end def invoice_number id end def receipt_number invoice_number end end end