Skip to content

Commit

Permalink
Merge branch 'main' into HER-67-Update-Order-Form-to-Use-Address-and-…
Browse files Browse the repository at this point in the history
…Organization
  • Loading branch information
mhope21 authored Jan 14, 2025
2 parents ec43b2e + 49a43f8 commit 8064f21
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 5 deletions.
41 changes: 41 additions & 0 deletions app/controllers/api/v1/addresses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class Api::V1::AddressesController < ApplicationController
before_action :set_addressable

def create
@address = @addressable.addresses.build(address_params)
if @address.save
render json: @address, status: :created
else
render json: @address.errors, status: :unprocessable_entity
end
end

def update
@address = @addressable.addresses.find(params[:id])
if @address.update(address_params)
render json: @address, status: :ok
else
render json: @address.errors, status: :unprocessable_entity
end
end

def destroy
@address = @addressable.addresses.find(params[:id])
@address.destroy
head :no_content
end

private

def set_addressable
@addressable = if params[:user_id]
User.find(params[:user_id])
elsif params[:organization_id]
Organization.find(params[:organization_id])
end
end

def address_params
params.require(:address).permit(:street_address, :city, :state, :postal_code, :save_to_user)
end
end
16 changes: 15 additions & 1 deletion app/controllers/api/v1/availabilities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ def index

viewing_month = params[:month].to_i || Date.today.month
viewing_year = params[:year].to_i || Date.today.year
start_date = Date.new(viewing_year, viewing_month, 1)
end_date = start_date.end_of_month

puts "Received Year: #{params[:year]}, Month: #{params[:month]}" # Debugging the incoming params


# Debugging the parsed values of year and month
puts "Parsed Year: #{viewing_year}, Month: #{viewing_month}"

Expand All @@ -34,6 +35,9 @@ def index
puts "Error creating start or end date: #{e.message}"
end

# Trigger the job to create next month's availabilities if needed
trigger_recurring_availability_job(viewing_month, viewing_year)

# Fetch the availabilities within the specified date range
@availabilities = Availability.where(start_time: start_date..end_date)
render json: @availabilities
Expand Down Expand Up @@ -79,4 +83,14 @@ def set_availability
def availability_params
params.require(:availability).permit(:start_time, :end_time, :speaker_id, :recurring_availability_id)
end

def trigger_recurring_availability_job(viewing_month, viewing_year)
# Calculate the next month and year based on the viewing month and year
next_month_date = Date.new(viewing_year, viewing_month, 1).next_month
next_month = next_month_date.month
next_year = next_month_date.year

# Trigger the job for the next month
RecurringAvailabilityJob.perform_later(next_month, next_year)
end
end
20 changes: 19 additions & 1 deletion app/controllers/api/v1/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ def index
# POST /api/v1/orders
def create
@order = Order.new(order_params)
@user = current_user # Ensure you're getting the current user

@order.user = current_user
if @order.save
@user = current_user
@user.reload # Reload the user to get the updated list of addresses
@addresses = @user.addresses # Get the addresses after reload

render json: { order: @order, addresses: @addresses }, status: :created
associate_address_with_user(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
Expand All @@ -30,6 +32,7 @@ def show
# PATCH/PUT /api/v1/orders/:id
def update
if @order.update(order_params)
associate_address_with_user(@order)
render json: @order, status: :ok
else
render json: @order.errors, status: :unprocessable_entity
Expand All @@ -45,7 +48,22 @@ def destroy

private

def set_order
@order = Order.find(params[:id])
end

def order_params
params.require(:order).permit(:user_id, :phone, :school_year, :product_id, :product_type, :address_id, :comments, address_attributes: [ :id, :street_address, :city, :state, :postal_code, :save_to_user, :addressable_type, :addressable_id, :_destroy ])
end

def associate_address_with_user(order)
if order.address && order.user
# Add a condition to check if the address should be saved to user
if order.address.save_to_user
unless order.user.addresses.exists?(order.address.id)
order.user.addresses << order.address
end
end
end
end
end
39 changes: 39 additions & 0 deletions app/jobs/recurring_availability_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class RecurringAvailabilityJob < ApplicationJob
queue_as :default

def perform(viewing_month, viewing_year)
start_date = DateTime.new(viewing_year, viewing_month, 1)
end_date = start_date.end_of_month

# Wrap the entire logic in a rescue block to handle unexpected errors
begin
# Check if availabilities for the specified month already exist
existing_availabilities = Availability.where(start_time: start_date..end_date)
return if existing_availabilities.exists?

# Find all recurring availabilities that need to be created for the next month
recurring_availabilities = RecurringAvailability.where("end_date IS NULL OR end_date >= ?", start_date)

# Use a transaction to ensure atomicity
Availability.transaction do
recurring_availabilities.each do |recurring|
(start_date.to_date..end_date.to_date).each do |date| # Use Date instead of DateTime
if recurring.recurs_on?(date)
Availability.create!(
start_time: DateTime.new(date.year, date.month, date.day, recurring.start_time.hour, recurring.start_time.min, recurring.start_time.sec),
end_time: DateTime.new(date.year, date.month, date.day, recurring.end_time.hour, recurring.end_time.min, recurring.end_time.sec),
speaker_id: recurring.speaker_id,
recurring_availability_id: recurring.id
)
end
end
end
end

rescue StandardError => e
Rails.logger.error("RecurringAvailabilityJob failed for month #{viewing_month}, year #{viewing_year}: #{e.message}")
Rails.logger.error(e.backtrace.join("\n"))
raise e # Re-raise the error to ensure the job retries or fails properly
end
end
end
2 changes: 2 additions & 0 deletions app/models/address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ class Address < ApplicationRecord
belongs_to :addressable, polymorphic: true
has_many :orders

attribute :save_to_user, :boolean, default: false

validates :street_address, :city, :state, :postal_code, :addressable, presence: true
validates :postal_code, format: { with: /\A\d{5}(-\d{4})?\z/, message: "must be a valid postal code" }
end
5 changes: 5 additions & 0 deletions app/models/recurring_availability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ class RecurringAvailability < ApplicationRecord
validates :end_date, presence: true
validate :end_date_cannot_be_in_the_past

def recurs_on?(date)
# Example logic: Recurs weekly on the same day of the week
(start_date.wday == date.wday) && (end_date.nil? || date <= end_date)
end

private

def end_date_cannot_be_in_the_past
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
post "kit_items_only", to: "kit_items#create_kit_items_only"
patch "kit_items_only/:id", to: "kit_items#update_kit_items_only"
resources :users do
resources :addresses, only: [ :create, :update, :destroy ]
member do
get "profile"
end
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20250110130617_add_save_to_user_to_addresses.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSaveToUserToAddresses < ActiveRecord::Migration[7.2]
def change
add_column :addresses, :save_to_user, :boolean
end
end
7 changes: 5 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions spec/factories/addresses.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
city { Faker::Address.city }
state { Faker::Address.state_abbr }
postal_code { Faker::Address.zip_code }
save_to_user { true }
association :addressable, factory: :user # Default polymorphic association
end
end
37 changes: 37 additions & 0 deletions spec/jobs/recurring_availability_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'rails_helper'

RSpec.describe RecurringAvailabilityJob, type: :job do
# describe '#perform' do
# let(:viewing_month) { 1 } # January
# let(:viewing_year) { 2025 }
# let(:start_date) { Date.new(viewing_year, viewing_month, 1) }
# let(:end_date) { start_date.end_of_month }

# before do
# # Create a recurring availability rule
# @recurring_availability = create(
# :recurring_availability,
# start_time: "09:00",
# end_time: "10:00",
# speaker_id: 1,
# recurs_on: ->(date) { date.wday == 1 } # Recur every Monday
# )
# end

# it 'creates new availabilities for recurring rules' do
# expect {
# RecurringAvailabilityJob.new.perform(viewing_month, viewing_year)
# }.to change(Availability, :count).by(4) # Assuming 4 Mondays in January 2025
# end

# it 'does not create duplicates if availabilities already exist' do
# # First execution
# RecurringAvailabilityJob.new.perform(viewing_month, viewing_year)

# # Second execution
# expect {
# RecurringAvailabilityJob.new.perform(viewing_month, viewing_year)
# }.not_to change(Availability, :count)
# end
# end
end
Loading

0 comments on commit 8064f21

Please sign in to comment.