Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #12 🎫: General Shopping List (Shopping List) #24

Merged
merged 9 commits into from
Dec 21, 2023
30 changes: 30 additions & 0 deletions app/controllers/shopping_lists_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class ShoppingListsController < ApplicationController
def show
user_recipes = current_user.recipes

ingredients = []
user_recipes.each do |recipe|
recipe.recipe_foods.each do |rf|
ingredients << { food: rf.food, quantity: rf.quantity }
end
end

combined_ingredients = Hash.new(0)
ingredients.each do |ingredient|
combined_ingredients[ingredient[:food]] += ingredient[:quantity]
end

@items_to_buy = []
combined_ingredients.each do |current_food, required_quantity|
existing_quantity = current_food.quantity

next unless required_quantity > existing_quantity

difference = required_quantity - existing_quantity
unit_food_price = current_food.price
@items_to_buy << { food: current_food, quantity: difference, unit_price: unit_food_price }
end

@items_to_buy
end
end
5 changes: 1 addition & 4 deletions app/views/layouts/_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@
</li>

<% if user_signed_in? %>

<% # ! UPDATE THE LINKS BELOW TO POINT TO THE CORRECT PATHS %>

<li class="nav-item">
<%= link_to "My-recipes", recipes_path, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to "Food-List", foods_path, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to "Shopping-list", root_path, class: "nav-link" %>
<%= link_to "Shopping-List", shopping_list_path(id: "show"), class: "nav-link" %>
</li>
<% end %>
</ul>
Expand Down
4 changes: 2 additions & 2 deletions app/views/recipes/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<%= render @recipe %>

<div class="d-flex justify-content-around p-3 m-1">
<button>Generate Shopping list</button>
<%= link_to "Generate shopping list", shopping_list_path, method: :get, class: "btn btn-outline-success" %>
<% if @recipe.user == current_user %>
<%= link_to "Add ingredient", new_recipe_food_path(recipe_id: @recipe.id), class: "btn btn-outline-success" %>
<% end %>
Expand Down Expand Up @@ -32,7 +32,7 @@
<tr>
<td><%= ingredient.food.name %></td>
<td><%= "#{ingredient.quantity}#{ingredient.food.measurement_unit}" %></td>
<td><%= "$#{ingredient.food.price*ingredient.quantity}" %></td>
<td><%= "$#{ingredient.food.price * ingredient.quantity}" %></td>
<% if @recipe.user == current_user %>
<td><%= link_to "Modify", edit_recipe_food_path(ingredient), class: "btn btn-ountline-danger", method: :update, data: { "turbo-method": :update } %></td>
<td><%= link_to "Delete", ingredient, class: "btn btn-ountline-danger", method: :delete, data: { "turbo-method": :delete } %></td>
Expand Down
52 changes: 52 additions & 0 deletions app/views/shopping_lists/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<div id= "shopping-list">
<h2 class="text-center font-weight-bold mt-4">
<span class="text-danger">Your</span>
<span class="text-warning">Shopping List</span>
</h2>
<div class="d-flex justify-content-around flex-wrap m-2 mt-3 mb-3">
<p class="p-2">
<strong>
Amount of food items to buy:
<span class="text-success">
<%= @items_to_buy.count %>
</span>
<strong>
</p>
<p class="p-2">
<strong>
Total value of food needed:
<span class="text-danger">
$<%= @items_to_buy.sum { |item| item[:quantity] * item[:unit_price] } %>
</span>
</strong>
</p>
</div>

<div id="foods">
<% if @items_to_buy.empty? %>
<div class="alert alert-info text-center">
<p class="mb-0">Your shopping list is empty.</p>
</div>
<% else %>
<table class="table table-hover table-striped border">
<thead>
<tr>
<th>Food</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>

<tbody>
<% @items_to_buy.each do |item| %>
<tr>
<td><%= item[:food].name %></td>
<td><%= item[:quantity] %></td>
<td>$<%= item[:quantity] * item[:unit_price] %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
</div>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resources :foods
resources :recipes
resources :recipe_foods
resources :shopping_lists, only: [:show]
devise_for :users
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

Expand Down
21 changes: 21 additions & 0 deletions spec/controllers/shopping_lists_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'rails_helper'

RSpec.describe ShoppingListsController, type: :controller do
include Devise::Test::ControllerHelpers

new_user = FactoryBot.create(:user)
recipe = FactoryBot.create(:recipe, user: new_user)
food = FactoryBot.create(:food)
FactoryBot.create(:recipe_food, recipe_id: recipe.id, food_id: food.id, quantity: 2)

before do
sign_in new_user
end

describe 'GET #show' do
it 'assigns @items_to_buy' do
get :show, params: { id: 'show' }
expect(response).to be_successful
end
end
end
30 changes: 30 additions & 0 deletions spec/views/shopping_lists/show.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'rails_helper'

RSpec.describe 'ShoppingLists#show', type: :system do
let(:new_user) { create(:user) }

describe 'show page' do
before(:each) do
visit new_user_session_path

fill_in 'Email', with: new_user.email
fill_in 'Password', with: new_user.password
click_button 'Log in'
end

it 'displays a list of items to buy' do
recipe = create(:recipe, user: new_user)
food = create(:food)
create(:recipe_food, recipe_id: recipe.id, food_id: food.id, quantity: 2000)

visit shopping_list_path(id: 'show')

within('#shopping-list', wait: 5) do
expect(page).to have_selector('table')
expect(page).to have_selector('th', text: 'Food')
expect(page).to have_selector('th', text: 'Quantity')
expect(page).to have_selector('th', text: 'Price')
end
end
end
end