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

Feature/pbrh+ 28 add user to item waitlist #178

Merged
merged 32 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
516642d
Fix notifications sorting
MariusDoe Dec 2, 2022
409e8bd
Clean up notifications index page
MariusDoe Dec 2, 2022
59b3016
Remove notification snippet from Notification
MariusDoe Dec 2, 2022
dcf4679
Add LendRequestNotification
MariusDoe Dec 2, 2022
ae752f3
Make Notification actable
MariusDoe Dec 2, 2022
f015572
Let LendRequestNotification act_as a Notification
MariusDoe Dec 2, 2022
b123d60
Add title and description to LendRequestNotification
MariusDoe Dec 2, 2022
3c375ff
Add method delegation to specific Notification class
MariusDoe Dec 2, 2022
8bb97fd
Show a notification's title and description
MariusDoe Dec 2, 2022
7f228ea
Add ability to show a custom partial for notifications
MariusDoe Dec 2, 2022
3043103
Add dummy buttons for LendRequestNotification
MariusDoe Dec 2, 2022
d80864d
merged with feature/pbrh+-46-notification-event
LinoH5 Dec 10, 2022
9383e81
starts implementing waitlist and adding users to it
LinoH5 Dec 11, 2022
cda5b8d
implements leaving waitlist, notifications, status info, refactoring
LinoH5 Dec 12, 2022
7888119
add tests for waitlist model
Dec 12, 2022
f484754
failing tests
Dec 12, 2022
3b36248
tests and stuff
Dec 12, 2022
3a14d78
renames users in tests to clarify their role
LinoH5 Dec 12, 2022
b1f5a54
adds success status update for waitlist.add_user
LinoH5 Dec 12, 2022
eaeede2
rubocop automatic corrections
AlexanderUngefug Dec 13, 2022
eac2d90
removes waitlist button for owner, more tests, rubocop corrections
LinoH5 Dec 13, 2022
339f33b
merge with local changes
LinoH5 Dec 13, 2022
8219c88
merged with dev
LinoH5 Dec 13, 2022
fc58161
fixed failing tests
LinoH5 Dec 13, 2022
292a95c
rubocop automatic corrections
LinoH5 Dec 13, 2022
a584763
rubocop fixes
LinoH5 Dec 13, 2022
e5c645c
test fix
LinoH5 Dec 13, 2022
453d781
Merge remote-tracking branch 'origin/dev' into feature/pbrh+-28-add-u…
LinoH5 Dec 13, 2022
22b2240
Merge branch 'dev' into feature/pbrh+-28-add-user-to-item-waitlist
julianaarnold Dec 13, 2022
abcca7e
set status to lent bei Item creation if holder is set
AlexanderUngefug Dec 14, 2022
b0a7602
button notification style changed, rudimentary Lendbutton implemented
AlexanderUngefug Dec 14, 2022
6efc136
removed button styling by return request
AlexanderUngefug Dec 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 63 additions & 11 deletions app/controllers/items_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# rubocop:disable Metrics/ClassLength
class ItemsController < ApplicationController
before_action :set_item, only: %i[ show edit update destroy ]

Expand All @@ -22,15 +23,10 @@ def edit
# POST /items or /items.json
def create
@item = Item.new(item_params)
respond_to do |format|
if @item.save
format.html { redirect_to item_url(@item), notice: t("models.item.created") }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
@item.waitlist = Waitlist.new
@item.set_status_lent unless @item.holder.nil?

create_create_response
end

# PATCH/PUT /items/1 or /items/1.json
Expand All @@ -56,7 +52,29 @@ def destroy
end
end

def add_to_waitlist
@item = Item.find(params[:id])
@user = current_user

create_add_to_waitlist_response
end

def leave_waitlist
@item = Item.find(params[:id])
@user = current_user
@item.remove_from_waitlist(@user)
@item.save
redirect_to item_url(@item)
end

def request_lend
@item = Item.find(params[:id])
@user = current_user
@item.holder = @user.id
@item.set_status_lent
@item.save

redirect_to item_url(@item)
end

def request_return
Expand All @@ -69,10 +87,17 @@ def request_return
borrower: @user)
@notification.save
end

redirect_to item_url(@item)
end

def accept_lend
@item = Item.find(params[:id])
@notification = LendRequestNotification.find_by(item: @item)
@item.set_status_lent
@item.holder = @notification.borrower.id
@item.save
end

def accept_return
@item = Item.find(params[:id])
@notification = ReturnRequestNotification.find_by(item: @item)
Expand All @@ -95,6 +120,31 @@ def deny_return

private

def create_create_response
respond_to do |format|
if @item.save
format.html { redirect_to item_url(@item), notice: t("models.item.created") }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end

def create_add_to_waitlist_response
respond_to do |format|
if @item.add_to_waitlist(@user) && @item.save
format.html do
redirect_to item_url(@item),
notice: t("models.waitlist.added_to_waitlist", position: @item.waitlist.position(@user) + 1)
end
else
format.html { redirect_to item_url(@item), alert: t("models.waitlist.failed_adding_to_waitlist") }
end
end
end

# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
Expand All @@ -103,6 +153,8 @@ def set_item
# Only allow a list of trusted parameters through.
def item_params
params.require(:item).permit(:name, :category, :location, :description, :image, :price_ct, :rental_duration_sec,
:rental_start, :return_checklist, :owner, :holder, :lend_status)
:rental_start, :return_checklist, :owner, :holder, :waitlist_id, :lend_status)
end
end

# rubocop:enable Metrics/ClassLength
15 changes: 15 additions & 0 deletions app/models/added_to_waitlist_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# class of a notification send to user, when he/her has been added to a waitlist.
class AddedToWaitlistNotification < ApplicationRecord
acts_as :notification

belongs_to :item

def title
I18n.t("views.notifications.added_to_waitlist.title")
end

def description
I18n.t("views.notifications.added_to_waitlist.description", position: item.waitlist.position(user) + 1,
item: item.name)
end
end
13 changes: 13 additions & 0 deletions app/models/item.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# class of a basic item.
class Item < ApplicationRecord
has_one_attached :image
has_one :waitlist, dependent: :destroy
has_many :lend_request_notifications, dependent: :destroy
has_and_belongs_to_many :users, join_table: "wishlist"

Expand Down Expand Up @@ -39,7 +40,19 @@ def deny_return
# TODO
end

def set_status_lent
self.lend_status = :lent
end

def price_in_euro=(euros)
self.price_ct = euros * 100
end

def add_to_waitlist(user)
waitlist.add_user(user)
end

def remove_from_waitlist(user)
waitlist.remove_user(user)
end
end
15 changes: 15 additions & 0 deletions app/models/move_up_on_waitlist_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# class of a notification send to user, when position in a waitlist changes.
class MoveUpOnWaitlistNotification < ApplicationRecord
acts_as :notification

belongs_to :item

def title
I18n.t("views.notifications.move_up_on_waitlist.title")
end

def description
I18n.t("views.notifications.move_up_on_waitlist.description", position: item.waitlist.position(user) + 1,
item: item.name)
end
end
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class User < ApplicationRecord
has_many :ownerships, class_name: 'Ownership', dependent: :destroy
has_many :owned_groups, through: :ownerships, source: :group

has_and_belongs_to_many :waitlists

def email_parts
email.split("@")[0].split(".")
end
Expand Down
67 changes: 67 additions & 0 deletions app/models/waitlist.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Waitlist model for handling adding and removing of users from items waitlist and corresponding side effects.
class Waitlist < ApplicationRecord
belongs_to :item
has_and_belongs_to_many :users

def position(user)
users.find_index(user)
end

def first_user
users.first
end

def add_user(user)
unless users.exists?(user.id) || user.id == item.owner
users << user
add_added_to_waitlist_notification(user)
return true
end
false
end

def remove_user(user)
user_index = users.find_index(user)
users.delete(user)

delete_waitlist_notifications(user)

return if user_index.nil? || user_index >= users.size

users[user_index..].each do |temp_user|
delete_waitlist_notifications(temp_user)
add_move_up_on_waitlist_notification(temp_user)
end
end

private

def delete_waitlist_notifications(user)
delete_added_to_waitlist_notification(user)
delete_moved_up_on_waitlist_notification(user)
end

def add_added_to_waitlist_notification(user)
@notification = AddedToWaitlistNotification.new(user: user, date: Time.zone.now, item: item)
@notification.save
end

def add_move_up_on_waitlist_notification(user)
@notification = MoveUpOnWaitlistNotification.new(user: user, date: Time.zone.now, item: item)
@notification.save
end

def delete_added_to_waitlist_notification(user)
@notification = AddedToWaitlistNotification.find_by(item: item, user: user)
return if @notification.nil?

@notification.destroy
end

def delete_moved_up_on_waitlist_notification(user)
@notification = MoveUpOnWaitlistNotification.find_by(item: item, user: user)
return if @notification.nil?

@notification.destroy
end
end
30 changes: 23 additions & 7 deletions app/views/items/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,31 @@
<p class="body1"><%= User.find(@item.owner).email %></p>
<p class="subtitle"><%= t('views.show_item.lend_until')%></p>
<p class="body1"><%= ((@item.rental_start.nil? ? Time.now() : @item.rental_start) + (@item.rental_duration_sec.nil? ? 86400 : @item.rental_duration_sec)).strftime('%d.%m.%Y') %></p>
<% if !current_user.nil? && @item.holder == current_user.id %>
<%= button_to t('views.show_item.return'), action:"request_return" %>
<% else %>
<% if @item.lend_status == "available" %>
<%= button_to t('views.show_item.borrow'), action:"request_lend" %>
<p class="subtitle"><%= t('views.show_item.waitlist')%></p>
<p class="body1">
<% if !current_user.nil? %>
<% if [email protected]?(current_user.id) %>
<%= t('views.show_item.users_waiting', amount: @item.waitlist.users.size) %>
<% else %>
<%= t('views.show_item.waitlist_position', position: @item.waitlist.users.find_index(current_user) + 1) %>
<% end %>
<% end %>
</p>
<% if !current_user.nil? && current_user.id != @item.owner %>
<% if @item.holder == current_user.id %>
<%= button_to t('views.show_item.return'), { action: "request_return" }, class: "primaryButton" %>
<% else %>
<%= button_to t('views.show_item.enter_waitlist') %>
<% if @item.lend_status == "available" %>
<%= button_to t('views.show_item.lend'), { action: "request_lend" }, class: "primaryButton" %>
<% else %>
<% if [email protected]?(current_user.id) %>
<%= button_to t('views.show_item.enter_waitlist'), { action: "add_to_waitlist" }, class: "primaryButton" %>
<% else %>
<%= button_to t('views.show_item.leave_waitlist'), { action: "leave_waitlist" }, class: "primaryButton" %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<br><br><br>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</div>
<div class="modal-footer">
<%= button_to t("defaults.decline"), "/", class:"btn btn-danger" %>
<%= button_to t("defaults.accept"), "/" , class:"btn btn-success" %>
<%= button_to t("defaults.accept"), accept_lend_path(id: notification.item.id) , class:"btn btn-success" %>
</div>
</div>
</div>
Expand Down
14 changes: 3 additions & 11 deletions app/views/notifications/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,10 @@
<div class="notification-grey-box">
<% notifications.each do |notification|%>
<div class="container notification">
<div class="row row-cols-2 ">
<div class="col-sm-1 align-self-center">
<div class="row ">
<div class="col align-self-center">
<%= render_if_exists notification.custom_partial, notification: notification %>
</div>
<div class="col-sm-11 align-self-center ">
<h3>
<%= notification.title %>
</h3>
<p>
<%= notification.description %>
</p>
</div>
</div>
</div>
</div>
<% end %>
Expand Down
Loading