mirror of
https://github.com/System-End/theseus.git
synced 2026-04-19 18:45:15 +00:00
281 lines
8.3 KiB
Ruby
281 lines
8.3 KiB
Ruby
class LettersController < ApplicationController
|
|
before_action :set_letter, except: %i[ index new create ]
|
|
|
|
# GET /letters
|
|
def index
|
|
authorize Letter
|
|
# Get all letters with their associations using policy scope
|
|
@all_letters = policy_scope(Letter).includes(:batch, :address, :usps_mailer_id, :label_attachment, :label_blob)
|
|
.where.not(aasm_state: "queued")
|
|
.order(created_at: :desc)
|
|
|
|
# Get unbatched letters with pagination
|
|
@unbatched_letters = @all_letters.not_in_batch.page(params[:page]).per(20)
|
|
|
|
# Get batched letters grouped by batch
|
|
@batched_letters = @all_letters.in_batch.group_by(&:batch)
|
|
end
|
|
|
|
# GET /letters/1
|
|
def show
|
|
authorize @letter
|
|
@available_templates = SnailMail::PhlexService.available_templates
|
|
end
|
|
|
|
# GET /letters/new
|
|
def new
|
|
authorize Letter
|
|
@letter = Letter.new
|
|
@letter.return_address = current_user.home_return_address || ReturnAddress.first
|
|
@letter.build_address
|
|
end
|
|
|
|
# GET /letters/1/edit
|
|
def edit
|
|
authorize @letter
|
|
# If letter doesn't have a return address already, don't build one
|
|
# Let the user select one from the dropdown
|
|
end
|
|
|
|
# POST /letters
|
|
def create
|
|
@letter = Letter.new(letter_params.merge(user: current_user))
|
|
authorize @letter
|
|
|
|
# Set postage type to international_origin if return address is not US
|
|
if @letter.return_address && @letter.return_address.country != "US"
|
|
@letter.postage_type = "international_origin"
|
|
end
|
|
|
|
if @letter.save
|
|
redirect_to @letter, notice: "Letter was successfully created."
|
|
else
|
|
render :new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
# PATCH/PUT /letters/1
|
|
def update
|
|
authorize @letter
|
|
|
|
if @letter.batch_id.present? && params[:letter][:postage_type].present?
|
|
redirect_to @letter, alert: "Cannot change postage type for a letter that is part of a batch."
|
|
return
|
|
end
|
|
|
|
# Set postage type to international_origin if return address is not US
|
|
if params[:letter][:return_address_id].present?
|
|
return_address = ReturnAddress.find(params[:letter][:return_address_id])
|
|
if return_address.country != "US"
|
|
params[:letter][:postage_type] = "international_origin"
|
|
end
|
|
end
|
|
|
|
if @letter.update(letter_params)
|
|
redirect_to @letter, notice: "Letter was successfully updated."
|
|
else
|
|
render :edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
# DELETE /letters/1
|
|
def destroy
|
|
authorize @letter
|
|
@letter.destroy!
|
|
redirect_to letters_path, status: :see_other, notice: "Letter was successfully destroyed."
|
|
end
|
|
|
|
# POST /letters/1/generate_label
|
|
def generate_label
|
|
authorize @letter, :generate_label?
|
|
template = params[:template]
|
|
include_qr_code = params[:qr].present?
|
|
|
|
# Generate label with specified template
|
|
begin
|
|
# Let the model method handle saving itself
|
|
if @letter.generate_label(template:, include_qr_code:)
|
|
if @letter.label.attached?
|
|
# Redirect back to the letter page with a success message
|
|
redirect_to @letter, notice: "Label was successfully generated."
|
|
else
|
|
redirect_to @letter, alert: "Failed to generate label."
|
|
end
|
|
else
|
|
redirect_to @letter, alert: "Failed to generate label: #{@letter.errors.full_messages.join(", ")}"
|
|
end
|
|
rescue => e
|
|
raise
|
|
redirect_to @letter, alert: "Error generating label: #{e.message}"
|
|
end
|
|
end
|
|
|
|
def preview_template
|
|
authorize @letter, :preview_template?
|
|
template = params["template"]
|
|
include_qr_code = params["qr"].present?
|
|
preview_mode = params["preview_mode"].present?
|
|
send_data SnailMail::PhlexService.generate_label(@letter, { template:, include_qr_code:, preview_mode: }).render, type: "application/pdf", disposition: "inline"
|
|
end
|
|
|
|
# POST /letters/1/mark_printed
|
|
def mark_printed
|
|
authorize @letter, :mark_printed?
|
|
if @letter.mark_printed!
|
|
redirect_to @letter, notice: "Letter has been marked as printed."
|
|
else
|
|
redirect_to @letter, alert: "Could not mark letter as printed: #{@letter.errors.full_messages.join(", ")}"
|
|
end
|
|
end
|
|
|
|
# POST /letters/1/mark_mailed
|
|
def mark_mailed
|
|
authorize @letter, :mark_mailed?
|
|
if @letter.mark_mailed!
|
|
User::UpdateTasksJob.perform_later(current_user)
|
|
redirect_to @letter, notice: "Letter has been marked as mailed."
|
|
else
|
|
redirect_to @letter, alert: "Could not mark letter as mailed: #{@letter.errors.full_messages.join(", ")}"
|
|
end
|
|
end
|
|
|
|
# POST /letters/1/mark_received
|
|
def mark_received
|
|
authorize @letter, :mark_received?
|
|
if @letter.mark_received!
|
|
redirect_to @letter, notice: "Letter has been marked as received."
|
|
else
|
|
redirect_to @letter, alert: "Could not mark letter as received: #{@letter.errors.full_messages.join(", ")}"
|
|
end
|
|
end
|
|
|
|
# POST /letters/1/clear_label
|
|
def clear_label
|
|
authorize @letter, :clear_label?
|
|
if @letter.pending? && @letter.label.attached?
|
|
@letter.label.purge
|
|
redirect_to @letter, notice: "Label has been cleared."
|
|
else
|
|
redirect_to @letter, alert: "Cannot clear label: Letter is not in pending state or has no label attached."
|
|
end
|
|
end
|
|
|
|
# POST /letters/1/buy_indicia
|
|
def buy_indicia
|
|
authorize @letter, :buy_indicia?
|
|
if @letter.batch_id.present?
|
|
redirect_to @letter, alert: "Cannot buy indicia for a letter that is part of a batch."
|
|
return
|
|
end
|
|
|
|
if @letter.postage_type != "indicia"
|
|
redirect_to @letter, alert: "Letter must be set to indicia postage type first."
|
|
return
|
|
end
|
|
|
|
if @letter.usps_indicium.present?
|
|
redirect_to @letter, alert: "Indicia already purchased for this letter."
|
|
return
|
|
end
|
|
|
|
usps_payment_account = USPS::PaymentAccount.find_by(id: params[:usps_payment_account_id])
|
|
if usps_payment_account.nil?
|
|
redirect_to @letter, alert: "Please select a valid USPS payment account."
|
|
return
|
|
end
|
|
|
|
hcb_payment_account = current_user.hcb_payment_accounts.find_by(id: params[:hcb_payment_account_id])
|
|
|
|
if hcb_payment_account.blank?
|
|
redirect_to @letter, alert: "You must select an HCB payment account to purchase indicia."
|
|
return
|
|
end
|
|
|
|
indicium = USPS::Indicium.create!(
|
|
letter: @letter,
|
|
payment_account: usps_payment_account,
|
|
hcb_payment_account: hcb_payment_account,
|
|
)
|
|
cost_cents = (@letter.postage * 100).ceil
|
|
|
|
transfer_service = HCB::TransferService.new(
|
|
hcb_payment_account: hcb_payment_account,
|
|
amount_cents: cost_cents,
|
|
name: "Postage for #{@letter.public_id} #{indicium.public_id} #{letter_path(@letter)}",
|
|
memo: "[theseus] postage for a #{@letter.processing_category}",
|
|
)
|
|
transfer = transfer_service.call
|
|
|
|
unless transfer
|
|
indicium.destroy!
|
|
redirect_to @letter, alert: transfer_service.errors.join(", ")
|
|
return
|
|
end
|
|
|
|
indicium.update!(hcb_transfer_id: transfer.id)
|
|
|
|
begin
|
|
indicium.buy!
|
|
rescue => e
|
|
HCB::PaymentAccount.refund_to_organization!(
|
|
organization_id: hcb_payment_account.organization_id,
|
|
amount_cents: cost_cents,
|
|
name: "Refund for #{@letter.public_id} #{indicium.public_id} #{letter_path(@letter)}",
|
|
memo: "[theseus] postage refund for a #{@letter.processing_category}",
|
|
)
|
|
redirect_to @letter, alert: "Purchase failed: #{e.message}"
|
|
return
|
|
end
|
|
|
|
redirect_to @letter, notice: "Indicia purchased successfully (charged to #{hcb_payment_account.organization_name})."
|
|
end
|
|
|
|
private
|
|
|
|
# Use callbacks to share common setup or constraints between actions.
|
|
def set_letter
|
|
@letter = Letter.find_by_public_id!(params[:id])
|
|
end
|
|
|
|
# Only allow a list of trusted parameters through.
|
|
def letter_params
|
|
params.require(:letter).permit(
|
|
:body,
|
|
:height,
|
|
:width,
|
|
:weight,
|
|
:non_machinable,
|
|
:processing_category,
|
|
:postage_type,
|
|
:mailing_date,
|
|
:rubber_stamps,
|
|
:user_facing_title,
|
|
:usps_mailer_id_id,
|
|
:return_address_id,
|
|
:return_address_name,
|
|
:recipient_email,
|
|
address_attributes: [
|
|
:id,
|
|
:first_name,
|
|
:last_name,
|
|
:line_1,
|
|
:line_2,
|
|
:city,
|
|
:state,
|
|
:postal_code,
|
|
:country,
|
|
],
|
|
return_address_attributes: [
|
|
:id,
|
|
:name,
|
|
:line_1,
|
|
:line_2,
|
|
:city,
|
|
:state,
|
|
:postal_code,
|
|
:country,
|
|
],
|
|
tags: [],
|
|
)
|
|
end
|
|
end
|