Implement LP L discount rule
This commit is contained in:
parent
2f34945418
commit
6c4c9c75fe
@ -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'
|
||||||
|
|
||||||
|
39
lib/planet_express/l_shipment_discount_rule.rb
Normal file
39
lib/planet_express/l_shipment_discount_rule.rb
Normal 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
|
@ -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
|
||||||
|
@ -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
|
||||||
|
77
spec/l_shipment_discount_rule_spec.rb
Normal file
77
spec/l_shipment_discount_rule_spec.rb
Normal 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
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user