feat(lifecycle): wire Captain::Reservation lifecycle hooks
Add after_commit callbacks to call Captain::Lifecycle::Scheduler on create, status change (cancelled/no_show), and check_in_at change. Each handler wraps in rescue StandardError to preserve existing behavior. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bb4631f427
commit
8e0a06246b
@ -90,6 +90,9 @@ class Captain::Reservation < ApplicationRecord
|
||||
after_commit :sync_conversation_marker_snapshot
|
||||
after_create_commit :update_contact_reservation_metadata
|
||||
after_create_commit :post_internal_reservation_note
|
||||
after_create_commit :schedule_lifecycle_rules
|
||||
after_update_commit :handle_lifecycle_status_change, if: :saved_change_to_status?
|
||||
after_update_commit :handle_lifecycle_checkin_change, if: :saved_change_to_check_in_at?
|
||||
|
||||
def ui_status
|
||||
Captain::Reservations::MarkerBuilder.ui_status(status)
|
||||
@ -160,6 +163,26 @@ class Captain::Reservation < ApplicationRecord
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
||||
|
||||
def schedule_lifecycle_rules
|
||||
Captain::Lifecycle::Scheduler.schedule_for(self)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[Lifecycle] schedule_for failed for reservation #{id}: #{e.class} #{e.message}")
|
||||
end
|
||||
|
||||
def handle_lifecycle_status_change
|
||||
return unless %w[cancelled no_show].include?(status.to_s)
|
||||
|
||||
Captain::Lifecycle::Scheduler.cancel_pending(self)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[Lifecycle] cancel_pending failed for reservation #{id}: #{e.class} #{e.message}")
|
||||
end
|
||||
|
||||
def handle_lifecycle_checkin_change
|
||||
Captain::Lifecycle::Scheduler.reschedule_for_checkin_change(self)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[Lifecycle] reschedule failed for reservation #{id}: #{e.class} #{e.message}")
|
||||
end
|
||||
|
||||
# Atualiza campos visiveis no painel lateral do Chatwoot (custom_attributes)
|
||||
# pra que a recepcionista veja num relance:
|
||||
# ultima_suite, ultima_permanencia, ultima_reserva_em, total_reservas
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Captain::Reservation, '#lifecycle_hooks' do
|
||||
let(:account) { create(:account) }
|
||||
let(:brand) { create(:captain_brand, account: account) }
|
||||
let(:unit) { Captain::Unit.create!(account: account, name: 'Test', brand: brand) }
|
||||
|
||||
describe 'after create' do
|
||||
it 'calls Scheduler.schedule_for' do
|
||||
expect(Captain::Lifecycle::Scheduler).to receive(:schedule_for).with(kind_of(described_class))
|
||||
create(:captain_reservation,
|
||||
account: account, unit: unit,
|
||||
check_in_at: 2.hours.from_now, check_out_at: 10.hours.from_now)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'after update (status → cancelled)' do
|
||||
let(:reservation) do
|
||||
allow(Captain::Lifecycle::Scheduler).to receive(:schedule_for)
|
||||
create(:captain_reservation,
|
||||
account: account, unit: unit,
|
||||
check_in_at: 2.hours.from_now, check_out_at: 10.hours.from_now)
|
||||
end
|
||||
|
||||
it 'cancels pending deliveries' do
|
||||
expect(Captain::Lifecycle::Scheduler).to receive(:cancel_pending).with(reservation)
|
||||
reservation.update!(status: 'cancelled')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'after update (check_in_at changed)' do
|
||||
let(:reservation) do
|
||||
allow(Captain::Lifecycle::Scheduler).to receive(:schedule_for)
|
||||
create(:captain_reservation,
|
||||
account: account, unit: unit,
|
||||
check_in_at: 2.hours.from_now, check_out_at: 10.hours.from_now)
|
||||
end
|
||||
|
||||
it 'reschedules checkin-based deliveries' do
|
||||
expect(Captain::Lifecycle::Scheduler).to receive(:reschedule_for_checkin_change).with(reservation)
|
||||
reservation.update!(check_in_at: 3.hours.from_now)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user