Merge pull request #8841 from apricot12/8790_display_stock_left_shop

Display remaining stock in shopfront if enabled in shop preferences
This commit is contained in:
Filipe
2022-04-15 17:58:40 +01:00
committed by GitHub
11 changed files with 59 additions and 18 deletions

View File

@@ -1,4 +1,4 @@
angular.module('Darkswarm').controller "ShopVariantCtrl", ($scope, $modal, Cart) ->
angular.module('Darkswarm').controller "ShopVariantCtrl", ($scope, $modal, Cart, Shopfront) ->
$scope.updateCart = (line_item) ->
Cart.adjust($scope.variant.line_item)
@@ -69,3 +69,6 @@ angular.module('Darkswarm').controller "ShopVariantCtrl", ($scope, $modal, Cart)
$scope.addBulk = (quantity) ->
$scope.add(quantity)
$modal.open(templateUrl: "bulk_buy_modal.html", scope: $scope, windowClass: "product-bulk-modal")
$scope.displayRemainingInStock = ->
Shopfront.shopfront.preferred_product_low_stock_display && $scope.available() <= 3 && !$scope.variant.line_item.quantity

View File

@@ -20,6 +20,7 @@ class Enterprise < ApplicationRecord
preference :shopfront_order_cycle_order, :string, default: "orders_close_at"
preference :shopfront_product_sorting_method, :string, default: "by_category"
preference :invoice_order_by_supplier, :boolean, default: false
preference :product_low_stock_display, :boolean, default: false
# Allow hubs to restrict visible variants to only those in their inventory
preference :product_selection_from_inventory_only, :boolean, default: false

View File

@@ -13,7 +13,8 @@ module Api
:default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes,
:logo, :promo_image, :terms_and_conditions,
:terms_and_conditions_file_name, :terms_and_conditions_updated_at,
:preferred_invoice_order_by_supplier
:preferred_invoice_order_by_supplier,
:preferred_product_low_stock_display
has_one :owner, serializer: Api::Admin::UserSerializer
has_many :users, serializer: Api::Admin::UserSerializer

View File

@@ -9,7 +9,7 @@ module Api
:instagram, :linkedin, :twitter, :facebook, :is_primary_producer, :is_distributor,
:phone, :visible, :email_address, :hash, :logo, :promo_image, :path, :category,
:active, :producers, :orders_close_at, :hubs, :taxons, :supplied_taxons, :pickup,
:delivery
:delivery, :preferred_product_low_stock_display
has_one :address, serializer: Api::AddressSerializer
has_many :supplied_properties, serializer: Api::PropertySerializer

View File

@@ -34,6 +34,7 @@ module PermittedAttributes
:preferred_shopfront_producer_order, :preferred_shopfront_order_cycle_order,
:show_customer_names_to_suppliers, :preferred_shopfront_product_sorting_method,
:preferred_invoice_order_by_supplier,
:preferred_product_low_stock_display
]
end
end

View File

@@ -61,18 +61,29 @@
%label= t '.allow_guest_orders'
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
%a= t 'admin.whats_this'
.eight.columns.omega
.row
.three.columns.alpha
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
.five.columns.omega
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
.eight.columns.alpha.omega
%i.icon-warning-sign
= t '.recommend_require_login'
.three.columns
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
.five.columns.omega
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
.eight.columns.alpha.omega
%i.icon-warning-sign
= t '.recommend_require_login'
.row
.three.columns.alpha
%label= t '.display_remaining_stock'
%div{'ofn-with-tip' => t('.display_remaining_stock_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :preferred_product_low_stock_display, true, 'ng-model' => 'Enterprise.preferred_product_low_stock_display', 'ng-value' => 'true'
= f.label :preferred_product_low_stock_display, t('.enabled'), value: :true
.five.columns.omega
= f.radio_button :preferred_product_low_stock_display, false, 'ng-model' => 'Enterprise.preferred_product_low_stock_display', 'ng-value' => 'false'
= f.label :preferred_product_low_stock_display, t('.disabled'), value: :false
.row
.three.columns.alpha
%label= t '.allow_order_changes'

View File

@@ -13,6 +13,8 @@
%button.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
-# U+FF0B Fullwidth Plus Sign
.variant-remaining-stock{ng: {if: "displayRemainingInStock()"}}
{{ "js.shopfront.variant.remaining_in_stock" | t:{quantity: available()} }}
.variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}}
{{ "js.shopfront.variant.quantity_in_cart" | t:{quantity: variant.line_item.quantity || 0} }}
%input{type: :hidden,

View File

@@ -71,12 +71,15 @@ button.variant-quantity {
}
}
.variant-quantity-display {
display: inline-block;
.variant-quantity-display, .variant-remaining-stock {
font-size: 0.875em;
margin-top: 0.25em;
text-align: center;
width: 7rem;
display: inline-block;
}
.variant-quantity-display {
visibility: hidden;
&.visible {
@@ -84,6 +87,10 @@ button.variant-quantity {
}
}
.variant-remaining-stock {
color: $red-500;
}
button.bulk-buy.variant-quantity {
background-color: transparent;
border: .1em solid $grey-200;

View File

@@ -977,6 +977,10 @@ en:
shopfront_sort_by_producer: "By producer"
shopfront_sort_by_category_placeholder: "Category"
shopfront_sort_by_producer_placeholder: "Producer"
display_remaining_stock: "Display remaining stock in shopfront if low on-hand"
display_remaining_stock_tip: "Let shoppers know when there are only 3 or less items left."
enabled: "Enabled"
disabled: "Disabled"
social:
twitter_placeholder: "eg. @the_prof"
instagram_placeholder: "eg. the_prof"
@@ -3104,6 +3108,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
add_to_cart: "Add"
in_cart: "in cart"
quantity_in_cart: "%{quantity} in cart"
remaining_in_stock: "Only %{quantity} left"
bulk_buy_modal:
min_quantity: "Min quantity"
max_quantity: "Max quantity"

View File

@@ -20,7 +20,7 @@ describe "ShopVariantCtrl", ->
CartMock =
adjust: ->
true
ctrl = $controller 'ShopVariantCtrl', {$scope: scope, $modal: $modal, Cart: CartMock}
ctrl = $controller 'ShopVariantCtrl', {$scope: scope, $modal: $modal, Cart: CartMock, Shopfront: {}}
it "initializes the quantity for shop display", ->
expect(scope.variant.line_item.quantity).toEqual 0

View File

@@ -376,6 +376,16 @@ describe "As a consumer I want to shop with a distributor", js: true do
end
end
it "shows quantity of remaining stock for products with quantity less < 3 when product_stock_display is true" do
distributor.set_preference(:product_low_stock_display, true)
variant.update on_hand: 2
visit shop_path
within_variant(variant) do
expect(page).to have_content "Only 2 left"
end
end
it "alerts us when we enter a quantity greater than the stock available" do
variant.update on_hand: 5
visit shop_path