Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,18 @@ See the `Makefile` for all commands.
1. Install npm packages: `npm i`
2. Initialize and migrate the db: `bundle exec rails db:migrate`
3. Seed the db: `bundle exec rails db:seed`
5. Start Tap: `./bin/dev`
5. Start Tap: `./bin/dev` (or run `npm run build:js`, then `bundle exec rails s`)

#### Tests

Run `bundle exec rake`\
or if that doesn't work try `bundle exec rspec`?

#### Linter (rubocop)
- Run `bundle exec rubocop` to lint
- To autocorrect most offences
- safely : `bundle exec rubocop -a`
- unsafely : `bundle exec rubocop -A`

## Deploy to production

Expand Down
45 changes: 45 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,51 @@ def order_dagschotel
end
end

# quickly order a single product
# POST /users/{username}/quickorder
# takes the product_id as payload
def quick_order
product = Product.find_by(id: params[:product_id])

unless product
flash.now[:error] = "Product not found!"
respond_to do |format|
format.html { redirect_back_or_to(root_path) }
format.json do
render json: { message: "Quick order failed for #{@user.name}. Product not found." }, status: :bad_request
end
end
return
end

order = @user.orders.build
order.order_items.build(count: 1, product: product)
authorize! :create, order

if order.save
flash[:success] = "#{product.name} has been ordered!"

flash[:successful_order_items] = order.order_items.map do |oi|
{ product: oi.product, count: oi.count }
end

respond_to do |format|
format.html { redirect_back_or_to(root_path) }
format.json { render json: { message: "Quick order succeeded for #{@user.name}." }, status: :ok }
end
else
flash[:error] = order.valid? ? "Something went wrong! Please try again." : order.errors.full_messages.join(". ")
respond_to do |format|
format.html { redirect_back_or_to(root_path) }
format.json do
render json: {
message: order.errors.full_messages.join(". ")
}, status: :unprocessable_content
end
end
end
end

def reset_key
@user.generate_key!
redirect_to @user
Expand Down
9 changes: 9 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ def balance
bal - total_pending
end

def last_ordered_products(amount = 5)
orders.includes(:products)
.order(created_at: :desc)
.limit(amount)
.flat_map(&:products)
.uniq
.first(amount)
end

# Static Users

def self.guest
Expand Down
19 changes: 19 additions & 0 deletions app/views/users/_quick_order.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div class="columns is-multiline is-justify-content-space-between">
<div class="column">
<div class="card">
<div class="card-content">
<h1 class="title is-size-4">Quick orders</h1>
<div style="display: flex; justify-content: space-evenly">
<% products.each do |product| %>
<%= button_to quick_user_path(@user),
method: :post,
params: { product_id: product.id },
class: "button button-flex is-fullwidth is-primary is-light" do %>
<%= image_tag product.avatar.url, title: product.name %>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
</div>
6 changes: 6 additions & 0 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
<div class="column is-12-mobile is-7-tablet is-8-desktop is-9-widescreen">
<!-- Statistics -->
<%= render "stats_cards" %>

<!-- Quick orders -->
<% recent_products = @user.last_ordered_products %>
<% if recent_products.any? %>
<%= render "quick_order", products: recent_products %>
<% end %>

<!-- Orders -->
<%= render "orders" %>
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
# Legacy endpoints, required for Tappb
get "quickpay" => "users#order_dagschotel"

post "quick" => "users#quick_order"

# Change the user's API key.
post :reset_key
end
Expand Down
43 changes: 43 additions & 0 deletions spec/controllers/users_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,47 @@
# end
# end
end

# quick order
describe "POST quick_order" do
let(:product) { create(:product, stock: 20) }

before do
# Mock the balance check (Tab API)
balance = 12_345
stub_request(:get, /.*/).to_return(status: 200, body: JSON.dump({ balance: balance }))
end

context "with a valid product_id" do
it "creates a new order" do
expect do
post :quick_order, params: { id: user.id, product_id: product.id }
end.to change { user.reload.orders_count }.by(1)
end

describe "the created order" do
before do
post :quick_order, params: { id: user.id, product_id: product.id }
end

let(:order) { user.orders.last }

it "contains exactly 1 order item" do
expect(order.order_items.size).to eq 1
end

it "contains the correct product" do
expect(order.order_items.first.product).to eq product
end
end
end

context "with an invalid product_id" do
it "does not create an order" do
expect do
post :quick_order, params: { id: user.id, product_id: 99_999 }
end.not_to change(Order, :count)
end
end
end
end