1
0

Implement S Shipments Discount rule

This commit is contained in:
Tim Kächele 2021-03-07 21:00:05 +01:00
parent 5c3bb4d41a
commit 2f34945418
3 changed files with 113 additions and 1 deletions

View File

@ -18,7 +18,7 @@ require 'planet_express/shipping_option'
require 'planet_express/shipping_option_repository'
require 'planet_express/rule'
# require 'planet_express/s_shipment_discount_rule'
require 'planet_express/s_shipment_discount_rule'
# require 'planet_express/l_shipment_discount_rule'
require 'planet_express/shipment_discount_calculator'

View File

@ -0,0 +1,36 @@
module PlanetExpress
class SShipmentDiscountRule < Rule
protected
def applicable_to?(shipment)
s_shipment?(shipment) && more_expensive_than_cheapest_shipping_option?(shipment)
end
def discount_for(shipment)
Discount.new(discount_amount(shipment), self)
end
private
def cheapest_available_shipping_price(shipment)
shipping_option_repository.lowest_price_for_package_size(package_size(shipment))
end
def more_expensive_than_cheapest_shipping_option?(shipment)
price(shipment) > cheapest_available_shipping_price(shipment)
end
def package_size(shipment)
shipment.shipping_option.package_size
end
def s_shipment?(shipment)
shipment.shipping_option.s_shipment?
end
def discount_amount(shipment)
desired_amount = price(shipment) - cheapest_available_shipping_price(shipment)
discount_budget(shipment).maximum_possible_discount(desired_amount)
end
end
end

View File

@ -0,0 +1,76 @@
# frozen_string_literal: true
RSpec.describe PlanetExpress::SShipmentDiscountRule do
let(:budget_repo) { PlanetExpress::DiscountBudgetForMonthRepository.new }
let(:shipping_option_repo) { PlanetExpress::ShippingOptionRepository.new }
let(:shipment_repo) { PlanetExpress::ShipmentRepository.new(data: []) }
subject do
described_class.new(
discount_budget_for_month_repository: budget_repo,
shipping_option_repository: shipping_option_repo,
shipment_repository: shipment_repo)
end
context 's_shipment' do
context 'more expensive than cheapest option' do
let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('MR', 'S')
end
let(:shipment) do
PlanetExpress::Shipment.new(Date.today,
shipping_option)
end
it 'does applies the discount' do
expect do
subject.apply_to(shipment)
end.to(change { shipment.discounts.length }.by(1))
expect(shipment.discounts.last.amount).to eq(50)
end
it 'changes the discount budget' do
expect do
subject.apply_to(shipment)
end.to(change { budget_repo.for_month(shipment.month).available_budget }.by(-50))
end
end
context 'equals cheapest options' do
let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'S')
end
let(:shipment) do
PlanetExpress::Shipment.new(Date.today,
shipping_option)
end
it 'does not apply the discount' do
expect do
subject.apply_to(shipment)
end.to_not(change { shipment.discounts })
end
end
end
context 'non s_shipment' do
let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'M')
end
let(:shipment) do
PlanetExpress::Shipment.new(Date.today,
shipping_option)
end
it 'does not apply the discount' do
expect do
subject.apply_to(shipment)
end.to_not(change { shipment.discounts })
end
end
end