diff --git a/app/controllers/requests_controller.rb b/app/controllers/requests_controller.rb index b6787e5..c4a31db 100644 --- a/app/controllers/requests_controller.rb +++ b/app/controllers/requests_controller.rb @@ -1,5 +1,5 @@ class RequestsController < ApplicationController - before_action :set_request, only: %i[ show edit update destroy ] + before_action :set_request, only: %i[ show edit update destroy settle ] before_action :authenticate_user!, only: %i[ index, my_requests ] @@ -18,6 +18,45 @@ def index def show @allCategories = Category.all @allItems = Item.all + @itemsToStock = @request.getItemStock() + + end + + def volunteer + end + + def settle + @show_settled = true + end + + def next_status + @request = Request.find(params[:format]) + @request.status = @request.status == "pending" ? "delivery_ready" : "claimed" + + if @request.status == "claimed" + # iterate through items table and update quantity + for item in @request.item_changes + # match item for inventory + matchingItems = Item.where(:itemType => item.itemType, :size => item.size, :category_id => item.category_id) + quantityFulfilled = item.quantity + + # contiously remove from each item until the set quantity has been removed + for matchedItem in matchingItems + if matchedItem.quantity <= quantityFulfilled + # perform the update quantity + # ex: quantityFulfilled = 20, and amount in inventory = 15, then quantityFulfilled becomes 5 and amount in inventory should become 0 + # it will then continue to loop to see if there are any more items it can remove + amountToRemove = quantityFulfilled + quantityFulfilled -= matchedItem.quantity + matchedItem.quantity -= amountToRemove + matchedItem.save + end + end + end + end + @request.save + + redirect_to @request end # GET /requests/new @@ -74,8 +113,12 @@ def update @request.items = "#{request_params["items_quantity"]}x #{request_params["items_category"]} #{request_params["items_itemType"]} Size #{request_params["items_sizes"]}" @request.save - format.html { redirect_to @request, notice: "Request was successfully updated." } - format.json { render :show, status: :ok, location: @request } + if request_params[:send_to_settle] && current_user&.volunteer? + format.html { redirect_to settle_request_path(@request), notice: "Request was successfully updated." } + else + format.html { redirect_to @request, notice: "Request was successfully updated." } + format.json { render :show, status: :ok, location: @request } + end else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @request.errors, status: :unprocessable_entity } diff --git a/app/models/item_change.rb b/app/models/item_change.rb index 3124edc..66de039 100644 --- a/app/models/item_change.rb +++ b/app/models/item_change.rb @@ -18,4 +18,8 @@ class ItemChange < ApplicationRecord default_scope { order(quantity: :desc) } + def description + return "#{category.name} #{itemType} (Size #{size}) x #{quantity}" + end + end diff --git a/app/models/request.rb b/app/models/request.rb index 39f9f63..06b84fe 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -28,6 +28,11 @@ class Request < ApplicationRecord 'Other (provide your address below)': 8 }.freeze + enum status: { pending: 0, claimed: 1, delivery_ready: 2 } + # scope :pending, -> { where(status: :pending) } + # scope :claimed, -> { where(status: :claimed) } + # scope :delivery_ready, -> { where(status: :delivery_ready) } + has_many :item_changes accepts_nested_attributes_for :item_changes, allow_destroy: true @@ -51,5 +56,44 @@ def any_blank(att) validates :full_name, length: { in: 2..80 } - + + # Returns how much time is left before the request is "past due," i.e. the + # set urgency window has passed + def due_time + offset = 1.day + case urgency + when URGENCIES.fetch(:"Within 24 hours"); offset = 1.day + when URGENCIES.fetch(:"Within 48 hours"); offset = 2.days + when URGENCIES.fetch(:"Within a week"); offset = 1.week + end + + created_at + offset + end + + # Returns a hash which stores the inventory items that match each element inside request.item_changes to the actual inventory quantity. + # If the item is either out of stock or in limited stock it will show up in this hash, otherwise it will not. + # So, an item that has enough stock to fulfill the order will not be in the hash, otherwise it will have the form: + # [itemChangeID: inventoryStock]. If someone requested 15 Boy's Size 6 Shoe's with ID 2 and there were only 5 in stock it would show + # [2: 5], where 2 is the ID of the 15 Boy's Size 6 in item_change and 5 is the actual stock in the "items" table + def getItemStock + itemsToStock = {} + for item in item_changes + # match item for inventory + matchingItems = Item.where(:itemType => item.itemType, :size => item.size, :category_id => item.category_id) + + # loop through and calculate the total inventory size + inventoryQuantity = 0 + for matchedItem in matchingItems + inventoryQuantity += matchedItem.quantity + end + + # this indicates there is not enough stock, so store the inventory quantity + if inventoryQuantity < item.quantity + itemsToStock[item.id] = inventoryQuantity + end + end + + return itemsToStock + end + end diff --git a/app/views/form_helpers/_item_selection.html.erb b/app/views/form_helpers/_item_selection.html.erb index 080262c..153e5fd 100644 --- a/app/views/form_helpers/_item_selection.html.erb +++ b/app/views/form_helpers/_item_selection.html.erb @@ -212,28 +212,54 @@ +<% send_to_settle ||= false %> +
Quantity | -Category | -Item Type | -Size | + <% if current_user&.volunteer? && send_to_settle %> +Settled | +Quantity | +Description | + <% else %> +Quantity | +Category | +Item Type | +Size | + <% end %>|
---|---|---|---|---|---|---|---|---|---|---|---|
<%= item_change_form.number_field :settled %> | +<%= item_change.quantity %> | ++ <%= item_change.description %> + <% if @itemsToStock.keys.any?(item_change.id) %> + <% if @itemsToStock[item_change.id] > 0 %> + - Limited Stock (<%= @itemsToStock[item_change.id] =%>) + <% else %> + - Out of Stock + <% end %> + <% end %> + | + <% else %><%= item_change_form.number_field :quantity %> | <%= item_change_form.select :category_id, Category.all.map { |category| [ category.name, category.id ] }, options = {}, html_options = {:onchange => "updateItemTypes(this)", :data => { selectorType: "category" }} %> | <%= item_change_form.select :itemType, Item.all.map{ |item| item.itemType }, options = {}, html_options = {:onchange => "updateItemSizes(this)", :data => { selectorType: "itemType" }} %> | <%= item_change_form.select :size, Item.all.map{ |item| item.size }, options = {}, html_options = {:data => { selectorType: "size" }} %> | <%= item_change_form.hidden_field :change_type, value:ItemChange::CHANGE_TYPES.fetch(parent_f) %> | <%= item_change_form.hidden_field :_destroy, html_options = {:onchange => "updateItemSizes(this)", :data => { type: "destroy" }}%> | + <% end %>