feat: implementa POST create (contact + conversa + reserva + pix) e GET status
This commit is contained in:
parent
e9a5e734ff
commit
5ff3a70474
@ -5,12 +5,104 @@
|
||||
class Public::Api::V1::Captain::PublicReservationsController < ActionController::API
|
||||
before_action :authenticate_reserva_token!
|
||||
|
||||
def create
|
||||
render json: { error: 'not_implemented' }, status: :not_implemented
|
||||
def create # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
||||
unit = Captain::Unit.find_by(id: params[:chatwoot_unit_id])
|
||||
return render(json: { error: 'unit_not_found' }, status: :not_found) if unit.nil?
|
||||
return render(json: { error: 'unit_has_no_inbox' }, status: :unprocessable_entity) if unit.inbox_id.blank?
|
||||
return render(json: { error: 'unit_missing_inter_credentials' }, status: :unprocessable_entity) unless unit.inter_credentials_present?
|
||||
|
||||
customer = params[:customer] || {}
|
||||
return render(json: { error: 'customer_required' }, status: :unprocessable_entity) if customer[:name].blank?
|
||||
|
||||
account = unit.account
|
||||
inbox = Inbox.find(unit.inbox_id)
|
||||
|
||||
contact_inbox = ::ContactInboxWithContactBuilder.new(
|
||||
source_id: "reserva1001-#{SecureRandom.uuid}",
|
||||
inbox: inbox,
|
||||
contact_attributes: {
|
||||
name: customer[:name],
|
||||
phone_number: customer[:phone].presence,
|
||||
email: customer[:email].presence,
|
||||
additional_attributes: {
|
||||
cpf: customer[:cpf].presence,
|
||||
origem: 'reserva-1001'
|
||||
}.compact
|
||||
}
|
||||
).perform
|
||||
|
||||
conversation = ConversationBuilder.new(
|
||||
params: ActionController::Parameters.new(
|
||||
additional_attributes: {
|
||||
source: 'reserva-1001',
|
||||
reserva_category: params[:category],
|
||||
reserva_stay_type: params[:stay_type],
|
||||
reserva_checkin_at: params[:checkin_at]
|
||||
}
|
||||
),
|
||||
contact_inbox: contact_inbox
|
||||
).perform
|
||||
|
||||
initial_note = build_initial_note(params)
|
||||
|
||||
Messages::MessageBuilder.new(
|
||||
nil,
|
||||
conversation,
|
||||
{ content: initial_note, message_type: 'outgoing', private: true }
|
||||
).perform
|
||||
|
||||
reservation = Captain::Reservation.create!(
|
||||
account: account,
|
||||
inbox: inbox,
|
||||
contact: contact_inbox.contact,
|
||||
contact_inbox: contact_inbox,
|
||||
conversation: conversation,
|
||||
unit: unit,
|
||||
suite_identifier: "#{params[:category]} · #{params[:stay_type]}",
|
||||
check_in_at: params[:checkin_at],
|
||||
check_out_at: checkout_from(params[:checkin_at], params[:stay_type]),
|
||||
status: :draft,
|
||||
payment_status: 'pending',
|
||||
total_amount: (params[:total_cents].to_i / 100.0),
|
||||
metadata: {
|
||||
origem: 'reserva-1001',
|
||||
category: params[:category],
|
||||
stay_type: params[:stay_type],
|
||||
deposit_cents: params[:deposit_cents].to_i,
|
||||
notes: params[:notes]
|
||||
}
|
||||
)
|
||||
|
||||
deposit_amount = (params[:deposit_cents].to_i / 100.0)
|
||||
charge = Captain::Inter::CobService.new(reservation, amount: deposit_amount).call
|
||||
reservation.update!(status: :pending_payment)
|
||||
|
||||
render json: {
|
||||
reservation_id: reservation.id,
|
||||
conversation_id: conversation.id,
|
||||
pix: {
|
||||
txid: charge.txid,
|
||||
copia_e_cola: charge.pix_copia_e_cola,
|
||||
qrcode_base64: nil,
|
||||
expires_at: (Time.current + Captain::PixCharge::EXPIRATION_SECONDS.seconds).iso8601
|
||||
}
|
||||
}, status: :created
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
Rails.logger.error("[PublicReservations] validation error: #{e.message}")
|
||||
render json: { error: 'validation_failed', details: e.record.errors.full_messages }, status: :unprocessable_entity
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[PublicReservations] unexpected error: #{e.class} - #{e.message}")
|
||||
render json: { error: 'internal_error', message: e.message }, status: :internal_server_error
|
||||
end
|
||||
|
||||
def status
|
||||
render json: { error: 'not_implemented' }, status: :not_implemented
|
||||
reservation = Captain::Reservation.find_by(id: params[:id])
|
||||
return render(json: { error: 'not_found' }, status: :not_found) if reservation.nil?
|
||||
|
||||
render json: {
|
||||
reservation_id: reservation.id,
|
||||
status: reservation.payment_status
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
@ -28,4 +120,28 @@ class Public::Api::V1::Captain::PublicReservationsController < ActionController:
|
||||
|
||||
render json: { error: 'unauthorized' }, status: :unauthorized
|
||||
end
|
||||
|
||||
def build_initial_note(payload)
|
||||
<<~NOTE.strip
|
||||
Nova reserva via reserva.1001
|
||||
Categoria: #{payload[:category]}
|
||||
Permanencia: #{payload[:stay_type]}
|
||||
Check-in: #{payload[:checkin_at]}
|
||||
Total: R$ #{format('%.2f', payload[:total_cents].to_i / 100.0)}
|
||||
Entrada (PIX 50%): R$ #{format('%.2f', payload[:deposit_cents].to_i / 100.0)}
|
||||
Observacao: #{payload[:notes].presence || '-'}
|
||||
NOTE
|
||||
end
|
||||
|
||||
def checkout_from(checkin_iso, stay_type)
|
||||
checkin = Time.zone.parse(checkin_iso.to_s)
|
||||
hours = case stay_type.to_s.downcase
|
||||
when '2hrs' then 2
|
||||
when '3hrs' then 3
|
||||
when 'pernoite' then 12
|
||||
when 'diaria', 'diária' then 24
|
||||
else 4 # default: 4hrs (inclui '4hrs' e qualquer outro valor)
|
||||
end
|
||||
checkin + hours.hours
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user