Created
January 8, 2018 13:33
-
-
Save elia/d5c68cf18193999bc2dbdf8ebb3c0336 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/app/backend/beestore/client.rb b/app/backend/beestore/client.rb | |
index 2e7c8f67d..aa9ccb708 100644 | |
--- a/app/backend/beestore/client.rb | |
+++ b/app/backend/beestore/client.rb | |
@@ -380,7 +380,9 @@ module Beestore | |
# Use this in case you need to restore stocks. | |
# New 22 Jun 2016. | |
# Used in VariantAvailabilityRestore (worker, multistock) and Quantifier (multistock in single stock location) | |
- # stock_locations is an array of stock locations instances. | |
+ # | |
+ # @param stock_locations [Array<Spree::StockLocation>] | |
+ # | |
def full_multi_availability_for_variant(variant, stock_locations: [], exclude_inactive: false) | |
stock_locations = Array.wrap(stock_locations).compact | |
Histreet.cache.fetch("full_multi_#{variant.in_stock_remote_cache_key}_#{stock_locations.join(',')}", expires_in: 5.seconds) do | |
diff --git a/app/backend/beestore/local_client.rb b/app/backend/beestore/local_client.rb | |
new file mode 100644 | |
index 000000000..792cc1be2 | |
--- /dev/null | |
+++ b/app/backend/beestore/local_client.rb | |
@@ -0,0 +1,22 @@ | |
+module Beestore | |
+ class LocalClient | |
+ def initialize(store) | |
+ @store = store | |
+ end | |
+ | |
+ def can_check_live_availability? | |
+ true | |
+ end | |
+ | |
+ def full_multi_availability_for_variant(variant, stock_locations: [], exclude_inactive: false) | |
+ # stock_items = Spree::StockItem.where(variant_id: variant.id) | |
+ # stock_items = stock_items.joins(:stock_location).merge(Spree::StockLocation.active) | |
+ sleep 5 # simulate call to beestore | |
+ { | |
+ # id_negozio => [disponibile, ordinato_a_fornitore] | |
+ '20' => [3,0], | |
+ '7' => [10,0], | |
+ } | |
+ end | |
+ end | |
+end | |
diff --git a/app/backend/nil_inventory_system.rb b/app/backend/nil_inventory_system.rb | |
index 4ad0332d7..8c7480172 100644 | |
--- a/app/backend/nil_inventory_system.rb | |
+++ b/app/backend/nil_inventory_system.rb | |
@@ -11,12 +11,15 @@ module NilInventorySystem | |
true | |
end | |
- def availability_for_variant(_variant) | |
- raise 'Asking availability_for_variant to NilInventorySystem' | |
+ def availability_for_variant(variant) | |
+ Rails.logger.warn 'Asking availability_for_variant to NilInventorySystem'.yellow | |
+ Rails.logger.info 'Quantifier: using nil inventory system, using sum'.green | |
+ Spree::StockItem.where(variant_id: variant.id).sum(:count_on_hand) | |
end | |
def full_multi_availability_for_variant(variant, stock_locations: [], exclude_inactive: false) | |
- raise 'Asking full_multi_availability_for_variant to NilInventorySystem' | |
+ Rails.logger.warn "Asking full_multi_availability_for_variant to NilInventorySystem".yellow | |
+ availability_for_variant(variant) | |
end | |
def perform_post_payment_actions!(payment, _delay = 0) | |
diff --git a/app/controllers/spree/global_collect_checkouts_controller.rb b/app/controllers/spree/global_collect_checkouts_controller.rb | |
new file mode 100644 | |
index 000000000..70e487450 | |
--- /dev/null | |
+++ b/app/controllers/spree/global_collect_checkouts_controller.rb | |
@@ -0,0 +1,14 @@ | |
+module Spree | |
+ class GlobalCollectCheckoutsController < BaseController | |
+ def create | |
+ return render(nothing: true) unless status_successful? | |
+ return render_ok if @payment.completed? | |
+ | |
+ if @payment.present? && @payment.can_complete? && @payment.next | |
+ render_ok | |
+ else | |
+ render_nok | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb | |
index e5989760d..2881866ff 100644 | |
--- a/app/controllers/spree/orders_controller_decorator.rb | |
+++ b/app/controllers/spree/orders_controller_decorator.rb | |
@@ -86,8 +86,9 @@ Spree::OrdersController.class_eval do | |
# We override to respond to json and place some checks. | |
# Adds a new item to the order (creating a new order if none already exists) | |
def populate | |
- order = current_order(create_order_if_necessary: true) | |
- populator = Spree::OrderPopulator.new(order, current_currency) | |
+ order = current_order(create_order_if_necessary: true) | |
+ populator = Spree::OrderPopulator.new(order, current_currency) | |
+ add_options = params[:options].dup | |
# Debug https://histreet.airbrake.io/projects/113569/groups/1550784120609183557/notices/1552096235114602394 | |
variant = Spree::Variant.find(params[:variant_id]) | |
@@ -124,6 +125,23 @@ Spree::OrdersController.class_eval do | |
render json: line_item.to_json | |
} | |
+ if histreet_store.has_feature?(:optimize_add_to_cart) | |
+ add_options[:disable_erp_check] = true | |
+ original_json_success_response = json_success_response | |
+ json_success_response = -> { | |
+ @order = order | |
+ line_item = populator.order.line_items.find { |li| li.variant_id.to_s == params[:variant_id].to_s }.attributes | |
+ line_item[:product_id] = variant.product_id # for facebook AddToCart | |
+ | |
+ render json: %{ | |
+ { | |
+ "line_item": #{line_item.to_json}, | |
+ "cart": #{render_to_string action: :edit, formats: [:json]} | |
+ } | |
+ } | |
+ } | |
+ end | |
+ | |
html_failure_response = -> { | |
flash[:error] = populator.errors.full_messages.join(' ') | |
redirect_back_or_default(cart_path) | |
@@ -133,7 +151,7 @@ Spree::OrdersController.class_eval do | |
} | |
respond_with(@order) do |format| | |
- if populator.populate(params[:variant_id], params[:quantity], params[:options]) | |
+ if populator.populate(params[:variant_id], params[:quantity], add_options) | |
format.html { request.xhr? ? json_success_response.call : html_success_response.call } | |
format.json { json_success_response.call } | |
else | |
diff --git a/app/models/histreet/store.rb b/app/models/histreet/store.rb | |
index 9a65b9454..82d299109 100644 | |
--- a/app/models/histreet/store.rb | |
+++ b/app/models/histreet/store.rb | |
@@ -261,9 +261,10 @@ module Histreet | |
def inventory_system_client | |
case inventory_system | |
- when 'beestore' then Beestore::Client.new(histreet_store: self) | |
- when 'dmagazine' then Dmagazine::Client.new(histreet_store: self) | |
- else NilInventorySystem::Client.new(histreet_store: self) | |
+ when 'beestore' then Beestore::Client.new(histreet_store: self) | |
+ when 'beestore_local' then Beestore::LocalClient.new(histreet_store: self) | |
+ when 'dmagazine' then Dmagazine::Client.new(histreet_store: self) | |
+ else NilInventorySystem::Client.new(histreet_store: self) | |
end | |
end | |
diff --git a/app/models/spree/order_contents.rb b/app/models/spree/order_contents.rb | |
index 2fdb0d1e0..3a41e6944 100644 | |
--- a/app/models/spree/order_contents.rb | |
+++ b/app/models/spree/order_contents.rb | |
@@ -182,7 +182,7 @@ module Spree | |
create_or_update_order_stock_locations(line_item, options[:stock_location_quantities]) | |
line_item.target_shipment = options[:shipment] if options.key?(:shipment) # transfer_to_location / transfer_to_shipment support | |
- line_item.disable_erp_check = true if options.key?(:shipment) | |
+ line_item.disable_erp_check = true if options.key?(:shipment) || options[:disable_erp_check] | |
begin | |
Rails.logger.tagged('add_to_line_item'.magenta, 'saving line item'.magenta) do | |
diff --git a/app/models/spree/stock/quantifier_decorator.rb b/app/models/spree/stock/quantifier_decorator.rb | |
index 604d2b0bd..c0d6fcd69 100644 | |
--- a/app/models/spree/stock/quantifier_decorator.rb | |
+++ b/app/models/spree/stock/quantifier_decorator.rb | |
@@ -133,15 +133,12 @@ Spree::Stock::Quantifier.class_eval do | |
end | |
def query_erp | |
- if inventory_system_client.is_a?(NilInventorySystem::Client) | |
- Rails.logger.info 'Quantifier: using nil inventory system, using sum'.green | |
- stock_items.sum(:count_on_hand) | |
- elsif stock_locations.present? | |
+ if Spree::StockLocation.count > 1 | |
Rails.logger.info "Quantifier: asking beestore about variant##{@variant.id} full_multi_availability_for_variant in #{stock_locations.map(&:name)}".green | |
- Spree::StockLocation.count > 1 ? inventory_system_client.full_multi_availability_for_variant(@variant, stock_locations: stock_locations, exclude_inactive: true).values.map { |v| v[0] }.inject(0) { |sum, x| sum + x } : (inventory_system_client.availability_for_variant(@variant) || stock_items.sum(:count_on_hand)) | |
+ inventory_system_client.full_multi_availability_for_variant(@variant, stock_locations: stock_locations || [], exclude_inactive: true).values.map(&:first).reduce(:+) | |
else | |
- Rails.logger.info "Quantifier: asking beestore about variant##{@variant.id} full_multi_availability_for_variant/availability_for_variant".green | |
- Spree::StockLocation.count > 1 ? inventory_system_client.full_multi_availability_for_variant(@variant, stock_locations: [], exclude_inactive: true).values.map { |v| v[0] }.inject(0) { |sum, x| sum + x } : (inventory_system_client.availability_for_variant(@variant) || stock_items.sum(:count_on_hand)) | |
+ Rails.logger.info "Quantifier: asking beestore about variant##{@variant.id} availability_for_variant/sum(:count_on_hand) in #{stock_locations.map(&:name)}".green | |
+ inventory_system_client.availability_for_variant(@variant) || stock_items.sum(:count_on_hand) | |
end | |
end | |
end | |
diff --git a/config/locales/en.yml b/config/locales/en.yml | |
index d92212ff1..2efe6d673 100644 | |
--- a/config/locales/en.yml | |
+++ b/config/locales/en.yml | |
@@ -476,6 +476,11 @@ en: | |
size: Size | |
sold_out: Sold Out | |
spree: | |
+ order_mailer: | |
+ cancel_email: | |
+ order_summary: Order summary | |
+ canceled: Canceled | |
+ order_summary_reason: Reason | |
product_by_designer: Products by designer | |
product_by_designer_description: List number of products for each designer | |
dhl_pickups: DHL Pickups | |
diff --git a/config/settings.yml b/config/settings.yml | |
index 892a6e301..f280f5cf5 100644 | |
--- a/config/settings.yml | |
+++ b/config/settings.yml | |
@@ -46,7 +46,11 @@ stores: | |
- legacy_runway_looks | |
# - guest_verification_code | |
# - new_seasons_are_invisible | |
- | |
+ - optimize_promo_handler | |
+ - optimize_promo_handler_zones | |
+ - optimize_promo_handler_users | |
+ - optimize_promo_eligibility | |
+ - optimize_add_to_cart | |
domains: | |
- antonioli.dev | |
@@ -1961,6 +1965,7 @@ stores: | |
available_exporters: [] | |
facebook_og_properties: | |
+ pixel_helper_id: '139774013394772' | |
title: AntoniaBoutique | |
description: Leaders in high fashion retail | |
diff --git a/public/assets/.sprockets-manifest-958e176a02f256e68a47070ec40c0726.json b/public/assets/.sprockets-manifest-958e176a02f256e68a47070ec40c0726.json | |
index cc7717d08..f34b73561 100644 | |
Binary files a/public/assets/.sprockets-manifest-958e176a02f256e68a47070ec40c0726.json and b/public/assets/.sprockets-manifest-958e176a02f256e68a47070ec40c0726.json differ | |
diff --git a/spec/controllers/spree/orders_controller_decorator_spec.rb b/spec/controllers/spree/orders_controller_decorator_spec.rb | |
index f64c54d0e..626f5561f 100644 | |
--- a/spec/controllers/spree/orders_controller_decorator_spec.rb | |
+++ b/spec/controllers/spree/orders_controller_decorator_spec.rb | |
@@ -43,7 +43,18 @@ RSpec.describe Spree::OrdersController, type: :controller do | |
allow(Spree::Variant).to receive(:find).with(variant_id).and_return(variant) | |
expect(Spree::OrderPopulator).to receive(:new).with(instance_of(Spree::Order), 'EUR').and_return(populator) | |
- expect(populator).to receive(:populate).with('1', '2', zone: @eur_zone).and_return(true) | |
+ | |
+ if Histreet::Store.current.has_feature? :optimize_add_to_cart | |
+ expect(populator).to receive(:populate).with( | |
+ '1', | |
+ '2', | |
+ zone: @eur_zone, | |
+ disable_erp_check: true, | |
+ ).and_return(true) | |
+ else | |
+ expect(populator).to receive(:populate).with('1', '2', zone: @eur_zone).and_return(true) | |
+ end | |
+ | |
expect { | |
spree_post :populate, { variant_id: variant_id, quantity: 2 }, {} | |
}.to change { Spree::Order.count }.by(1) | |
@@ -124,9 +135,18 @@ RSpec.describe Spree::OrdersController, type: :controller do | |
create(:zone_price_markup, zone: @eur_zone) | |
product_one = create(:product) | |
variant_one = create(:variant, product: product_one) | |
- product_one.stock_items.last.set_count_on_hand(1) | |
- allow_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(variant_one).and_return(10) | |
+ if Histreet::Store.current.has_feature? :optimize_add_to_cart | |
+ # if optimized it won't forcibly check the inventory system / ERP | |
+ # so we set the on_hand count to allow for both the calls | |
+ product_one.stock_items.last.set_count_on_hand(10) | |
+ else | |
+ # if NOT optimized it will forcibly check the inventory system / ERP | |
+ # and will add even if the db is telling use there's no availability | |
+ product_one.stock_items.last.set_count_on_hand(1) | |
+ allow_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(variant_one).and_return(10) | |
+ end | |
+ | |
expect { spree_post :populate, { variant_id: variant_one.id, quantity: 1 }, {} }.to change { @eur_zone.orders.count }.from(0).to(1) | |
expect(Spree::Order.count).to eq(1) | |
diff --git a/spec/stores/antonioli/features/flash_sale_spec.rb b/spec/stores/antonioli/features/flash_sale_spec.rb | |
index f88537e9c..607c2b7cd 100644 | |
--- a/spec/stores/antonioli/features/flash_sale_spec.rb | |
+++ b/spec/stores/antonioli/features/flash_sale_spec.rb | |
@@ -461,7 +461,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'Accessories' | |
click_on 'MARKETING TITLE' | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant)#.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
expect(current_path).to eq('/en/IT/cart') | |
expect(Spree::Order.unscoped.count).to eq(1) | |
@@ -490,7 +490,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'Accessories' | |
click_on 'MARKETING TITLE' | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant) #.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
click_on 'Checkout' | |
@@ -515,7 +515,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'Accessories' | |
click_on 'MARKETING TITLE' | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant)#.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
expect(current_path).to eq('/en/IT/cart') | |
@@ -554,7 +554,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'MARKETING TITLE' | |
expect(current_path).to eq("/en/IT/men/products/#{@test_variant.slug}") | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant)#.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
expect(current_path).to eq('/en/IT/cart') | |
click_on 'Checkout' | |
@@ -657,8 +657,6 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
end | |
scenario 'user fails to add multiple products multiple packages' do | |
- pending 'FIXME: fix in #2345 and merge in master (set to pending on 2017-09-01)' | |
- | |
@milano.stock_items.each { |si| si.update_columns(count_on_hand: 1, backorderable: false) } | |
@torino.stock_items.each { |si| si.update_columns(count_on_hand: 1, backorderable: false) } | |
@ibiza.stock_items.each { |si| si.update_columns(count_on_hand: 1, backorderable: false) } | |
@@ -675,6 +673,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'MARKETING TITLE' | |
expect(current_path).to eq("/en/IT/men/products/#{@variant_6_1.slug}") | |
choose('S') | |
+ | |
click_on 'Add to shopping bag' # milan | |
visit("/en/IT/men/products/#{@variant_6_1.slug}") | |
choose('S') | |
@@ -711,6 +710,8 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
sign_in_as_user(@user) | |
fill_in_billing_address_and_continue | |
expect(current_path).to eq('/en/IT/checkout/delivery') | |
+ | |
+ pending 'FIXME: fix in #2345 and merge in master (set to pending on 2017-09-01)' | |
expect(page).to have_content('DHL ITA / DHL Express Ship (2-3 Days) Free', count: 0) | |
expect(page).to have_content('DHL ITA / DHL Express Ship (2-3 Days) € 10,00') | |
expect(page).to have_content('Package 1') | |
@@ -789,7 +790,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
click_on 'MARKETING TITLE' | |
expect(current_path).to eq("/en/IT/men/products/#{@test_variant.slug}") | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant) #.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
expect(current_path).to eq('/en/IT/cart') | |
click_on 'Checkout' | |
@@ -830,7 +831,7 @@ RSpec.feature 'Antonioli: flash sale', :slowest do | |
scenario 'applies and removes packaging costs', slow: true do | |
visit "/en/IT/men/products/#{@test_variant.slug}" | |
choose('S') | |
- expect_any_instance_of(Beestore::Client).to receive(:availability_for_variant).with(@test_variant).and_return(1) | |
+ expect_any_instance_of(Beestore::Client).not_to receive(:availability_for_variant)#.with(@test_variant).and_return(1) | |
click_on 'Add to shopping bag' | |
check('order_hs_packaging') | |
click_on 'Checkout' | |
diff --git a/stores/antonioli/assets/javascripts/antonioli/actions.js.rb b/stores/antonioli/assets/javascripts/antonioli/actions.js.rb | |
index 5ba5cf87a..6bd801485 100644 | |
--- a/stores/antonioli/assets/javascripts/antonioli/actions.js.rb | |
+++ b/stores/antonioli/assets/javascripts/antonioli/actions.js.rb | |
@@ -216,18 +216,36 @@ module Antonioli::Actions | |
Timeout.new(3000) { $app.action! :cart_hide } | |
- Histreet::API.add_to_cart(variant_id).then do |data| | |
- Facebook.add_to_cart( | |
- variant_id: data[:variant_id], | |
- amount: data[:price].to_f.to_n, | |
- currency: data[:currency], | |
- ) | |
- Histreet::API.fetch_profile.then do |data| | |
- $app.action! :profile_update, data | |
- end.always do | |
+ Histreet::API.add_to_cart(variant_id).then do |add_to_cart_data| | |
+ if META['optimize_add_to_cart'] | |
+ p add_to_cart_data: add_to_cart_data | |
+ item_data = add_to_cart_data.fetch('line_item') | |
+ profile_data = add_to_cart_data.fetch('cart') | |
+ | |
+ Facebook.add_to_cart( | |
+ variant_id: item_data[:variant_id], | |
+ amount: item_data[:price].to_f.to_n, | |
+ currency: item_data[:currency], | |
+ ) | |
+ $app.action! :profile_update, profile_data | |
$app.trigger 'cart:added', variant_id | |
$app.data[:cart][:adding].delete(uuid) | |
$app.trigger 'cart:updated' | |
+ | |
+ else | |
+ item_data = add_to_cart_data | |
+ Facebook.add_to_cart( | |
+ variant_id: item_data[:variant_id], | |
+ amount: item_data[:price].to_f.to_n, | |
+ currency: item_data[:currency], | |
+ ) | |
+ Histreet::API.fetch_profile.then do |profile_data| | |
+ $app.action! :profile_update, profile_data | |
+ end.always do | |
+ $app.trigger 'cart:added', variant_id | |
+ $app.data[:cart][:adding].delete(uuid) | |
+ $app.trigger 'cart:updated' | |
+ end | |
end | |
end.fail do |data| | |
error_message = data[:errors] ? data[:errors] : data | |
diff --git a/stores/antonioli/assets/stylesheets/antonioli/_content.sass b/stores/antonioli/assets/stylesheets/antonioli/_content.sass | |
index 52f7f92f6..047d419cc 100644 | |
--- a/stores/antonioli/assets/stylesheets/antonioli/_content.sass | |
+++ b/stores/antonioli/assets/stylesheets/antonioli/_content.sass | |
@@ -34,6 +34,8 @@ | |
+font-size(13px) | |
+font-light | |
text-transform: uppercase | |
+ &.hide | |
+ display: none | |
+media($large-screen) | |
+font-size(15px) | |
> p | |
diff --git a/stores/antonioli/assets/stylesheets/antonioli/content/_products.sass b/stores/antonioli/assets/stylesheets/antonioli/content/_products.sass | |
index ee014396d..81500fa5d 100644 | |
--- a/stores/antonioli/assets/stylesheets/antonioli/content/_products.sass | |
+++ b/stores/antonioli/assets/stylesheets/antonioli/content/_products.sass | |
@@ -20,14 +20,20 @@ | |
height: auto | |
max-height: 500px | |
.title | |
- position: absolute | |
- top: -100px | |
+ // position: absolute | |
+ top: -70px | |
+ position: relative | |
left: 0 | |
- width: 100% | |
- height: 40px | |
+ width: auto | |
+ height: 20px | |
+ padding: 0 15px | |
overflow: hidden | |
- text-indent: -99999px | |
+ // text-indent: -99999px | |
text-transform: uppercase | |
+ display: inline-block | |
+ margin: 0 auto | |
+ +media($medium-screen) | |
+ top: -35px | |
+media($large-screen) | |
position: relative | |
top: -5px | |
@@ -35,15 +41,20 @@ | |
height: auto | |
display: inline-block | |
margin: 0 auto | |
+ padding: 0 | |
+font-size(13px) | |
+font-medium | |
cursor: pointer | |
line-height: 1 | |
overflow: initial | |
text-indent: inherit | |
- span | |
- +icon-plus | |
- position: absolute | |
+ z-index: 200 | |
+ span | |
+ +icon-plus | |
+ position: absolute | |
+ right: 0 | |
+ top: 3px | |
+ +media($large-screen) | |
right: -15px | |
top: 1px | |
@@ -61,7 +72,9 @@ | |
p | |
color: $grey-text | |
margin: 0 | |
- padding: $margin-desktop 10% 0 | |
+ padding: 0 10% $margin-desktop | |
+ +media($medium-screen) | |
+ padding: $margin-desktop 10% 0 | |
section.products | |
+grid-article(2,3,4,10,15,20) | |
@@ -285,9 +298,12 @@ | |
+media($large-screen) | |
display: none | |
.pagination | |
+ margin: 0 | |
+ padding-top: $margin*1.5 | |
+end | |
- margin-bottom: $margin | |
- margin-top: $margin*1.5 | |
text-align: right | |
+ +media($large-screen) | |
+ margin-bottom: $margin | |
+ // margin-top: $margin*1.5 | |
@import ./_products/not_found | |
diff --git a/stores/antonioli/views/application/_head.html.haml b/stores/antonioli/views/application/_head.html.haml | |
index 26c9da65d..66f782859 100644 | |
--- a/stores/antonioli/views/application/_head.html.haml | |
+++ b/stores/antonioli/views/application/_head.html.haml | |
@@ -26,6 +26,10 @@ | |
%meta(name="locale" content="#{current_locale}") | |
%meta(name="CART_PATH" content="#{cart_url}") | |
%meta(name="CHECKOUT_PATH" content="#{checkout_url}") | |
+ | |
+ - if histreet_store.has_feature? :optimize_add_to_cart | |
+ %meta(name="optimize_add_to_cart" content="true") | |
+ | |
- unless Rails.env.production? | |
%meta(name="DEBUG" content="true") | |
diff --git a/stores/antonioli/views/spree/products/_header.html.haml b/stores/antonioli/views/spree/products/_header.html.haml | |
index b135b1767..ef3a77e86 100644 | |
--- a/stores/antonioli/views/spree/products/_header.html.haml | |
+++ b/stores/antonioli/views/spree/products/_header.html.haml | |
@@ -2,7 +2,7 @@ | |
- self.title = meta_title[:"title_#{params[:gender]}"].presence || meta_title[:title_unisex].presence || presentation[:results_page_title] | |
%header | |
- %h1= presentation[:results_page_title] | |
+ %h1{class: ('hide' if presentation[:results_page_description].present?)}= presentation[:results_page_title] | |
- if presentation[:results_page_description].present? | |
%p= presentation[:results_page_description] | |
diff --git a/stores/dmagazine/assets/javascripts/dmagazine/repositories/top_designer_repository.rb b/stores/dmagazine/assets/javascripts/dmagazine/repositories/top_designer_repository.rb | |
index 385a263db..521c631eb 100644 | |
--- a/stores/dmagazine/assets/javascripts/dmagazine/repositories/top_designer_repository.rb | |
+++ b/stores/dmagazine/assets/javascripts/dmagazine/repositories/top_designer_repository.rb | |
@@ -9,7 +9,9 @@ class Dmagazine::TopDesignerRepository | |
end | |
def all | |
- (@visited_designers + @designers.shuffle).first(@designers.count).sort_by { |designer| designer[:name] } | |
+ (@visited_designers + @designers.shuffle).first(@designers.count) | |
+ .select { |designer| designer[:name] } | |
+ .sort_by { |designer| designer[:name] } | |
end | |
def each | |
diff --git a/stores/dmagazine/assets/javascripts/dmagazine/views/home_page.js.rb b/stores/dmagazine/assets/javascripts/dmagazine/views/home_page.js.rb | |
index b9d9faccd..0b394a741 100644 | |
--- a/stores/dmagazine/assets/javascripts/dmagazine/views/home_page.js.rb | |
+++ b/stores/dmagazine/assets/javascripts/dmagazine/views/home_page.js.rb | |
@@ -6,7 +6,7 @@ class Dmagazine::HomePage | |
self.selector = 'body.controller_home_pages' | |
LARGE_TOP_DESIGNERS_FIXED_AT = 105 #px | |
- MEDIUM_TOP_DESIGNERS_FIXED_AT = 195 #px | |
+ MEDIUM_TOP_DESIGNERS_FIXED_AT = 210 #px | |
on_document 'page:change' do | |
@current_gender = CurrentGender.new | |
@@ -51,7 +51,7 @@ class Dmagazine::HomePage | |
find("a[data-change-gender='#{@current_gender.code}']").add_class(:active) | |
find('a[data-change-menu-gender]').remove_class(:active) | |
find("a[data-change-menu-gender='#{@current_gender.code}']").add_class(:active) | |
- visited_designers = Dmagazine::VisitedDesignerRepository.new.designers_for(:generic) | |
+ visited_designers = Dmagazine::VisitedDesignerRepository.new.designers_for(@current_gender.code) | |
context = OpenStruct.new( | |
country: Dmagazine.country, | |
designers: Dmagazine::TopDesignerRepository.new(top_designers_attributes, visited_designers) | |
@@ -68,11 +68,11 @@ class Dmagazine::HomePage | |
end | |
def self.top_designers_element | |
- @top_designers_element ||= find('#top-designers') | |
+ @top_designers_element = find("#home-#{@current_gender.code} #top-designers") | |
end | |
def self.top_designers_attributes | |
- @top_designers_attributes ||= (top_designers_element.data('designers') || []).map do |designer| | |
+ @top_designers_attributes = (top_designers_element.data('designers') || []).map do |designer| | |
{ name: `designer.name`, url: `designer.url` } | |
end | |
end | |
@@ -96,7 +96,7 @@ class Dmagazine::HomePage | |
if Window.large? | |
40 | |
elsif Window.medium? | |
- 10 | |
+ 35 | |
end | |
end | |
diff --git a/stores/dmagazine/assets/javascripts/dmagazine/views/messages.js.rb b/stores/dmagazine/assets/javascripts/dmagazine/views/messages.js.rb | |
index c334e6e4a..0d75799b1 100644 | |
--- a/stores/dmagazine/assets/javascripts/dmagazine/views/messages.js.rb | |
+++ b/stores/dmagazine/assets/javascripts/dmagazine/views/messages.js.rb | |
@@ -6,6 +6,9 @@ class Dmagazine::Messages | |
event.prevent | |
find('aside#messages').hide | |
find('aside#messages').html("") | |
+ if find('.coupon-form').present? | |
+ find('.coupon-form input[type="text"]').value = '' | |
+ end | |
end | |
end | |
diff --git a/stores/dmagazine/assets/javascripts/templates/dmagazine/cart_error.js.haml b/stores/dmagazine/assets/javascripts/templates/dmagazine/cart_error.js.haml | |
index 2d4e1bc23..5ea0705b2 100644 | |
--- a/stores/dmagazine/assets/javascripts/templates/dmagazine/cart_error.js.haml | |
+++ b/stores/dmagazine/assets/javascripts/templates/dmagazine/cart_error.js.haml | |
@@ -1,12 +1,12 @@ | |
%button.close-cart-sidebar.js-close-cart | |
-:sass | |
- .box, ul, li, a | |
- font-size: 1.2rem | |
- a | |
- font-size: inherit !important | |
- font-weight: bold | |
- text-decoration: underline | |
+// :sass | |
+// .box, ul, li, a | |
+// font-size: 1.2rem | |
+// a | |
+// font-size: inherit !important | |
+// font-weight: bold | |
+// text-decoration: underline | |
.box | |
%header | |
diff --git a/stores/dmagazine/assets/stylesheets/dmagazine/_style_guides.sass b/stores/dmagazine/assets/stylesheets/dmagazine/_style_guides.sass | |
index e4a9f07c9..2f4d22226 100644 | |
--- a/stores/dmagazine/assets/stylesheets/dmagazine/_style_guides.sass | |
+++ b/stores/dmagazine/assets/stylesheets/dmagazine/_style_guides.sass | |
@@ -12,7 +12,7 @@ $border_size: 3px | |
width: 100% | |
&.catalog | |
- display: none | |
+ // display: none | |
+media($medium-screen) | |
display: flex | |
@@ -74,9 +74,10 @@ $border_size: 3px | |
.images | |
- display: inline-flex | |
+ display: none | |
+media($medium-screen) | |
+ display: inline-flex | |
justify-content: flex-end | |
a | |
diff --git a/stores/dmagazine/assets/stylesheets/dmagazine/content/_products.sass b/stores/dmagazine/assets/stylesheets/dmagazine/content/_products.sass | |
index 4a2ff473c..fcfe6c083 100644 | |
--- a/stores/dmagazine/assets/stylesheets/dmagazine/content/_products.sass | |
+++ b/stores/dmagazine/assets/stylesheets/dmagazine/content/_products.sass | |
@@ -27,12 +27,16 @@ | |
align-items: flex-start | |
margin-bottom: $margin | |
min-height: 35px | |
+ &:nth-child(2) | |
+ min-height: 0 | |
+media($medium-screen) | |
margin-top: 0 | |
margin-bottom: 0 | |
min-height: inherit | |
&:last-child | |
margin-top: 15px | |
+ &:nth-child(2) | |
+ min-height: inherit | |
+media($large-screen) | |
height: 25px | |
&:last-child | |
@@ -40,7 +44,7 @@ | |
&.style-guide-element | |
height: auto | |
- display: none | |
+ // display: none | |
+media($medium-screen) | |
display: flex | |
diff --git a/stores/dmagazine/views/application/_search_box.html.haml b/stores/dmagazine/views/application/_search_box.html.haml | |
index 9a857a52e..46c66d8b0 100644 | |
--- a/stores/dmagazine/views/application/_search_box.html.haml | |
+++ b/stores/dmagazine/views/application/_search_box.html.haml | |
@@ -1,10 +1,10 @@ | |
= form_tag spree.dmagazine_search_path, class: 'header-search js-header-search', method: :get do | |
%input(id="search_#{scope}" type="text" name="q" value="" placeholder="TYPE TO SEARCH" class="js-search-input") | |
- - current_gender = Dmagazine.current_gender || Dmagazine.male_code | |
- - [Dmagazine.male_code, Dmagazine.female_code].each do |gender_code| | |
- %span.custom-radio | |
- - checked = current_gender == gender_code | |
- %input(type="radio" name="gender" value="#{gender_code}" id="search_#{gender_code}_#{scope}" checked=checked) | |
- %label(for="search_#{gender_code}_#{scope}") | |
- = t(gender_code, scope: :genders, default: "Search in #{gender_code}") | |
+ - current_gender = Dmagazine.current_gender || Dmagazine.male_code | |
+ - [Dmagazine.male_code, Dmagazine.female_code].each do |gender_code| | |
+ %span.custom-radio | |
+ - checked = current_gender == gender_code | |
+ %input(type="radio" name="gender" value="#{gender_code}" id="search_#{gender_code}_#{scope}" checked=checked) | |
+ %label(for="search_#{gender_code}_#{scope}") | |
+ = t(gender_code, scope: :genders, default: "Search in #{gender_code}") | |
%input(type="submit" value="search") | |
diff --git a/stores/dmagazine/views/spree/home_pages/index.html.haml b/stores/dmagazine/views/spree/home_pages/index.html.haml | |
index 68dd995a2..f28332cde 100644 | |
--- a/stores/dmagazine/views/spree/home_pages/index.html.haml | |
+++ b/stores/dmagazine/views/spree/home_pages/index.html.haml | |
@@ -66,14 +66,14 @@ | |
Dolce & Gabbana, Valentino, Moschino, Brunello Cucinelli, Martin Margiela, | |
Ann Demeulemeester, Marcelo Burlon, Acne Studios and thousands more. | |
Our online catalog is updated every week with hundreds of new products to choose from. | |
- %p | |
+ %div | |
The Boutique Outlet Experience | |
%ul | |
%li Nearly 3000 national and international authenticated brands | |
%li Hundreds of new arrivals every week | |
%li Constant sales and promotions to benefit from | |
%li Clothing, shoes, bags and accessories for men and women | |
- %p | |
+ %div | |
The Customer Service Experience | |
%ul | |
%li Our multinational staff are available to help in more than 4 languages | |
diff --git a/stores/dmagazine/views/spree/order_mailer/cancel_email.html.erb b/stores/dmagazine/views/spree/order_mailer/cancel_email.html.erb | |
index 129b37ba0..475887de4 100644 | |
--- a/stores/dmagazine/views/spree/order_mailer/cancel_email.html.erb | |
+++ b/stores/dmagazine/views/spree/order_mailer/cancel_email.html.erb | |
@@ -31,7 +31,15 @@ | |
<%= Spree.t('order_mailer.cancel_email.instructions') %> | |
</p> | |
<p> | |
- <%= Spree.t('order_mailer.cancel_email.order_summary_canceled') %> | |
+ <span style="text-transform:uppercase;"> | |
+ <%= Spree.t('order_mailer.cancel_email.order_summary') %>: | |
+ </span> | |
+ <b><%= Spree.t('order_mailer.cancel_email.canceled') %></b> | |
+ <br /> | |
+ <span style="text-transform:uppercase;"> | |
+ <%= Spree.t('order_mailer.cancel_email.order_summary_reason') %>: | |
+ </span> | |
+ <b><%= @reason %></b> | |
</p> | |
<table width="650" border="0" cellpadding="0" cellspacing="0" style="margin-top: 30px;"> | |
<tr> | |
diff --git a/themes/savona_97/views/application/_head.html.haml b/themes/savona_97/views/application/_head.html.haml | |
index 1554de437..b7483f2d3 100644 | |
--- a/themes/savona_97/views/application/_head.html.haml | |
+++ b/themes/savona_97/views/application/_head.html.haml | |
@@ -44,4 +44,4 @@ | |
= yield :page_microformat_header_tags | |
-# FB wants to stay in HEAD | |
-= facebook_javascript_tag('168297763542229'.freeze) | |
+= facebook_javascript_tag(histreet_store.facebook_og_properties['pixel_helper_id']) | |
diff --git a/vendor/spree-06a7120d25d5/core/app/models/spree/promotion.rb b/vendor/spree-06a7120d25d5/core/app/models/spree/promotion.rb | |
index 73247ec01..7e29bfec2 100644 | |
--- a/vendor/spree-06a7120d25d5/core/app/models/spree/promotion.rb | |
+++ b/vendor/spree-06a7120d25d5/core/app/models/spree/promotion.rb | |
@@ -84,8 +84,8 @@ module Spree | |
action_taken = results.include?(true) | |
if action_taken | |
- # connect to the order | |
- # create the join_table entry. | |
+ # connect to the order | |
+ # create the join_table entry. | |
self.orders << order | |
self.save | |
end | |
@@ -109,25 +109,61 @@ module Spree | |
specific_rules = rules.select { |rule| rule.applicable?(promotable) } | |
return [] if specific_rules.none? | |
- rule_eligibility = Hash[specific_rules.map do |rule| | |
- [rule, rule.eligible?(promotable, options)] | |
- end] | |
- | |
- if match_all? | |
- # If there are rules for this promotion, but no rules for this | |
- # particular promotable, then the promotion is ineligible by default. | |
- unless rule_eligibility.values.all? | |
- @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?) | |
- return nil | |
- end | |
- specific_rules | |
+ if Histreet::Store.current.has_feature?(:optimize_promo_handler) | |
+ optimize = {} | |
+ optimize[:eligibility] = true if Histreet::Store.current.has_feature? :optimize_promo_eligibility | |
else | |
- unless rule_eligibility.values.any? | |
- @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?) | |
- return nil | |
+ optimize = false | |
+ end | |
+ optimize = $optimize if Rails.env.development? | |
+ | |
+ if optimize && optimize[:eligibility] | |
+ if match_all? | |
+ if specific_rules.all? { |rule| rule.eligible?(promotable, options) } | |
+ specific_rules | |
+ else | |
+ nil | |
+ end | |
+ else | |
+ if (eligible_rule = specific_rules.find { |rule| rule.eligible?(promotable, options) }) | |
+ eligible_rule | |
+ else | |
+ nil | |
+ end | |
end | |
+ else | |
+ | |
+ # bm = -> &block { | |
+ # r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) | |
+ # block.call | |
+ # Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0 | |
+ # } | |
+ # $rules ||= [] | |
+ rule_eligibility = Hash[specific_rules.map do |rule| | |
+ eligible = rule.eligible?(promotable, options) | |
+ # ms = bm.call { | |
+ # eligible = | |
+ # } | |
+ # $rules << [ms, eligible, rule.class.name, rule.id, promotable.class.name, promotable.id] | |
+ [rule, eligible] | |
+ end] | |
+ | |
+ if match_all? | |
+ # If there are rules for this promotion, but no rules for this | |
+ # particular promotable, then the promotion is ineligible by default. | |
+ unless rule_eligibility.values.all? | |
+ @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?) | |
+ return nil | |
+ end | |
+ specific_rules | |
+ else | |
+ unless rule_eligibility.values.any? | |
+ @eligibility_errors = specific_rules.map(&:eligibility_errors).detect(&:present?) | |
+ return nil | |
+ end | |
- [rule_eligibility.detect { |_, eligibility| eligibility }.first] | |
+ [rule_eligibility.detect { |_, eligibility| eligibility }.first] | |
+ end | |
end | |
end | |
@@ -185,7 +221,13 @@ module Spree | |
end | |
end | |
+ def match_all? | |
+ match_policy == 'all' | |
+ end | |
+ | |
+ | |
private | |
+ | |
def blacklisted?(promotable) | |
case promotable | |
when Spree::LineItem | |
@@ -201,9 +243,5 @@ module Spree | |
self[column] = nil if self[column].blank? | |
end | |
end | |
- | |
- def match_all? | |
- match_policy == 'all' | |
- end | |
end | |
end | |
diff --git a/vendor/spree-06a7120d25d5/core/app/models/spree/promotion_handler/cart.rb b/vendor/spree-06a7120d25d5/core/app/models/spree/promotion_handler/cart.rb | |
index 9a957b85e..e97a36659 100644 | |
--- a/vendor/spree-06a7120d25d5/core/app/models/spree/promotion_handler/cart.rb | |
+++ b/vendor/spree-06a7120d25d5/core/app/models/spree/promotion_handler/cart.rb | |
@@ -31,23 +31,73 @@ module Spree | |
private | |
def promotions | |
- # AR cannot bind raw ASTs to prepared statements. There always must be a manager around. | |
- # Also Postgresql requires an aliased table for `SELECT * FROM (subexpression) AS alias`. | |
- # And Sqlite3 cannot work on outher parenthesis from `(left UNION right)`. | |
- # So this construct makes both happy. | |
- select = Arel::SelectManager.new( | |
- Promotion, | |
- Promotion.arel_table.create_table_alias( | |
- order.promotions.active.union(Promotion.active.where(code: nil, path: nil)), | |
- Promotion.table_name | |
- ), | |
- ) | |
- select.project(Arel.star) | |
- | |
- Promotion.find_by_sql( | |
- select, | |
- order.promotions.bind_values | |
- ) | |
+ if Histreet::Store.current.has_feature? :optimize_promo_handler | |
+ optimize = {} | |
+ optimize[:zones] = true if Histreet::Store.current.has_feature? :optimize_promo_handler_zones | |
+ optimize[:users] = true if Histreet::Store.current.has_feature? :optimize_promo_handler_users | |
+ else | |
+ optimize = false | |
+ end | |
+ optimize = $optimize if Rails.env.development? && defined?($optimize) | |
+ | |
+ if optimize | |
+ promos = ( | |
+ Promotion.active.where(code: nil, path: nil).to_a + | |
+ order.promotions.active.to_a | |
+ ).uniq | |
+ | |
+ promos = exclude_promos_unapplicable_for_zone(promos, order.zone) if optimize[:zones] | |
+ promos = exclude_promos_only_applicable_to_user(promos, order.user_id) if optimize[:users] | |
+ | |
+ else | |
+ # AR cannot bind raw ASTs to prepared statements. There always must be a manager around. | |
+ # Also Postgresql requires an aliased table for `SELECT * FROM (subexpression) AS alias`. | |
+ # And Sqlite3 cannot work on outher parenthesis from `(left UNION right)`. | |
+ # So this construct makes both happy. | |
+ select = Arel::SelectManager.new( | |
+ Promotion, | |
+ Promotion.arel_table.create_table_alias( | |
+ order.promotions.active.union(Promotion.active.where(code: nil, path: nil)), | |
+ Promotion.table_name | |
+ ), | |
+ ) | |
+ select.project(Arel.star) | |
+ promos = Promotion.find_by_sql( | |
+ select, | |
+ order.promotions.bind_values | |
+ ) | |
+ end | |
+ # print "--P#{promos.size}--" | |
+ # Rails.logger.info "optimization: #{optimize.inspect}, promos: #{promos.size}" | |
+ promos | |
+ end | |
+ | |
+ def exclude_promos_unapplicable_for_zone promos, zone | |
+ in_current_zone = ::Spree::Promotion::Rules::Zone.where( | |
+ id: ::Histreet::ZonesPromotionRules.where(zone: zone).select(:promotion_rule_id) | |
+ ).distinct.pluck(:promotion_id) | |
+ | |
+ with_zone_rule = ::Spree::Promotion::Rules::Zone.distinct.pluck(:promotion_id) | |
+ | |
+ promos.reject do |promo| | |
+ promo.match_all? && | |
+ with_zone_rule.include?(promo.id) && | |
+ not(in_current_zone.include?(promo.id)) | |
+ end | |
+ end | |
+ | |
+ def exclude_promos_only_applicable_to_user promos, user_id | |
+ for_current_user = ::Spree::Promotion::Rules::User.where( | |
+ 'id IN (SELECT DISTINCT promotion_rule_id FROM spree_promotion_rules_users WHERE user_id = ?)', user_id | |
+ ).distinct.pluck(:promotion_id) | |
+ | |
+ with_user_rule = ::Spree::Promotion::Rules::User.distinct.pluck(:promotion_id) | |
+ | |
+ promos.reject do |promo| | |
+ promo.match_all? && | |
+ with_user_rule.include?(promo.id) && | |
+ not(for_current_user.include?(promo.id)) | |
+ end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment