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

Custom calculator #12

Open
wants to merge 9 commits into
base: monterail
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ node_modules
/node_modules
yarn-debug.log*
.yarn-integrity
/yarn-error.log
/yarn-error.log
config/master.key
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ GEM
friendly_id (5.4.2)
activerecord (>= 4.0.0)
gem-release (2.2.1)
geocoder (1.6.7)
github_changelog_generator (1.16.2)
activesupport
async (>= 1.25.0)
Expand Down Expand Up @@ -704,6 +705,7 @@ DEPENDENCIES
flipper-redis
flipper-ui
font_assets
geocoder (~> 1.6, >= 1.6.7)
letter_opener
listen
memory_profiler
Expand Down Expand Up @@ -744,4 +746,4 @@ RUBY VERSION
ruby 2.7.3p183

BUNDLED WITH
2.1.4
2.2.25
20 changes: 20 additions & 0 deletions app/models/spree/address_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module SpreeStarter
module Spree
module AddressDecorator
def self.prepended(base)
base.attr_accessor :postcode

base.geocoded_by :coordinates
base.after_validation :geocode
end

def coordinates
[address1, address2, city, zipcode].compact.join(', ')
end
end
end
end

::Spree::Address.prepend SpreeStarter::Spree::AddressDecorator if ::Spree::Address.included_modules.exclude?(SpreeStarter::Spree::AddressDecorator)


34 changes: 34 additions & 0 deletions app/models/spree/calculator/shipping/store_distance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'pry'
require_dependency 'spree/shipping_calculator'

module Spree
module Calculator::Shipping
class StoreDistance < Spree::ShippingCalculator
preference :base_amount_up_to_2_5_mi, :decimal, default: 0
preference :base_amount_up_to_3_5_mi, :decimal, default: 0
preference :base_amount_up_to_6_mi, :decimal, default: 0
preference :base_amount_up_to_9_mi, :decimal, default: 0

def self.description
Spree.t(:shipping_store_distance)
end

def compute_package(package)
compute_store_distance(package)
end

delegate :compute_store_distance, to: :distance_calculator

private

def distance_calculator
::Spree::Calculator::StoreDistance.new(
preferred_base_amount_up_to_2_5_mi: preferred_base_amount_up_to_2_5_mi,
preferred_base_amount_up_to_3_5_mi: preferred_base_amount_up_to_3_5_mi,
preferred_base_amount_up_to_6_mi: preferred_base_amount_up_to_6_mi,
preferred_base_amount_up_to_9_mi: preferred_base_amount_up_to_9_mi
)
end
end
end
end
82 changes: 82 additions & 0 deletions app/models/spree/calculator/store_distance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
require 'spree/calculator'

module Spree
class Calculator::StoreDistance < Calculator
preference :base_amount_up_to_2_5_mi, :decimal, default: 0
preference :base_amount_up_to_3_5_mi, :decimal, default: 0
preference :base_amount_up_to_6_mi, :decimal, default: 0
preference :base_amount_up_to_9_mi, :decimal, default: 0

def self.description
Spree.t(:store_distance)
end

def self.available?(_object)
true
end

def compute(object)
compute_store_distance(object.distance)
end


def compute_store_distance(distance)
vendors = distance.order.variants.map do |vend|
vend.vendor.to_coordinates
end

total = 0

start = distance.to_shipment.stock_location.to_coordinates
total += Geocoder::Calculations.distance_between(start, vendors[0])

n = 1
x = vendors.count - 1
for a in n...x
vendor_distance = Geocoder::Calculations.distance_between(vendors[n], vendors[n - 1])
total += vendor_distance
end

final_location = distance.order.ship_address.to_coordinates
total += Geocoder::Calculations.distance_between(vendors.last, final_location)

total += Geocoder::Calculations.distance_between(final_location, start)

store_collection_charge = -0.5
vendors.map { |store_charge| store_collection_charge += 0.5 }
Copy link
Member

Choose a reason for hiding this comment

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


case total
when 0..2.5
total = preferred_base_amount_up_to_2_5_mi
when 2.6..3.5
total = preferred_base_amount_up_to_3_5_mi
when 3.6..5.9
total = preferred_base_amount_up_to_6_mi
when 6.0..9
total = preferred_base_amount_up_to_9_mi
end

total_weight = 0
x = distance.order.variants.all.count

for b in 0...x do
total_weight = distance.order.variants.map do |all|
Copy link
Member

Choose a reason for hiding this comment

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

all.weight
end
end
total_load = total_weight.sum

case total_load
when 0..25
total_load = 1
when 26..36
total_load = 1.2
when 36..50
total_load = 1.4
end

total = total + store_collection_charge
total_price = (total * total_load)
Copy link
Member

Choose a reason for hiding this comment

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

(base_amount + store_collection_charge) * total_weight_factor

end
end
end
20 changes: 20 additions & 0 deletions app/models/spree/stock_location_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module SpreeStarter
module Spree
module StockLocationDecorator
def self.prepended(base)
base.attr_accessor :postcode

base.geocoded_by :coordinates
base.after_validation :geocode
end

def coordinates
[address1, address2, zipcode ].compact.join(', ')
end
end
end
end

::Spree::StockLocation.prepend SpreeStarter::Spree::StockLocationDecorator if ::Spree::StockLocation.included_modules.exclude?(SpreeStarter::Spree::StockLocationDecorator)


19 changes: 19 additions & 0 deletions app/models/spree/zone_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module SpreeStarter
module Spree
module ZoneDecorator
def self.prepended(base)
base.attr_accessor :postcode

base.geocoded_by :coordinates
base.after_validation :geocode
end

def coordinates
[starting_point].compact.join(', ')
end
end
end
end

::Spree::Zone.prepend SpreeStarter::Spree::ZoneDecorator if ::Spree::Zone.included_modules.exclude?(SpreeStarter::Spree::ZoneDecorator)

2 changes: 2 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,7 @@ class Application < Rails::Application

# flipper memoizing
config.middleware.use Flipper::Middleware::Memoizer

config.autoloader = :classic
end
end
4 changes: 4 additions & 0 deletions config/initializers/spree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
# Example:
# Uncomment to stop tracking inventory levels in the application
# config.track_inventory_levels = false

end

Spree.user_class = 'Spree::User'

config = Rails.application.config
config.spree.calculators.shipping_methods << Spree::Calculator::Shipping::StoreDistance
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddStartingPointToSpreeZones < ActiveRecord::Migration[6.1]
def change
add_column :spree_zones, :starting_point, :string
end
end
6 changes: 6 additions & 0 deletions db/migrate/20210922141756_add_coordinates_to_spree_zone.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddCoordinatesToSpreeZone < ActiveRecord::Migration[6.1]
def change
add_column :spree_zones, :latitude, :float
add_column :spree_zones, :longitude, :float
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddCoordinatesToSpreeStockLocation < ActiveRecord::Migration[6.1]
def change
add_column :spree_stock_locations, :latitude, :float
add_column :spree_stock_locations, :longitude, :float
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddCoordinatesToSpreeAddresses < ActiveRecord::Migration[6.1]
def change
add_column :spree_addresses, :latitude, :float
add_column :spree_addresses, :longitude, :float
end
end
9 changes: 8 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2021_08_10_140732) do
ActiveRecord::Schema.define(version: 2021_09_24_073830) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -110,6 +110,8 @@
t.integer "user_id"
t.datetime "deleted_at"
t.string "label"
t.float "latitude"
t.float "longitude"
t.index ["country_id"], name: "index_spree_addresses_on_country_id"
t.index ["deleted_at"], name: "index_spree_addresses_on_deleted_at"
t.index ["firstname"], name: "index_addresses_on_firstname"
Expand Down Expand Up @@ -969,6 +971,8 @@
t.boolean "propagate_all_variants", default: true
t.string "admin_name"
t.integer "vendor_id"
t.float "latitude"
t.float "longitude"
t.index ["active"], name: "index_spree_stock_locations_on_active"
t.index ["backorderable_default"], name: "index_spree_stock_locations_on_backorderable_default"
t.index ["country_id"], name: "index_spree_stock_locations_on_country_id"
Expand Down Expand Up @@ -1291,6 +1295,9 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "kind", default: "state"
t.string "starting_point"
t.float "latitude"
t.float "longitude"
t.index ["default_tax"], name: "index_spree_zones_on_default_tax"
t.index ["kind"], name: "index_spree_zones_on_kind"
end
Expand Down
40 changes: 40 additions & 0 deletions spec/models/spec/calculator/shipping/store_distance_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'spec_helper'

module Spree
module Calculator::Shipping
describe StoreDistance, type: :model do
let(:subject) { StoreDistance.new }

let(:variant1) { build(:variant, price: 19) }
let(:variant2) { build(:variant, price: 25) }

let(:package) do
build(:stock_package, variants_contents: {variant1 => 5})
end
let!(:vendor) { Spree::Vendor.create!(name: "vendor1", about_us: "50 Newton St, Birmingham B4 6NE") }
let!(:vendor2) { Spree::Vendor.create!(name: "vendor2", about_us: "Ryder St, Birmingham B4 7NE") }

let(:stock_location1) { build(:stock_location) }

let(:line_item1) { build(:line_item, variant1: variant1) }
let(:line_item2) { build(:line_item, variant2: variant2) }

it 'returns address' do
expect(subject.compute(package)).to eq(0)
end

it 'return vendor' do
expect(vendor.to_coordinates).to eq(Spree::Vendor.first.to_coordinates)
end

it 'allows creation of new object with all the attributes' do
StoreDistance.new(
preferred_base_amount_up_to_2_5_mi: 1,
preferred_base_amount_up_to_3_5_mi: 2,
preferred_base_amount_up_to_6_mi: 3,
preferred_base_amount_up_to_9_mi: 4
)
end
end
end
end