1
0

Implement LP L discount rule

This commit is contained in:
Tim Kächele 2021-03-07 22:11:59 +01:00
parent 2f34945418
commit 6c4c9c75fe
6 changed files with 152 additions and 1 deletions

View File

@ -13,13 +13,14 @@ require 'planet_express/invalid_shipment'
require 'planet_express/shipment' require 'planet_express/shipment'
require 'planet_express/shipment_repository' require 'planet_express/shipment_repository'
require 'planet_express/shipment_reader' require 'planet_express/shipment_reader'
# require 'planet_express/shipment_formatter'
require 'planet_express/shipping_option' require 'planet_express/shipping_option'
require 'planet_express/shipping_option_repository' require 'planet_express/shipping_option_repository'
require 'planet_express/rule' 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/l_shipment_discount_rule'
require 'planet_express/shipment_discount_calculator' require 'planet_express/shipment_discount_calculator'

View File

@ -0,0 +1,39 @@
module PlanetExpress
class LShipmentDiscountRule < Rule
protected
def applicable_to?(shipment)
lp_provider_shipment?(shipment) &&
third_l_shipment_in_month?(shipment) &&
rule_not_applied_in_month_already?(shipment)
end
def discount_for(shipment)
Discount.new(discount_amount(shipment), self)
end
private
def lp_provider_shipment?(shipment)
shipment.lp_provider?
end
def third_l_shipment_in_month?(shipment)
provider = shipment.provider
month = shipment.month
count = shipment_repository.l_shipment_count_for_provider_and_month(provider,
month)
(count % 3) == 2
end
def rule_not_applied_in_month_already?(shipment)
!shipment_repository.rule_applied_in_month?(shipment.month, self.class)
end
def discount_amount(shipment)
desired_amount = price(shipment)
discount_budget(shipment).maximum_possible_discount(desired_amount)
end
end
end

View File

@ -14,6 +14,18 @@ module PlanetExpress
date.begin_of_month date.begin_of_month
end end
def price_with_discounts
shipping_option.price_in_cents - total_discount_amount
end
def total_discount_amount
discounts.map(&:amount).sum
end
def lp_provider?
shipping_option.lp_provider?
end
def s_shipment? def s_shipment?
shipping_option.s_shipment? shipping_option.s_shipment?
end end

View File

@ -10,6 +10,10 @@ module PlanetExpress
package_size == 'L' package_size == 'L'
end end
def lp_provider?
provider == 'LP'
end
def inspect def inspect
"ShippingOption [proivder=#{provider} package_size=#{package_size} price_in_cents=#{price_in_cents}]" "ShippingOption [proivder=#{provider} package_size=#{package_size} price_in_cents=#{price_in_cents}]"
end end

View File

@ -0,0 +1,77 @@
# frozen_string_literal: true
RSpec.describe PlanetExpress::LShipmentDiscountRule 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
let(:correct_shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'L')
end
let(:applicable_shipment) do
PlanetExpress::Shipment.new(Date.today, correct_shipping_option)
end
context 'l_shipment' do
context 'not the third shipment' do
it 'does not apply the discount' do
expect do
subject.apply_to(applicable_shipment)
end.to_not(change { applicable_shipment.discounts })
end
end
context 'third shipment for LP' do
context 'LP provider' do
before(:each) do
shipment_repo.add(applicable_shipment)
shipment_repo.add(applicable_shipment)
end
it 'does apply the discount' do
expect do
subject.apply_to(applicable_shipment)
end.to(change { applicable_shipment.discounts.length }.by(1))
discount = applicable_shipment.discounts.last
expect(discount.amount).to eq(applicable_shipment.shipping_option.price_in_cents)
end
it 'updates the discount budget' do
expected_difference = -applicable_shipment.shipping_option.price_in_cents
expect do
subject.apply_to(applicable_shipment)
end.to(change { budget_repo.for_month(applicable_shipment.month).available_budget }.by(expected_difference))
end
end
context 'non LP provider' do
before(:each) do
shipment_repo.add(applicable_shipment)
shipment_repo.add(applicable_shipment)
end
let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('MR', 'L')
end
let(:shipment) do
PlanetExpress::Shipment.new(Date.today, shipping_option)
end
it 'does not update the discounts' do
expect do
subject.apply_to(shipment)
end.to_not(change { shipment.discounts })
end
end
end
end
end

View File

@ -32,4 +32,22 @@ RSpec.describe PlanetExpress::ShippingOption do
end end
end end
end end
describe '#lp_provider?' do
context 'with LP provider' do
subject { build(:shipping_option, provider: 'LP') }
it 'returns true' do
expect(subject.lp_provider?).to eq(true)
end
end
context 'with non L package size' do
subject { build(:shipping_option, provider: 'MP') }
it 'returns false' do
expect(subject.lp_provider?).to eq(false)
end
end
end
end end