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

Add warning threshold to products, mail when below #91 #102

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/interactors/pay_cart.rb
Expand Up @@ -9,5 +9,6 @@ class PayCart
CheckUserBalance,
ApplyTransactionToUserBalance,
CommitTransaction,
ApplyAndDestroyCart
ApplyAndDestroyCart,
WarnIfProductQuantityBelowThreshold
end
10 changes: 10 additions & 0 deletions app/interactors/warn_if_product_quantity_below_threshold.rb
@@ -0,0 +1,10 @@
class WarnIfProductQuantityBelowThreshold
include Interactor

def call
btp = context.cart.cart_items.map(&:product).
select(&:below_warning_threshold?).
compact.uniq
AdminMailer.btp_mail(btp: btp).deliver_later if btp.present?
end
end
9 changes: 9 additions & 0 deletions app/mailers/admin_mailer.rb
@@ -0,0 +1,9 @@
class AdminMailer < ApplicationMailer
def btp_mail(btp:)
@btp = btp
mail(
to: ENV['KDV_ADMIN_MAIL'],
subject: 'Some products are running low'
)
end
end
4 changes: 4 additions & 0 deletions app/mailers/application_mailer.rb
@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: 'kdv@kif.rocks'
layout 'mailer'
end
5 changes: 5 additions & 0 deletions app/models/product.rb
Expand Up @@ -11,4 +11,9 @@ def quantity
def available_quantity
pricings.to_a.sum &:available_quantity
end

def below_warning_threshold?
return false if warning_threshold.nil?
quantity <= warning_threshold
end
end
2 changes: 2 additions & 0 deletions app/representers/product_representer.rb
Expand Up @@ -4,6 +4,8 @@ class ProductRepresenter < ApplicationDecorator
property :name
property :quantity, writeable: false, type: Integer
property :available_quantity, writeable: false, type: Integer
property :warning_threshold, type: Integer

collection(
:tags,
decorator: TagRepresenter,
Expand Down
9 changes: 9 additions & 0 deletions app/views/admin_mailer/btp_mail.text.erb
@@ -0,0 +1,9 @@
Moin,

Folgende Produkte gehen bald leer, es sind nur noch übrig jeweils:

<% @btp.each do |p| -%>
* <%= p.name -%>: <%= p.quantity -%>
<% end -%>

Deine KDV Admins.
13 changes: 13 additions & 0 deletions app/views/layouts/mailer.html.erb
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>

<body>
<%= yield %>
</body>
</html>
1 change: 1 addition & 0 deletions app/views/layouts/mailer.text.erb
@@ -0,0 +1 @@
<%= yield %>
5 changes: 5 additions & 0 deletions db/migrate/20170614221707_add_threshold_to_products.rb
@@ -0,0 +1,5 @@
class AddThresholdToProducts < ActiveRecord::Migration[5.1]
def change
add_column :products, :warning_threshold, :integer
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20170614124236) do
ActiveRecord::Schema.define(version: 20170614221707) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -92,6 +92,7 @@
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "warning_threshold"
end

create_table "taggings", id: :serial, force: :cascade do |t|
Expand Down
7 changes: 4 additions & 3 deletions spec/interactors/pay_cart_spec.rb
Expand Up @@ -11,12 +11,13 @@
end
let(:context) { interactor.context }
let(:user) { create :user, balance: 1000 }
let(:pricings) do
let(:products) do
[
create(:pricing, price: 50, quantity: 5),
create(:pricing, price: 200, quantity: 5)
create(:product, price: 50, quantity: 5),
create(:product, price: 200, quantity: 5)
]
end
let(:pricings) { products.map { |p| p.pricings.first } }
let(:cart_items) do
[
create(:cart_item, quantity: 2, pricing: pricings[0]),
Expand Down
56 changes: 56 additions & 0 deletions spec/interactors/warn_if_product_quantity_below_threshold_spec.rb
@@ -0,0 +1,56 @@
require 'rails_helper'

RSpec.describe WarnIfProductQuantityBelowThreshold do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block has too many lines. [45/25]

describe '#call' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block has too many lines. [43/25]

let(:interactor) { WarnIfProductQuantityBelowThreshold.new cart: cart }
let(:context) { interactor.context }

let(:products) do
[
create(:product),
create(:product)
]
end
let(:cart_items) do
[
create(:cart_item, quantity: 2, pricing: products[0].pricings.first),
create(:cart_item, quantity: 1, pricing: products[1].pricings.first)
]
end
let(:cart) { create :cart, cart_items: cart_items }

before do
allow(AdminMailer).to receive_message_chain(:btp_mail, :deliver_later)
end
before { interactor.call }

context 'when there are no products below their thresholds' do
it 'succeeds' do
expect(context).to be_a_success
end

it 'doesn\'t send an email' do
expect(AdminMailer).to_not have_received(:btp_mail)
end
end

context 'when some products are below their threshold' do
let(:products) do
[
create(:product, quantity: 5, warning_threshold: 12),
create(:product, quantity: 12, warning_threshold: 5),
create(:product, quantity: 5, warning_threshold: 10)
]
end

it 'succeeds' do
expect(context).to be_a_success
end

it 'sends an email' do
expect(AdminMailer).to have_received(:btp_mail).
with(btp: [products[0]])
end
end
end
end
30 changes: 30 additions & 0 deletions spec/models/product_spec.rb
Expand Up @@ -36,4 +36,34 @@
end
end
end

describe '#below_warning_threshold?' do
subject { product.below_warning_threshold? }

context 'the warning_threshold is not set' do
before { product.warning_threshold = nil }

it { is_expected.to be false }
end

context 'a warning_threshold is set' do
context 'and it is less than the remaining items' do
before { product.warning_threshold = product.quantity - 1 }

it { is_expected.to be false }
end

context 'and it is the same as the remaining items' do
before { product.warning_threshold = product.quantity }

it { is_expected.to be true }
end

context 'and it is less than the remaining items' do
before { product.warning_threshold = product.quantity + 5 }

it { is_expected.to be true }
end
end
end
end