mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-22 20:16:50 +00:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49de11567b | ||
|
|
3af0365c6b | ||
|
|
be92b0049b | ||
|
|
a1c94d0d9f | ||
|
|
f6bb8a9a04 | ||
|
|
d254df7ccc | ||
|
|
8caf10f634 | ||
|
|
2966dd9536 | ||
|
|
21e1c0ed0b | ||
|
|
48b99d02b9 | ||
|
|
f17a2eeaea | ||
|
|
18419d0276 | ||
|
|
bd19d8b0bd | ||
|
|
4bcd665379 | ||
|
|
e63dbcfa89 | ||
|
|
c3283adcf5 | ||
|
|
b2ed69831b | ||
|
|
7daba62f43 | ||
|
|
a08020490d | ||
|
|
eb4d970bc7 | ||
|
|
7a3549209f | ||
|
|
52ebd1b402 | ||
|
|
a3a26f704f | ||
|
|
cff8f6dd96 | ||
|
|
81537d92cf | ||
|
|
91e88bd028 | ||
|
|
f5e254a105 | ||
|
|
b41b5d0395 | ||
|
|
296d2e5edb | ||
|
|
ac0a62e962 | ||
|
|
2c5db8935b | ||
|
|
24c8f38111 | ||
|
|
b801bffcd9 | ||
|
|
434b68b019 | ||
|
|
9af4bb9757 | ||
|
|
d847560d7c | ||
|
|
87fae15434 | ||
|
|
e27f7a4301 | ||
|
|
bddfa95eb5 | ||
|
|
ef0fb18fda | ||
|
|
87ee4bbebc | ||
|
|
f5567e556b | ||
|
|
54c3c73ed2 | ||
|
|
8dfdc9bc15 | ||
|
|
36aa52736a | ||
|
|
ac38b2735c | ||
|
|
8b93c5ab56 | ||
|
|
434f98fb46 | ||
|
|
c82c54873c | ||
|
|
de180d32bf | ||
|
|
5b481c19cc | ||
|
|
7110f9e6ee | ||
|
|
63d748b2a4 | ||
|
|
310906c7da | ||
|
|
b81843921b | ||
|
|
dd0e135a4d | ||
|
|
0f2c5d379a | ||
|
|
a29f263041 | ||
|
|
0b878dd0a2 | ||
|
|
45c204017f | ||
|
|
fa98a8ea17 | ||
|
|
7582df2771 | ||
|
|
c788f1ae57 | ||
|
|
7baa875a91 | ||
|
|
3de887e1d8 | ||
|
|
1382bb3c6b |
@@ -499,7 +499,7 @@ GEM
|
||||
parallel (1.19.1)
|
||||
paranoia (1.3.4)
|
||||
activerecord (~> 3.1)
|
||||
parser (2.7.0.4)
|
||||
parser (2.7.0.5)
|
||||
ast (~> 2.4.0)
|
||||
paypal-sdk-core (0.2.10)
|
||||
multi_json (~> 1.0)
|
||||
@@ -612,7 +612,8 @@ GEM
|
||||
rexml
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 1.7)
|
||||
rubocop-rails (2.4.2)
|
||||
rubocop-rails (2.5.0)
|
||||
activesupport
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 0.72.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
@@ -671,7 +672,7 @@ GEM
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.6.1)
|
||||
unicorn (5.5.3)
|
||||
unicorn (5.5.4)
|
||||
kgio (~> 2.6)
|
||||
raindrops (~> 0.7)
|
||||
unicorn-rails (2.2.1)
|
||||
|
||||
@@ -35,7 +35,7 @@ We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. B
|
||||
Copyright (c) 2012 - 2020 Open Food Foundation, released under the AGPL licence.
|
||||
|
||||
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
|
||||
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/enQtNzY3NDEwNzM2MDM0LWFmNGRhNDUwYzNmNWNkYmFkMzgxNDg1OTg1ODNjNWY4Y2FhNDIwNmE4ZWI0OThiMGNmZjFkODczNGZiYTJmNWI
|
||||
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/zt-9sjkjdlu-r02kUMP1zbrTgUhZhYPF~A
|
||||
[contributor-guide]: https://ofn-user-guide.gitbook.io/ofn-contributor-guide/who-are-we
|
||||
[ofn-install]: https://github.com/openfoodfoundation/ofn-install
|
||||
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide
|
||||
|
||||
@@ -1,77 +1,13 @@
|
||||
@import "typography";
|
||||
|
||||
.darkswarm navigation {
|
||||
display: block;
|
||||
background: $white;
|
||||
|
||||
distributor.details {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
min-height: 150px;
|
||||
padding: 30px 0 20px 0;
|
||||
position: relative;
|
||||
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
location {
|
||||
@include headingFont;
|
||||
}
|
||||
@media all and (max-width: 768px) {
|
||||
location, location + small {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
#distributor_title h3 {
|
||||
margin-top: 0;
|
||||
padding-top: 0.45em;
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ordercycle {
|
||||
float: right;
|
||||
background: $teal-400;
|
||||
color: $white;
|
||||
background: $grey-050;
|
||||
color: $grey-800;
|
||||
width: 100%;
|
||||
border-radius: 0.5em 0.5em 0 0;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
padding: 1em;
|
||||
margin-top: 3em;
|
||||
height: 7.6em;
|
||||
|
||||
&.requires-selection {
|
||||
background-color: $red-700;
|
||||
|
||||
.order-cycle-select {
|
||||
border: 1px solid $red-500;
|
||||
|
||||
.select-label {
|
||||
background-color: rgba($red-500, 0.5);
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: $white;
|
||||
background-image: url('/assets/black-caret.svg');
|
||||
color: $grey-500;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-top: 1em;
|
||||
padding: 1em 1.25em 0;
|
||||
|
||||
p {
|
||||
max-width: 400px;
|
||||
@@ -97,14 +33,10 @@ ordercycle {
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
@media all and (max-width: 480px) {
|
||||
padding: 0.5em 1em 0.75em;
|
||||
}
|
||||
|
||||
form.custom {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.order-cycle-select {
|
||||
border: 1px solid $teal-300;
|
||||
display: inline-block;
|
||||
@@ -164,9 +96,44 @@ ordercycle {
|
||||
|
||||
closing {
|
||||
@include headingFont;
|
||||
color: $white;
|
||||
color: $grey-800;
|
||||
font-size: 1.25rem;
|
||||
display: block;
|
||||
padding: 0.5em 0;
|
||||
|
||||
span {
|
||||
@media all and (max-width: 768px) {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shop ordercycle {
|
||||
background: $teal-400;
|
||||
color: $white;
|
||||
|
||||
&.requires-selection {
|
||||
background-color: $red-700;
|
||||
|
||||
.order-cycle-select {
|
||||
border: 1px solid $red-500;
|
||||
|
||||
.select-label {
|
||||
background-color: rgba($red-500, 0.5);
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: $white;
|
||||
background-image: url('/assets/black-caret.svg');
|
||||
color: $grey-500;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closing {
|
||||
color: $white;
|
||||
padding: 0 0 12px;
|
||||
|
||||
@media all and (max-width: 1024px) {
|
||||
@@ -181,11 +148,25 @@ ordercycle {
|
||||
float: none;
|
||||
padding: 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
@media all and (max-width: 768px) {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
form.custom {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
shop navigation ordercycle {
|
||||
margin-top: 3em;
|
||||
padding: 1em;
|
||||
height: 7.6em;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
}
|
||||
|
||||
.sub-header {
|
||||
form {
|
||||
p {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,6 @@
|
||||
@import "mixins";
|
||||
@import "branding";
|
||||
|
||||
// .darkswarm
|
||||
// product
|
||||
|
||||
ordercycle {
|
||||
.joyride-tip-guide {
|
||||
background-color: $clr-brick;
|
||||
|
||||
.joyride-nub.right {
|
||||
border-color: $clr-brick !important;
|
||||
border-top-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pop over
|
||||
// Foundation overrides
|
||||
.joyride-tip-guide.price_breakdown {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
products .filter-box {
|
||||
background: #f7f7f7;
|
||||
background: $grey-050;
|
||||
}
|
||||
|
||||
.filter-box {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
$ofn-brand: #f27052;
|
||||
|
||||
$distributor-header-shadow: 0 1px 0 rgba(0, 0, 0, 0.05), 0 8px 6px -6px rgba(0, 0, 0, 0.2);
|
||||
|
||||
// e.g. australia, uk, norway specific color
|
||||
|
||||
$ofn-grey: #808184;
|
||||
@@ -39,6 +41,8 @@ $light-grey-transparency: rgba(0, 0, 0, .1);
|
||||
$black: #000;
|
||||
$white: #fff;
|
||||
|
||||
$grey-050: #f7f7f7;
|
||||
|
||||
$grey-400: #bbb;
|
||||
$grey-500: #999;
|
||||
$grey-600: #777;
|
||||
|
||||
@@ -44,7 +44,7 @@ checkout {
|
||||
h5 {
|
||||
margin: 0;
|
||||
padding: 0.65em;
|
||||
background: #f7f7f7;
|
||||
background: $grey-050;
|
||||
|
||||
.label {
|
||||
font-size: 1em;
|
||||
|
||||
52
app/assets/stylesheets/darkswarm/distributor_header.css.scss
Normal file
52
app/assets/stylesheets/darkswarm/distributor_header.css.scss
Normal file
@@ -0,0 +1,52 @@
|
||||
@import 'typography';
|
||||
|
||||
section {
|
||||
:not(shop) navigation {
|
||||
box-shadow: $distributor-header-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.darkswarm navigation {
|
||||
display: block;
|
||||
background: $white;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.details {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
min-height: 150px;
|
||||
padding: 30px 0 0;
|
||||
position: relative;
|
||||
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
location {
|
||||
@include headingFont;
|
||||
}
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
location, location + small {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
#distributor_title h3 {
|
||||
margin-top: 0;
|
||||
padding-top: 0.45em;
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
.tab-buttons {
|
||||
color: $dark-grey;
|
||||
box-shadow: 0 1px 0 rgba(0,0,0,0.05), 0 8px 6px -6px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: $distributor-header-shadow;
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
|
||||
@@ -32,6 +32,12 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@object = Enterprise.where(permalink: params[:id]).
|
||||
includes(users: [:ship_address, :bill_address]).first
|
||||
super
|
||||
end
|
||||
|
||||
def welcome
|
||||
render layout: "spree/layouts/bare_admin"
|
||||
end
|
||||
@@ -172,12 +178,14 @@ module Admin
|
||||
end
|
||||
|
||||
def load_methods_and_fees
|
||||
enterprise_payment_methods = @enterprise.payment_methods.to_a
|
||||
enterprise_shipping_methods = @enterprise.shipping_methods.to_a
|
||||
# rubocop:disable Style/TernaryParentheses
|
||||
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).sort_by! do |pm|
|
||||
[(@enterprise.payment_methods.include? pm) ? 0 : 1, pm.name]
|
||||
[(enterprise_payment_methods.include? pm) ? 0 : 1, pm.name]
|
||||
end
|
||||
@shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user).sort_by! do |sm|
|
||||
[(@enterprise.shipping_methods.include? sm) ? 0 : 1, sm.name]
|
||||
[(enterprise_shipping_methods.include? sm) ? 0 : 1, sm.name]
|
||||
end
|
||||
# rubocop:enable Style/TernaryParentheses
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class CustomersController < BaseController
|
||||
class CustomersController < Api::BaseController
|
||||
skip_authorization_check only: :index
|
||||
|
||||
def index
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class EnterpriseAttachmentController < BaseController
|
||||
class EnterpriseAttachmentController < Api::BaseController
|
||||
class MissingImplementationError < StandardError; end
|
||||
class UnknownEnterpriseAuthorizationActionError < StandardError; end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class EnterpriseFeesController < BaseController
|
||||
class EnterpriseFeesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class LogosController < EnterpriseAttachmentController
|
||||
class LogosController < Api::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class OrderCyclesController < BaseController
|
||||
class OrderCyclesController < Api::BaseController
|
||||
include EnterprisesHelper
|
||||
respond_to :json
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class OrdersController < BaseController
|
||||
class OrdersController < Api::BaseController
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class ProductImagesController < BaseController
|
||||
class ProductImagesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def update_product_image
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Api
|
||||
class PromoImagesController < EnterpriseAttachmentController
|
||||
class PromoImagesController < Api::EnterpriseAttachmentController
|
||||
private
|
||||
|
||||
def attachment_name
|
||||
|
||||
@@ -8,7 +8,7 @@ class ProducersController < BaseController
|
||||
.activated
|
||||
.visible
|
||||
.is_primary_producer
|
||||
.includes(address: :state)
|
||||
.includes(address: [:state, :country])
|
||||
.includes(:properties)
|
||||
.includes(supplied_products: :properties)
|
||||
.all
|
||||
|
||||
@@ -8,7 +8,7 @@ class ShopsController < BaseController
|
||||
.activated
|
||||
.visible
|
||||
.is_distributor
|
||||
.includes(address: :state)
|
||||
.includes(address: [:state, :country])
|
||||
.includes(:properties)
|
||||
.includes(supplied_products: :properties)
|
||||
.all
|
||||
|
||||
@@ -109,7 +109,10 @@ module Spree
|
||||
private
|
||||
|
||||
def load_order
|
||||
@order = Order.find_by_number!(params[:id], include: :adjustments) if params[:id]
|
||||
if params[:id]
|
||||
@order = Order.includes(:adjustments, :shipments, line_items: :adjustments).
|
||||
find_by_number!(params[:id])
|
||||
end
|
||||
authorize! action, @order
|
||||
end
|
||||
|
||||
@@ -128,7 +131,7 @@ module Spree
|
||||
def load_distribution_choices
|
||||
@shops = Enterprise.is_distributor.managed_by(spree_current_user).by_name
|
||||
|
||||
ocs = OrderCycle.managed_by(spree_current_user)
|
||||
ocs = OrderCycle.includes(:suppliers, :distributors).managed_by(spree_current_user)
|
||||
@order_cycles = ocs.soonest_closing +
|
||||
ocs.soonest_opening +
|
||||
ocs.closed +
|
||||
|
||||
@@ -3,10 +3,10 @@ require 'open_food_network/enterprise_injection_data'
|
||||
module InjectionHelper
|
||||
include SerializerHelper
|
||||
|
||||
def inject_enterprises(enterprises = Enterprise.activated.includes(address: :state).all)
|
||||
def inject_enterprises(enterprises = nil)
|
||||
inject_json_ams(
|
||||
"enterprises",
|
||||
enterprises,
|
||||
enterprises || default_enterprise_query,
|
||||
Api::EnterpriseSerializer,
|
||||
enterprise_injection_data
|
||||
)
|
||||
@@ -17,7 +17,10 @@ module InjectionHelper
|
||||
|
||||
inject_json_ams(
|
||||
"groups",
|
||||
EnterpriseGroup.on_front_page.by_position.select(select_only).includes(address: :state).all,
|
||||
EnterpriseGroup.on_front_page.by_position.select(select_only).
|
||||
includes(enterprises: [:shipping_methods, { address: [:state, :country] }],
|
||||
address: :state).
|
||||
all,
|
||||
Api::GroupListSerializer
|
||||
)
|
||||
end
|
||||
@@ -35,13 +38,21 @@ module InjectionHelper
|
||||
|
||||
inject_json_ams(
|
||||
"enterprises",
|
||||
Enterprise.activated.visible.select(select_only).includes(address: :state).all,
|
||||
Enterprise.activated.visible.select(select_only).includes(address: [:state, :country]).all,
|
||||
Api::EnterpriseShopfrontListSerializer
|
||||
)
|
||||
end
|
||||
|
||||
def inject_enterprise_and_relatives
|
||||
inject_json_ams "enterprises", current_distributor.relatives_including_self.activated.includes(address: :state).all, Api::EnterpriseSerializer, enterprise_injection_data
|
||||
enterprises_and_relatives = current_distributor.
|
||||
relatives_including_self.
|
||||
activated.
|
||||
includes(address: [:state, :country]).
|
||||
all
|
||||
|
||||
inject_json_ams "enterprises",
|
||||
enterprises_and_relatives,
|
||||
Api::EnterpriseSerializer, enterprise_injection_data
|
||||
end
|
||||
|
||||
def inject_group_enterprises
|
||||
@@ -138,6 +149,10 @@ module InjectionHelper
|
||||
|
||||
private
|
||||
|
||||
def default_enterprise_query
|
||||
Enterprise.activated.includes(address: [:state, :country]).all
|
||||
end
|
||||
|
||||
def enterprise_injection_data
|
||||
@enterprise_injection_data ||= OpenFoodNetwork::EnterpriseInjectionData.new
|
||||
{ data: @enterprise_injection_data }
|
||||
|
||||
@@ -5,5 +5,21 @@ module Spree
|
||||
def variant_options(v, _options = {})
|
||||
v.options_text
|
||||
end
|
||||
|
||||
# Overriden to eager-load :states
|
||||
def available_countries
|
||||
checkout_zone = Zone.find_by_name(Spree::Config[:checkout_zone])
|
||||
|
||||
countries = if checkout_zone && checkout_zone.kind == 'country'
|
||||
checkout_zone.country_list
|
||||
else
|
||||
Country.includes(:states).all
|
||||
end
|
||||
|
||||
countries.collect do |country|
|
||||
country.name = Spree.t(country.iso, scope: 'country_names', default: country.name)
|
||||
country
|
||||
end.sort { |a, b| a.name <=> b.name }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,6 +54,8 @@ module Calculator
|
||||
# Customer ends up getting 350mL (line_item.final_weight_volume) of wine
|
||||
# that represent 2.8 (quantity_implied_in_final_weight_volume) glasses of wine
|
||||
def quantity_implied_in_final_weight_volume(line_item)
|
||||
return line_item.quantity if line_item.variant.unit_value.to_f.zero?
|
||||
|
||||
(1.0 * line_item.final_weight_volume / line_item.variant.unit_value).round(3)
|
||||
end
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ Spree::LineItem.class_eval do
|
||||
end
|
||||
}
|
||||
|
||||
scope :in_orders, lambda { |orders|
|
||||
where(order_id: orders)
|
||||
}
|
||||
|
||||
# Find line items that are from order sorted by variant name and unit value
|
||||
scope :sorted_by_name_and_unit_value, -> {
|
||||
joins(variant: :product).
|
||||
|
||||
@@ -24,8 +24,10 @@ module Stock
|
||||
#
|
||||
# @return [Array<Spree::ShippingMethod>]
|
||||
def shipping_methods
|
||||
super.delete_if do |shipping_method|
|
||||
!ships_with?(order.distributor, shipping_method)
|
||||
available_shipping_methods = super.to_a
|
||||
|
||||
available_shipping_methods.keep_if do |shipping_method|
|
||||
ships_with?(order.distributor.shipping_methods.to_a, shipping_method)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,11 +35,11 @@ module Stock
|
||||
|
||||
# Checks whether the given distributor provides the specified shipping method
|
||||
#
|
||||
# @param distributor [Spree::Enterprise]
|
||||
# @param shipping_methods [Array<Spree::ShippingMethod>]
|
||||
# @param shipping_method [Spree::ShippingMethod]
|
||||
# @return [Boolean]
|
||||
def ships_with?(distributor, shipping_method)
|
||||
distributor.shipping_methods.include?(shipping_method)
|
||||
def ships_with?(shipping_methods, shipping_method)
|
||||
shipping_methods.include?(shipping_method)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -107,7 +107,7 @@ module Api
|
||||
end
|
||||
|
||||
def active
|
||||
data.active_distributors.andand.include? enterprise
|
||||
data.active_distributor_ids.andand.include? enterprise.id
|
||||
end
|
||||
|
||||
# Map svg icons.
|
||||
|
||||
@@ -9,7 +9,7 @@ module Api
|
||||
end
|
||||
|
||||
def active
|
||||
options[:data].active_distributors.andand.include? object
|
||||
options[:data].active_distributor_ids.andand.include? object.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,24 +2,28 @@ require 'open_food_network/permissions'
|
||||
|
||||
module Permissions
|
||||
class Order
|
||||
def initialize(user)
|
||||
def initialize(user, search_params = nil)
|
||||
@user = user
|
||||
@permissions = OpenFoodNetwork::Permissions.new(@user)
|
||||
@search_params = search_params
|
||||
end
|
||||
|
||||
# Find orders that the user can see
|
||||
def visible_orders
|
||||
Spree::Order.
|
||||
orders = Spree::Order.
|
||||
with_line_items_variants_and_products_outer.
|
||||
where(visible_orders_where_values)
|
||||
|
||||
filtered_orders(orders)
|
||||
end
|
||||
|
||||
# Any orders that the user can edit
|
||||
def editable_orders
|
||||
Spree::Order.where(
|
||||
managed_orders_where_values.
|
||||
or(coordinated_orders_where_values)
|
||||
)
|
||||
orders = Spree::Order.
|
||||
where(managed_orders_where_values.
|
||||
or(coordinated_orders_where_values))
|
||||
|
||||
filtered_orders(orders)
|
||||
end
|
||||
|
||||
def visible_line_items
|
||||
@@ -35,6 +39,18 @@ module Permissions
|
||||
|
||||
private
|
||||
|
||||
attr_reader :search_params
|
||||
|
||||
def filtered_orders(orders)
|
||||
return orders unless filter_orders?
|
||||
|
||||
orders.complete.not_state(:canceled).search(search_params).result
|
||||
end
|
||||
|
||||
def filter_orders?
|
||||
search_params.present?
|
||||
end
|
||||
|
||||
def visible_orders_where_values
|
||||
# Grouping keeps the 2 where clauses from produced_orders_where_values inside parentheses
|
||||
# This way it makes the OR work between the 3 types of orders:
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
.darkswarm.footer-pad
|
||||
- content_for :order_cycle_form do
|
||||
|
||||
%closing
|
||||
= t :checkout_now
|
||||
%p
|
||||
@@ -15,16 +14,23 @@
|
||||
%strong
|
||||
= pickup_time current_order_cycle
|
||||
|
||||
= render partial: "shopping_shared/header", locals: { hide_oc_selector: true }
|
||||
- content_for :ordercycle_sidebar do
|
||||
.show-for-large-up.large-4.columns
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
= render partial: "shopping_shared/header"
|
||||
|
||||
.sub-header.show-for-medium-down
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
%accordion{"close-others" => "false"}
|
||||
%checkout.row{"ng-controller" => "CheckoutCtrl"}
|
||||
.small-12.medium-8.large-9.columns
|
||||
.small-12.medium-8.columns
|
||||
- unless spree_current_user
|
||||
= render partial: "checkout/authentication"
|
||||
%div{"ng-show" => "enabled", "ng-controller" => "AccordionCtrl"}
|
||||
= render partial: "checkout/form"
|
||||
.small-12.medium-4.large-3.columns
|
||||
.small-12.medium-4.columns
|
||||
= render partial: "checkout/summary"
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
- if oc_select_options.count > 1
|
||||
%option{value: "", disabled: "", selected: ""}= t :shopping_oc_select
|
||||
|
||||
- content_for :ordercycle_sidebar do
|
||||
.show-for-large-up.large-4.columns
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
= render partial: "shopping_shared/header"
|
||||
= render partial: "shopping_shared/tabs"
|
||||
|
||||
|
||||
10
app/views/layouts/_bugsnag_js.html.haml
Normal file
10
app/views/layouts/_bugsnag_js.html.haml
Normal file
@@ -0,0 +1,10 @@
|
||||
- bugsnag_js_key = ENV['BUGSNAG_JS_KEY'] || ENV['BUGSNAG_API_KEY']
|
||||
- if bugsnag_js_key.present?
|
||||
%script{src: "//d2wy8f7a9ursnm.cloudfront.net/v6/bugsnag.min.js"}
|
||||
:javascript
|
||||
window.bugsnagClient = bugsnag({
|
||||
apiKey: "#{bugsnag_js_key}",
|
||||
beforeSend: function (report) {
|
||||
report.app.releaseStage = "#{Rails.env}"
|
||||
}
|
||||
});
|
||||
@@ -37,6 +37,7 @@
|
||||
#footer
|
||||
%loading
|
||||
|
||||
= render "layouts/bugsnag_js"
|
||||
%script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"}
|
||||
%script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "}
|
||||
= javascript_include_tag "darkswarm/all"
|
||||
|
||||
@@ -10,6 +10,4 @@
|
||||
= distributor.name
|
||||
%location= distributor.address.city
|
||||
|
||||
- unless defined? hide_oc_selector
|
||||
.show-for-large-up.large-4.columns
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
= yield :ordercycle_sidebar
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
$("#new_property").html('<%= escape_javascript(render :template => "spree/admin/properties/new", :formats => [:html], :handlers => [:erb]) %>');
|
||||
$("#new_property").html('<%= escape_javascript(render :template => "spree/admin/properties/new", :formats => [:html], :handlers => [:haml]) %>');
|
||||
$("#new_property_link").parent().hide();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
%link{:href => "//fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,600&subset=latin,cyrillic,greek,vietnamese", :rel => "stylesheet", :type => "text/css"}
|
||||
|
||||
= stylesheet_link_tag 'admin/all'
|
||||
= render "layouts/bugsnag_js"
|
||||
= javascript_include_tag 'admin/all'
|
||||
|
||||
= render "spree/admin/shared/translations"
|
||||
|
||||
@@ -16,8 +16,15 @@
|
||||
- else
|
||||
= @order.distributor.next_collection_at
|
||||
|
||||
- content_for :ordercycle_sidebar do
|
||||
.show-for-large-up.large-4.columns
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
= render partial: "shopping_shared/header"
|
||||
|
||||
.sub-header.show-for-medium-down
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
%fieldset.footer-pad
|
||||
- if @order.line_items.empty?
|
||||
%div.row{"data-hook" => "empty_cart"}
|
||||
|
||||
@@ -37,6 +37,9 @@ SMTP_PASSWORD: 'f00d'
|
||||
# MAILS_FROM: hello@example.com
|
||||
# MAIL_BCC: manager@example.com
|
||||
|
||||
# Javascript error reporting via Bugsnag.
|
||||
#BUGSNAG_JS_KEY: ""
|
||||
|
||||
# SingleSignOn login for Discourse
|
||||
#
|
||||
# DISCOURSE_SSO_SECRET should be a random string. It must be the same as provided to your Discourse instance.
|
||||
|
||||
@@ -246,6 +246,8 @@ ar:
|
||||
notes: ملاحظات
|
||||
error: خطأ
|
||||
processing_payment: "معالجة الدفع..."
|
||||
no_pending_payments: "لا توجد دفعات معلقة"
|
||||
invalid_payment_state: "حالة الدفع غير صالحة"
|
||||
filter_results: تصفية النتائج
|
||||
quantity: الكمية
|
||||
pick_up: النقل
|
||||
@@ -1483,6 +1485,7 @@ ar:
|
||||
shopping_oc_closed_description: "يرجى الانتظار حتى تفتح الدورة التالية (أو اتصل بنا مباشرة لمعرفة ما إذا كان يمكننا قبول أي طلبات متأخرة)"
|
||||
shopping_oc_last_closed: "آخر دورة تم إغلاق %{distance_of_time} منذ"
|
||||
shopping_oc_next_open: "تفتح الدورة التالية في %{distance_of_time}"
|
||||
shopping_oc_select: "اختيار..."
|
||||
shopping_tabs_home: "الصفحة الرئيسية"
|
||||
shopping_tabs_shop: "المتجر"
|
||||
shopping_tabs_about: "حول"
|
||||
@@ -1864,6 +1867,7 @@ ar:
|
||||
headline: "تم الانتهاء !"
|
||||
thanks: "شكرًا لملء تفاصيل %{enterprise}."
|
||||
login: "يمكنك تغيير أو تحديث شركتك في أي مرحلة من خلال تسجيل الدخول إلى شبكة الغذاء المفتوح والذهاب إلى المسؤول."
|
||||
action: "انتقل إلى واجهة الشركة"
|
||||
back: "عودة"
|
||||
continue: "استمر"
|
||||
action_or: "أو"
|
||||
@@ -2278,6 +2282,7 @@ ar:
|
||||
enterprise_register_success_notice: "تهانينا! اكتمل التسجيل لـ %{enterprise}!"
|
||||
enterprise_bulk_update_success_notice: "تم تحديث المؤسسات بنجاح"
|
||||
enterprise_bulk_update_error: 'فشل التحديث'
|
||||
enterprise_shop_show_error: "المتجر الذي تبحث عنه غير موجود أو غير نشط . يرجى التحقق من المحلات التجارية الأخرى."
|
||||
order_cycles_create_notice: 'تم إنشاء دورة الطلب الخاصة بك.'
|
||||
order_cycles_update_notice: 'تم تحديث دورة الطلب.'
|
||||
order_cycles_bulk_update_notice: 'تم تحديث دورات الطلب.'
|
||||
@@ -2603,6 +2608,34 @@ ar:
|
||||
few: "حزم"
|
||||
many: "حزم"
|
||||
other: "حزم"
|
||||
bottle:
|
||||
zero: "زجاجات"
|
||||
one: "زجاجة"
|
||||
two: "زجاجات"
|
||||
few: "زجاجات"
|
||||
many: "زجاجات"
|
||||
other: "زجاجات"
|
||||
item:
|
||||
zero: "العناصر"
|
||||
one: "بند"
|
||||
two: "العناصر"
|
||||
few: "العناصر"
|
||||
many: "العناصر"
|
||||
other: "المواد"
|
||||
dozen:
|
||||
zero: "العشرات"
|
||||
one: "دزينة"
|
||||
two: "العشرات"
|
||||
few: "العشرات"
|
||||
many: "العشرات"
|
||||
other: "العشرات"
|
||||
unit:
|
||||
zero: "الوحدات"
|
||||
one: "وحدة"
|
||||
two: "الوحدات"
|
||||
few: "الوحدات"
|
||||
many: "الوحدات"
|
||||
other: "الوحدات"
|
||||
producers:
|
||||
signup:
|
||||
start_free_profile: "ابدأ بملف تعريف مجاني ، وتوسع عندما تكون جاهزًا!"
|
||||
@@ -2956,7 +2989,8 @@ ar:
|
||||
tax_invoice: "فاتورة ضريبية"
|
||||
code: "الشفرة"
|
||||
from: "من "
|
||||
to: "إلى"
|
||||
to: "فاتورة الى"
|
||||
shipping: "الشحن"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "توزيع"
|
||||
|
||||
@@ -1425,7 +1425,7 @@ ca:
|
||||
email_confirm_customer_greeting: "Hola %{name},"
|
||||
email_confirm_customer_intro_html: "Gràcies per comprar a <strong> %{distributor}</strong>."
|
||||
email_confirm_customer_number_html: "Confirmació de la comanda <strong> # %{number} </strong>"
|
||||
email_confirm_customer_details_html: "Aquests són els detalls de la teva comanda de <strong> %{distributor} </ strong>:"
|
||||
email_confirm_customer_details_html: "Aquests són els detalls de la teva comanda de<strong>%{distributor}</strong>:"
|
||||
email_confirm_customer_signoff: "Salutacions cordials,"
|
||||
email_confirm_shop_greeting: "Hola %{name},"
|
||||
email_confirm_shop_order_html: "Que bé! Tens una nova comanda per <strong> %{distributor} </ strong>."
|
||||
@@ -3015,7 +3015,6 @@ ca:
|
||||
tax_invoice: "FACTURA D'IMPOSTOS"
|
||||
code: "Codi"
|
||||
from: "De"
|
||||
to: "Per a"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribució"
|
||||
|
||||
@@ -2927,7 +2927,6 @@ de_DE:
|
||||
tax_invoice: "Steuerrechnung"
|
||||
code: "Code"
|
||||
from: "Von"
|
||||
to: "Zu"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Verteilung"
|
||||
|
||||
@@ -2927,7 +2927,6 @@ en_AU:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -2856,7 +2856,6 @@ en_BE:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -3018,7 +3018,8 @@ en_CA:
|
||||
tax_invoice: "Order Number"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
to: "Bill to"
|
||||
shipping: "Shipping"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -2872,7 +2872,6 @@ en_DE:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -3019,7 +3019,6 @@ en_FR:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -3025,7 +3025,6 @@ en_GB:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -246,6 +246,8 @@ en_NZ:
|
||||
notes: Notes
|
||||
error: Error
|
||||
processing_payment: "Processing payment..."
|
||||
no_pending_payments: "No pending payments"
|
||||
invalid_payment_state: "Invalid payment state"
|
||||
filter_results: Filter Results
|
||||
quantity: Quantity
|
||||
pick_up: Pick up
|
||||
@@ -1484,6 +1486,7 @@ en_NZ:
|
||||
shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)"
|
||||
shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago"
|
||||
shopping_oc_next_open: "The next cycle opens in %{distance_of_time}"
|
||||
shopping_oc_select: "Select..."
|
||||
shopping_tabs_home: "Home"
|
||||
shopping_tabs_shop: "Shop"
|
||||
shopping_tabs_about: "About"
|
||||
@@ -1857,6 +1860,7 @@ en_NZ:
|
||||
headline: "Finished!"
|
||||
thanks: "Thanks for filling out the details for %{enterprise}."
|
||||
login: "You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin."
|
||||
action: "Go to Enterprise Dashboard"
|
||||
back: "Back"
|
||||
continue: "Continue"
|
||||
action_or: "OR"
|
||||
@@ -2273,6 +2277,7 @@ en_NZ:
|
||||
enterprise_register_success_notice: "Congratulations! Registration for %{enterprise} is complete!"
|
||||
enterprise_bulk_update_success_notice: "Enterprises updated successfully"
|
||||
enterprise_bulk_update_error: 'Update failed'
|
||||
enterprise_shop_show_error: "The shop you are looking for doesn't exist or is inactive on OFN. Please check other shops."
|
||||
order_cycles_create_notice: 'Your order cycle has been created.'
|
||||
order_cycles_update_notice: 'Your order cycle has been updated.'
|
||||
order_cycles_bulk_update_notice: 'Order cycles have been updated.'
|
||||
@@ -3014,7 +3019,8 @@ en_NZ:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
to: "Bill to"
|
||||
shipping: "Shipping"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -50,6 +50,8 @@ en_US:
|
||||
shipping_method_ids: "Shipping Methods"
|
||||
payment_method_ids: "Payment Methods"
|
||||
errors:
|
||||
messages:
|
||||
inclusion: "is not included in the list"
|
||||
models:
|
||||
subscription_validator:
|
||||
attributes:
|
||||
@@ -116,7 +118,9 @@ en_US:
|
||||
email_welcome: "Welcome"
|
||||
email_registered: "is now part of"
|
||||
email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}"
|
||||
userguide: "Open Food Network User Guide"
|
||||
email_admin_html: "You can manage your account by logging into the %{link} or by clicking on the cog in the top right hand side of the homepage, and selecting Administration."
|
||||
admin_panel: "Admin Panel"
|
||||
email_community_html: "We also have an online forum for community discussion related to OFN software and the unique challenges of running a food enterprise. You are encouraged to join in. We are constantly evolving and your input into this forum will shape what happens next. %{link}"
|
||||
join_community: "Join the community"
|
||||
invite_manager:
|
||||
@@ -242,6 +246,8 @@ en_US:
|
||||
notes: Notes
|
||||
error: Error
|
||||
processing_payment: "Processing payment..."
|
||||
no_pending_payments: "No pending payments"
|
||||
invalid_payment_state: "Invalid payment state"
|
||||
filter_results: Filter Results
|
||||
quantity: Quantity
|
||||
pick_up: Pick up
|
||||
@@ -434,9 +440,12 @@ en_US:
|
||||
infinity: "Infinity"
|
||||
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
|
||||
back_to_products_list: "Back to products list"
|
||||
editing_product: "Editing Product"
|
||||
tabs:
|
||||
product_details: "Product Details"
|
||||
group_buy_options: "Group Buy Options"
|
||||
images: "Images"
|
||||
variants: "Variants"
|
||||
product_properties: "Product Properties"
|
||||
product_import:
|
||||
title: Product Import
|
||||
@@ -539,6 +548,7 @@ en_US:
|
||||
title: Inventory
|
||||
description: Use this page to manage inventories for your enterprises. Any product details set here will override those set on the 'Products' page
|
||||
enable_reset?: Enable Stock Reset?
|
||||
default_stock: "Default stock"
|
||||
inherit?: Inherit?
|
||||
add: Add
|
||||
hide: Hide
|
||||
@@ -693,6 +703,10 @@ en_US:
|
||||
enable_subscriptions_false: "Disabled"
|
||||
enable_subscriptions_true: "Enabled"
|
||||
shopfront_message: "Shopfront Message"
|
||||
shopfront_message_placeholder: >
|
||||
An optional message to welcome customers and explain how to shop with
|
||||
you. If text is entered here it will be displayed in a home tab when
|
||||
customers first arrive at your shopfront.
|
||||
shopfront_message_link_tooltip: "Insert / edit link"
|
||||
shopfront_message_link_prompt: "Please enter a URL to insert"
|
||||
shopfront_closed_message: "Shopfront Closed Message"
|
||||
@@ -830,20 +844,32 @@ en_US:
|
||||
new:
|
||||
create: "Create"
|
||||
cancel: "Cancel"
|
||||
back_to_list: "Back To List"
|
||||
edit:
|
||||
advanced_settings: "Advanced Settings"
|
||||
save: "Save"
|
||||
save_and_next: "Save and Next"
|
||||
next: "Next"
|
||||
cancel: "Cancel"
|
||||
back_to_list: "Back To List"
|
||||
save_and_back_to_list: "Save and Back to List"
|
||||
choose_products_from: "Choose Products From:"
|
||||
incoming:
|
||||
save: "Save"
|
||||
save_and_next: "Save and Next"
|
||||
next: "Next"
|
||||
cancel: "Cancel"
|
||||
back_to_list: "Back To List"
|
||||
outgoing:
|
||||
previous: "Previous"
|
||||
save: "Save"
|
||||
save_and_back_to_list: "Save and Back to List"
|
||||
cancel: "Cancel"
|
||||
back_to_list: "Back To List"
|
||||
wizard_progress:
|
||||
edit: "1. General Settings"
|
||||
incoming: "2. Incoming Products"
|
||||
outgoing: "3. Outgoing Products"
|
||||
exchange_form:
|
||||
pickup_time_tip: When orders from this OC will be ready for the customer
|
||||
pickup_instructions_placeholder: "Pick-up instructions"
|
||||
@@ -1081,10 +1107,13 @@ en_US:
|
||||
destroy_attachment_does_not_exist: "Logo does not exist"
|
||||
enterprise_promo_image:
|
||||
destroy_attachment_does_not_exist: "Promo image does not exist"
|
||||
orders:
|
||||
failed_to_update: "Failed to update order"
|
||||
checkout:
|
||||
already_ordered:
|
||||
cart: "cart"
|
||||
message_html: "You have an order for this order cycle already. Check the %{cart} to see the items you ordered before. You can also cancel items as long as the order cycle is open."
|
||||
failed: "The checkout failed. Please let us know so that we can process your order."
|
||||
shops:
|
||||
hubs:
|
||||
show_closed_shops: "Show closed shops"
|
||||
@@ -1255,6 +1284,7 @@ en_US:
|
||||
saving_credit_card: Saving credit card...
|
||||
card_has_been_removed: "Your card has been removed (number: %{number})"
|
||||
card_could_not_be_removed: Sorry, the card could not be removed
|
||||
invalid_credit_card: "Invalid credit card"
|
||||
ie_warning_headline: "Your browser is out of date :-("
|
||||
ie_warning_text: "For the best Open Food Network experience, we strongly recommend upgrading your browser:"
|
||||
ie_warning_chrome: Download Chrome
|
||||
@@ -1456,6 +1486,7 @@ en_US:
|
||||
shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)"
|
||||
shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago"
|
||||
shopping_oc_next_open: "The next cycle opens in %{distance_of_time}"
|
||||
shopping_oc_select: "Select..."
|
||||
shopping_tabs_home: "Home"
|
||||
shopping_tabs_shop: "Shop"
|
||||
shopping_tabs_about: "About"
|
||||
@@ -1829,6 +1860,7 @@ en_US:
|
||||
headline: "Finished!"
|
||||
thanks: "Thanks for filling out the details for %{enterprise}."
|
||||
login: "You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin."
|
||||
action: "Go to Enterprise Dashboard"
|
||||
back: "Back"
|
||||
continue: "Continue"
|
||||
action_or: "OR"
|
||||
@@ -1914,6 +1946,7 @@ en_US:
|
||||
tax_category: "Tax Category"
|
||||
calculator: "Calculator"
|
||||
calculator_values: "Calculator values"
|
||||
calculator_settings_warning: "If you are changing the calculator type, you must save first before you can edit the calculator settings"
|
||||
flat_percent_per_item: "Flat Percent (per item)"
|
||||
flat_rate_per_item: "Flat Rate (per item)"
|
||||
flat_rate_per_order: "Flat Rate (per order)"
|
||||
@@ -2244,6 +2277,7 @@ en_US:
|
||||
enterprise_register_success_notice: "Congratulations! Registration for %{enterprise} is complete!"
|
||||
enterprise_bulk_update_success_notice: "Enterprises updated successfully"
|
||||
enterprise_bulk_update_error: 'Update failed'
|
||||
enterprise_shop_show_error: "The shop you are looking for doesn't exist or is inactive on OFN. Please check other shops."
|
||||
order_cycles_create_notice: 'Your order cycle has been created.'
|
||||
order_cycles_update_notice: 'Your order cycle has been updated.'
|
||||
order_cycles_bulk_update_notice: 'Order cycles have been updated.'
|
||||
@@ -2395,6 +2429,12 @@ en_US:
|
||||
severity: Severity
|
||||
description: Description
|
||||
resolve: Resolve
|
||||
exchange_products:
|
||||
load_more_variants: "Load More Variants"
|
||||
load_all_variants: "Load All Variants"
|
||||
select_all_variants: "Select All %{total_number_of_variants} Variants"
|
||||
variants_loaded: "%{num_of_variants_loaded} of %{total_number_of_variants} Variants Loaded"
|
||||
loading_variants: "Loading Variants"
|
||||
tag_rules:
|
||||
shipping_method_tagged_top: "Shipping methods tagged"
|
||||
shipping_method_tagged_bottom: "are:"
|
||||
@@ -2477,6 +2517,7 @@ en_US:
|
||||
customer_placeholder: "customer@example.org"
|
||||
valid_email_error: "Please enter a valid email address"
|
||||
subscriptions:
|
||||
error_saving: "Error saving subscription"
|
||||
new:
|
||||
please_select_a_shop: "Please select a shop"
|
||||
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"
|
||||
@@ -2552,6 +2593,76 @@ en_US:
|
||||
signup_or_login: "Start By signing up (or logging in)"
|
||||
have_an_account: "Already have an account?"
|
||||
action_login: "Log in now."
|
||||
inflections:
|
||||
each:
|
||||
one: "each"
|
||||
other: "each"
|
||||
bunch:
|
||||
one: "bunch"
|
||||
other: "bunches"
|
||||
pack:
|
||||
one: "pack"
|
||||
other: "packs"
|
||||
box:
|
||||
one: "box"
|
||||
other: "boxes"
|
||||
bottle:
|
||||
one: "bottle"
|
||||
other: "bottles"
|
||||
jar:
|
||||
one: "jar"
|
||||
other: "jars"
|
||||
head:
|
||||
one: "head"
|
||||
other: "heads"
|
||||
bag:
|
||||
one: "bag"
|
||||
other: "bags"
|
||||
loaf:
|
||||
one: "loaf"
|
||||
other: "loaves"
|
||||
single:
|
||||
one: "single"
|
||||
other: "singles"
|
||||
tub:
|
||||
one: "tub"
|
||||
other: "tubs"
|
||||
packet:
|
||||
one: "packet"
|
||||
other: "packets"
|
||||
item:
|
||||
one: "item"
|
||||
other: "items"
|
||||
dozen:
|
||||
one: "dozen"
|
||||
other: "dozens"
|
||||
unit:
|
||||
one: "unit"
|
||||
other: "units"
|
||||
serve:
|
||||
one: "serve"
|
||||
other: "serves"
|
||||
tray:
|
||||
one: "tray"
|
||||
other: "trays"
|
||||
piece:
|
||||
one: "piece"
|
||||
other: "pieces"
|
||||
pot:
|
||||
one: "pot"
|
||||
other: "pots"
|
||||
bundle:
|
||||
one: "bundle"
|
||||
other: "bundles"
|
||||
flask:
|
||||
one: "flask"
|
||||
other: "flasks"
|
||||
basket:
|
||||
one: "basket"
|
||||
other: "baskets"
|
||||
sack:
|
||||
one: "sack"
|
||||
other: "sacks"
|
||||
producers:
|
||||
signup:
|
||||
start_free_profile: "Start with a free profile, and expand when you're ready!"
|
||||
@@ -2869,7 +2980,6 @@ en_US:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -2870,7 +2870,6 @@ en_ZA:
|
||||
tax_invoice: "TAX INVOICE"
|
||||
code: "Code"
|
||||
from: "From"
|
||||
to: "To"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -2877,7 +2877,6 @@ es:
|
||||
tax_invoice: "FACTURA DE IMPUESTOS"
|
||||
code: "Código"
|
||||
from: "De"
|
||||
to: "A"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribución"
|
||||
|
||||
@@ -3049,7 +3049,6 @@ fr:
|
||||
tax_invoice: "FACTURE"
|
||||
code: "Code"
|
||||
from: "De"
|
||||
to: "A"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -2949,7 +2949,6 @@ fr_BE:
|
||||
tax_invoice: "FACTURE"
|
||||
code: "Code"
|
||||
from: "De"
|
||||
to: "A"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -3029,7 +3029,6 @@ fr_CA:
|
||||
tax_invoice: "FACTURE"
|
||||
code: "Code"
|
||||
from: "De"
|
||||
to: "A"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -1394,7 +1394,7 @@ it:
|
||||
order_delivery_address: Indirizzo di consegna
|
||||
order_delivery_time: Tempo di consegna
|
||||
order_special_instructions: "Tue note:"
|
||||
order_pickup_time: Pronto per la raccolta
|
||||
order_pickup_time: Pronto per il ritiro
|
||||
order_pickup_instructions: Istruzioni per la raccolta
|
||||
order_produce: Produrre
|
||||
order_total_price: Totale
|
||||
@@ -1463,7 +1463,7 @@ it:
|
||||
email_shipping_delivery_time: "Consegna il"
|
||||
email_shipping_delivery_address: "Indirizzo di consegna"
|
||||
email_shipping_collection_details: Dettagli della raccolta
|
||||
email_shipping_collection_time: "Pronto per la raccolta:"
|
||||
email_shipping_collection_time: "Pronto per il ritiro:"
|
||||
email_shipping_collection_instructions: "Istruzioni per la raccolta:"
|
||||
email_special_instructions: "Tue note:"
|
||||
email_signup_greeting: Ciao!
|
||||
@@ -3023,7 +3023,6 @@ it:
|
||||
tax_invoice: "FATTURA DELLE TASSE"
|
||||
code: "Codice"
|
||||
from: "Da"
|
||||
to: "A"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribuzione"
|
||||
|
||||
@@ -3018,7 +3018,6 @@ nb:
|
||||
tax_invoice: "AVGIFTSFAKTURA"
|
||||
code: "Kode"
|
||||
from: "Fra"
|
||||
to: "Til"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribusjon"
|
||||
|
||||
@@ -2865,7 +2865,6 @@ nl_BE:
|
||||
tax_invoice: "FACTUUR"
|
||||
code: "Code"
|
||||
from: "Van"
|
||||
to: "tot"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distributie"
|
||||
|
||||
@@ -2811,7 +2811,6 @@ pt:
|
||||
tax_invoice: "FACTURA FISCAL"
|
||||
code: "Código"
|
||||
from: "De"
|
||||
to: "Para"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribuição"
|
||||
|
||||
@@ -175,7 +175,7 @@ pt_BR:
|
||||
home: "OFB"
|
||||
title: Open Food Brasil
|
||||
welcome_to: 'Bem-vindo a'
|
||||
site_meta_description: "A gente começa pela base. Com agricultores e produtores preparados para contar suas histórias com orgulho e verdade. Com distribuidores prontos para conectar pessoas com produtos de forma justa e honesta. Com os compradores que acreditam que melhores decisões de compras semanais podem..."
|
||||
site_meta_description: "A nossa proposta é conectar agricultoras/es, produtoras/es e consumidoras/es que estão próximos entre si. Buscamos, assim, potencializar a circulação e a comercialização de produtos agroecológicos, orgânicos e artesanais em circuitos curtos, bem como criar novas formas de relação, orientadas pela troca, diálogo e confiança."
|
||||
search_by_name: Procurar por nome ou localidade
|
||||
producers_join: Produtores nacionais estão convidados a se unirem à Open Food Brasil.
|
||||
charges_sales_tax: Cobra imposto sobre bens e serviços?
|
||||
@@ -583,7 +583,7 @@ pt_BR:
|
||||
actions_delete: "Deletar selecionado"
|
||||
loading: "Carregando pedidos"
|
||||
no_results: "Nenhum pedido encontrado. "
|
||||
group_buy_unit_size: "Tamanho de unidade para compras de Grupo"
|
||||
group_buy_unit_size: "Tamanho da Unidade para Grupo de Compras"
|
||||
total_qtt_ordered: "Quantidade total do pedido"
|
||||
max_qtt_ordered: "Quantidade máxima do pedido"
|
||||
current_fulfilled_units: "Unidades completadas no momento"
|
||||
@@ -598,7 +598,7 @@ pt_BR:
|
||||
title: Iniciativas
|
||||
new_enterprise: Nova iniciativa
|
||||
producer?: "Produtor?"
|
||||
package: Embalagem
|
||||
package: Tipo de Perfil
|
||||
status: Status
|
||||
manage: Administrar
|
||||
form:
|
||||
@@ -806,7 +806,7 @@ pt_BR:
|
||||
manage: Administrar
|
||||
manage_link: Configurações
|
||||
producer?: "Produtor?"
|
||||
package: "Embalagem"
|
||||
package: "Tipo de Perfil"
|
||||
status: "Status"
|
||||
new_form:
|
||||
owner: Proprietário
|
||||
@@ -1333,28 +1333,28 @@ pt_BR:
|
||||
cookies_policy_link: "política de cookies"
|
||||
cookies_accept_button: "Aceitar Cookies"
|
||||
home_shop: Compre Agora
|
||||
brandstory_headline: "Alimentos, com liberdade"
|
||||
brandstory_intro: "Às vezes, a melhor maneira de consertar o sistema é construir um novo..."
|
||||
brandstory_part1: "Começamos do início. Com agricultores e produtores preparados para contar com orgulho suas verdadeiras histórias. Com distribuidores prontos para conectar pessoas com produtos de forma justa e honesta. Com consumidores que acreditam que melhores decisões de compras podem mudar seriamente o mundo."
|
||||
brandstory_part2: "Então precisamos de uma forma para tornar isto real. Uma maneira para empoderar todos os que produzem, vendem e compram alimentos. Uma maneira de contar história e lidar com a logística. Uma maneira de transformar suas compras em mudanças positivas para a sociedade."
|
||||
brandstory_part3: "Assim construímos um mercado de alimentos mais justo e transparente, por isso criamos relacionamentos reais. Nosso código é aberto, por isso é de todos. Nos multiplicamos por diversas regiões e países, com pessoas criando seus próprios mercados pelo mundo."
|
||||
brandstory_part4: "É acessível a todos, em qualquer lugar do mundo."
|
||||
brandstory_part5_strong: "Somos a Open Food Brasil."
|
||||
brandstory_part6: "Todos amamos comida. Agora a gente também pode amar nosso maneira de consumir. "
|
||||
brandstory_headline: "Comida de verdade, com autonomia "
|
||||
brandstory_intro: "Comer é um ato político! Por trás de todo alimento há pessoas, processos e histórias. "
|
||||
brandstory_part1: "A nossa proposta é conectar agricultoras/es, produtoras/es e consumidoras/es que estão próximos entre si. Buscamos, assim, potencializar a circulação e a comercialização de produtos agroecológicos, orgânicos e artesanais em circuitos curtos, bem como criar novas formas de relação, orientadas pela troca, diálogo e confiança."
|
||||
brandstory_part2: "Para tornar essa ideia real, trouxemos a plataforma Open Food Network para o Brasil. Nosso código (a receita do site) é aberto e seu desenvolvimento é orientado globalmente pelas/os interessadas/os e baseado em uma cultura de autonomia e transparência."
|
||||
brandstory_part3: "Uma maneira de incentivar a colaboração entre quem produz, vende e compra. Uma maneira de contar histórias e lidar com a logística. Uma maneira de transformar seu consumo de alimentos em mudanças positivas para a sociedade."
|
||||
brandstory_part4: "Colabore com essa (des)construção!"
|
||||
brandstory_part5_strong: "Open Food Brasil"
|
||||
brandstory_part6: "–"
|
||||
learn_body: "Explore modelos, histórias e recursos para te dar suporte para desenvolver seu próprio negócio ou organização justa de alimentos. Encontre treinamento, eventos e outras oportunidades para aprender com quem faz parte do seu setor. "
|
||||
learn_cta: "Inspire-se"
|
||||
connect_body: "Procure em nossa lista de produtores, distribuidores e cooperativas para encontrar um comércio justo perto de você. Registre seu negócio ou organização na Open Food Brasil para que os consumidores possam te encontrar. Junte-se à comunidade para trocar experiências e resolver problemas."
|
||||
connect_cta: "Explore"
|
||||
system_headline: "Compras - é assim que funciona:"
|
||||
system_headline: "Como comprar:"
|
||||
system_step1: "1. Busca"
|
||||
system_step1_text: "Dentre os diversos mercados independentes, escolha o de sua preferência. Procure por região, tipo de alimentos, alimentos locais e sazonais e escolha o método de recebimento que pode ser receber em casa ou retirar no local. "
|
||||
system_step2: "2. Compra"
|
||||
system_step2_text: "Conheça as histórias por trás da sua comida e as pessoas que as produzem! Transforme suas compras com alimentos locais acessíveis."
|
||||
system_step2_text: "Conheça as pessoas e as histórias por trás da sua comida. Transforme sua relação com o alimento!"
|
||||
system_step3: "3. Retirada / Entrega"
|
||||
system_step3_text: "Você escolhe a melhor forma de receber o seu alimentar, aguarde pela sua entrega, ou visite seus produtores ou centrais para uma conexão mais pessoal com seus alimentos."
|
||||
system_step3_text: "Escolha a forma de recebimento do seu pedido: você pode receber em casa ou retirar no local, assim pode encontrar e conhecer as pessoas envolvidas e estreitar sua relação com as/os agricultoras/es ou as/os mediadoras/es da circulação de produtos. "
|
||||
cta_headline: "Compras que fazem do mundo um lugar melhor."
|
||||
cta_label: "Estou pronto"
|
||||
stats_headline: "Estamos criando um novo sistema alimentar"
|
||||
stats_headline: "Estamos trabalhando para relocalizar os sistemas agroalimentares"
|
||||
stats_producers: "produtores de alimentos"
|
||||
stats_shops: "lojas de alimentos"
|
||||
stats_shoppers: "consumidores de alimentos"
|
||||
@@ -1901,7 +1901,7 @@ pt_BR:
|
||||
successfully_updated: '%{resource} foi atualizado com sucesso!'
|
||||
running_balance: "Balanço corrente"
|
||||
outstanding_balance: "Saldo devedor"
|
||||
admin_enterprise_relationships: "Permissões corporativas"
|
||||
admin_enterprise_relationships: "Permissões da Iniciativa"
|
||||
admin_enterprise_relationships_everything: "Tudo"
|
||||
admin_enterprise_relationships_permits: "permite"
|
||||
admin_enterprise_relationships_seach_placeholder: "Buscar"
|
||||
@@ -2133,7 +2133,7 @@ pt_BR:
|
||||
report_header_producer: Produtor
|
||||
report_header_producer_suburb: Subúrbio do produtor
|
||||
report_header_unit: Unidade
|
||||
report_header_group_buy_unit_quantity: Quantidade de unidade de compra em grupo
|
||||
report_header_group_buy_unit_quantity: Quantidade da Unidade para Grupo de Compras
|
||||
report_header_cost: Custo
|
||||
report_header_shipping_cost: ' Custo de envio'
|
||||
report_header_curr_cost_per_unit: Custo unitário atual
|
||||
@@ -2229,7 +2229,7 @@ pt_BR:
|
||||
adrdress: "Endereço"
|
||||
contact: "Contato"
|
||||
social: "Social"
|
||||
business_details: "Detalhes do negócio"
|
||||
business_details: "Detalhes da iniciativa"
|
||||
properties: "Propriedades"
|
||||
shipping: "Envio"
|
||||
shipping_methods: "Métodos de envio"
|
||||
@@ -2271,7 +2271,7 @@ pt_BR:
|
||||
mas não possuem métodos de envio e pagamento válidos. Até que você configure
|
||||
eles, os consumidores não poderão fazer compras nessas centrais.
|
||||
enterprise_fees_update_notice: As tarifas da sua iniciativa foram atualizadas.
|
||||
enterprise_register_package_error: "Por favor selecione um pacote"
|
||||
enterprise_register_package_error: "Por favor selecione um tipo de perfil"
|
||||
enterprise_register_error: "Não foi possível completar o registro para %{enterprise}"
|
||||
enterprise_register_success_notice: "Parabéns! O registro para %{enterprise} está completo!"
|
||||
enterprise_bulk_update_success_notice: "Iniciativas atualizadas com sucesso"
|
||||
@@ -2360,7 +2360,7 @@ pt_BR:
|
||||
hub_shop_text3: >
|
||||
Se você também quer vender seus próprios produtos, você precisará mudar
|
||||
essa iniciativa para ser um produtor.
|
||||
choose_package: Por favor escolha um pacote
|
||||
choose_package: Por favor escolha um tipo de perfil
|
||||
choose_package_text1: >
|
||||
Sua iniciativa não será totalmente ativada até que um tipo de perfil
|
||||
seja selecionado a partir das opções à esquerda.
|
||||
@@ -3023,7 +3023,8 @@ pt_BR:
|
||||
tax_invoice: "NOTA FISCAL"
|
||||
code: "Código"
|
||||
from: "De"
|
||||
to: "Para"
|
||||
to: "Informações de cobrança"
|
||||
shipping: "Entrega"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribuição"
|
||||
@@ -3140,7 +3141,7 @@ pt_BR:
|
||||
primary_taxon_form:
|
||||
product_category: Categoria de Produto
|
||||
group_buy_form:
|
||||
group_buy: "Compra de grupo?"
|
||||
group_buy: "Grupo de Compras?"
|
||||
bulk_unit_size: Tamanho da unidade em massa
|
||||
display_as:
|
||||
display_as: Mostrar como
|
||||
|
||||
@@ -1972,7 +1972,6 @@ sv:
|
||||
tax_invoice: "FAKTURA"
|
||||
code: "Kod"
|
||||
from: "Från"
|
||||
to: "Till"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Distribution"
|
||||
|
||||
@@ -3010,7 +3010,6 @@ tr:
|
||||
tax_invoice: "VERGİ FATURASI"
|
||||
code: "Kod"
|
||||
from: "İtibaren"
|
||||
to: "Şu vakte kadar"
|
||||
form:
|
||||
distribution_fields:
|
||||
title: "Dağıtım"
|
||||
|
||||
@@ -33,6 +33,14 @@ module Web
|
||||
end
|
||||
|
||||
describe "language from locale" do
|
||||
# keeps global state unchanged
|
||||
around do |example|
|
||||
original_available_locales = I18n.available_locales
|
||||
I18n.available_locales = ['en', 'en_GB', '']
|
||||
example.run
|
||||
I18n.available_locales = original_available_locales
|
||||
end
|
||||
|
||||
scenario "when locale is the language" do
|
||||
I18n.locale = "en"
|
||||
expect(helper.locale_language).to eq "en"
|
||||
|
||||
@@ -128,7 +128,7 @@ module OpenFoodNetwork
|
||||
|
||||
def order_permissions
|
||||
return @order_permissions unless @order_permissions.nil?
|
||||
@order_permissions = ::Permissions::Order.new(@user)
|
||||
@order_permissions = ::Permissions::Order.new(@user, @params[:q])
|
||||
end
|
||||
|
||||
def report_line_items
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
module OpenFoodNetwork
|
||||
class EnterpriseInjectionData
|
||||
def active_distributors
|
||||
@active_distributors ||= Enterprise.distributors_with_active_order_cycles.ready_for_checkout
|
||||
def active_distributor_ids
|
||||
@active_distributor_ids ||=
|
||||
Enterprise.distributors_with_active_order_cycles.ready_for_checkout.pluck(:id)
|
||||
end
|
||||
|
||||
def earliest_closing_times
|
||||
|
||||
@@ -5,7 +5,7 @@ module OpenFoodNetwork
|
||||
@user = user
|
||||
@render_table = render_table
|
||||
|
||||
@permissions = ::Permissions::Order.new(user)
|
||||
@permissions = ::Permissions::Order.new(user, @params[:q])
|
||||
end
|
||||
|
||||
def header
|
||||
|
||||
@@ -83,7 +83,7 @@ module OpenFoodNetwork
|
||||
|
||||
def order_permissions
|
||||
return @order_permissions unless @order_permissions.nil?
|
||||
@order_permissions = ::Permissions::Order.new(@user)
|
||||
@order_permissions = ::Permissions::Order.new(@user, options[:q])
|
||||
end
|
||||
|
||||
def report_line_items
|
||||
|
||||
@@ -128,7 +128,7 @@ module OpenFoodNetwork
|
||||
|
||||
def order_permissions
|
||||
return @order_permissions unless @order_permissions.nil?
|
||||
@order_permissions = ::Permissions::Order.new(@user)
|
||||
@order_permissions = ::Permissions::Order.new(@user, @params[:q])
|
||||
end
|
||||
|
||||
def is_temperature_controlled?(line_item)
|
||||
|
||||
@@ -12,9 +12,7 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def list(line_item_includes = nil)
|
||||
line_items = @order_permissions.
|
||||
visible_line_items.
|
||||
merge(Spree::LineItem.where(order_id: orders.result))
|
||||
line_items = @order_permissions.visible_line_items.in_orders(orders.result)
|
||||
|
||||
if @params[:supplier_id_in].present?
|
||||
line_items = line_items.supplied_by_any(@params[:supplier_id_in])
|
||||
|
||||
@@ -7,7 +7,7 @@ describe ShopsController, type: :controller do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
before do
|
||||
allow(Enterprise).to receive_message_chain(:distributors_with_active_order_cycles, :ready_for_checkout) { [distributor] }
|
||||
allow(OpenFoodNetwork::EnterpriseInjectionData).to receive(:active_distributor_ids) { [distributor.id] }
|
||||
end
|
||||
|
||||
it 'renders distributed product properties' do
|
||||
|
||||
27
spec/features/admin/properties_spec.rb
Normal file
27
spec/features/admin/properties_spec.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
feature '
|
||||
As an admin
|
||||
I want to manage product properties
|
||||
' do
|
||||
include AuthenticationWorkflow
|
||||
|
||||
scenario "creating and editing a property" do
|
||||
login_to_admin_section
|
||||
visit spree.admin_properties_path
|
||||
|
||||
click_link 'New Property'
|
||||
fill_in 'property_name', with: 'New property!'
|
||||
fill_in 'property_presentation', with: 'New property presentation!'
|
||||
click_button 'Create'
|
||||
expect(page).to have_content 'New property!'
|
||||
|
||||
page.find('td.actions a.icon-edit').click
|
||||
expect(page).to have_field 'property_name', with: 'New property!'
|
||||
fill_in 'property_name', with: 'New changed property!'
|
||||
click_button 'Update'
|
||||
expect(page).to have_content 'New changed property!'
|
||||
end
|
||||
end
|
||||
@@ -19,8 +19,8 @@ describe Calculator::Weight do
|
||||
end
|
||||
|
||||
describe "line item with variant_unit weight and variant unit_value" do
|
||||
let(:variant) { build(:variant, unit_value: 10_000) }
|
||||
let(:line_item) { build(:line_item, variant: variant, quantity: 2) }
|
||||
let(:variant) { create(:variant, unit_value: 10_000) }
|
||||
let(:line_item) { create(:line_item, variant: variant, quantity: 2) }
|
||||
|
||||
before { subject.set_preference(:per_kg, 5) }
|
||||
|
||||
@@ -46,11 +46,11 @@ describe Calculator::Weight do
|
||||
end
|
||||
|
||||
it "computes shipping cost for an object with an order" do
|
||||
variant1 = build(:variant, unit_value: 10_000)
|
||||
variant2 = build(:variant, unit_value: 20_000)
|
||||
variant1 = create(:variant, unit_value: 10_000)
|
||||
variant2 = create(:variant, unit_value: 20_000)
|
||||
|
||||
line_item1 = build(:line_item, variant: variant1, quantity: 1)
|
||||
line_item2 = build(:line_item, variant: variant2, quantity: 2)
|
||||
line_item1 = create(:line_item, variant: variant1, quantity: 1)
|
||||
line_item2 = create(:line_item, variant: variant2, quantity: 2)
|
||||
|
||||
order = double(:order, line_items: [line_item1, line_item2])
|
||||
object_with_order = double(:object_with_order, order: order)
|
||||
@@ -65,7 +65,7 @@ describe Calculator::Weight do
|
||||
|
||||
let(:calculator) { described_class.new(preferred_per_kg: 6) }
|
||||
let(:line_item) do
|
||||
build(:line_item, variant: variant, quantity: 2).tap do |object|
|
||||
create(:line_item, variant: variant, quantity: 2).tap do |object|
|
||||
object.send(:calculate_final_weight_volume)
|
||||
end
|
||||
end
|
||||
@@ -141,7 +141,7 @@ describe Calculator::Weight do
|
||||
end
|
||||
|
||||
context "when the product uses item unit" do
|
||||
let!(:product_attributes) { { variant_unit: "items", variant_unit_scale: nil, variant_unit: "pc", display_as: "pc" } }
|
||||
let!(:product_attributes) { { variant_unit: "items", variant_unit_scale: nil, variant_unit_name: "pc", display_as: "pc" } }
|
||||
let!(:variant_attributes) { { unit_value: 3.0, weight: 2.5, display_as: "pc" } }
|
||||
|
||||
it "is correct" do
|
||||
@@ -151,4 +151,53 @@ describe Calculator::Weight do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when variant_unit is 'items'" do
|
||||
let(:product) {
|
||||
create(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: "bunch")
|
||||
}
|
||||
let(:line_item) { create(:line_item, variant: variant, quantity: 1) }
|
||||
|
||||
before { subject.set_preference(:per_kg, 5) }
|
||||
|
||||
context "when unit_value is zero variant.weight is present" do
|
||||
let(:variant) { create(:variant, product: product, unit_value: 0, weight: 10.0) }
|
||||
|
||||
it "uses the variant weight" do
|
||||
expect(subject.compute(line_item)).to eq 50.0
|
||||
end
|
||||
end
|
||||
|
||||
context "when unit_value is zero variant.weight is nil" do
|
||||
let(:variant) { create(:variant, product: product, unit_value: 0, weight: nil) }
|
||||
|
||||
it "uses zero weight" do
|
||||
expect(subject.compute(line_item)).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
context "when unit_value is nil and variant.weight is present" do
|
||||
let(:variant) {
|
||||
create(:variant, product: product, unit_description: "bunches", unit_value: nil, weight: 10.0)
|
||||
}
|
||||
|
||||
it "uses the variant weight" do
|
||||
line_item.final_weight_volume = 1
|
||||
|
||||
expect(subject.compute(line_item)).to eq 50.0
|
||||
end
|
||||
end
|
||||
|
||||
context "when unit_value is nil and variant.weight is nil" do
|
||||
let(:variant) {
|
||||
create(:variant, product: product, unit_description: "bunches", unit_value: nil, weight: nil)
|
||||
}
|
||||
|
||||
it "uses zero weight" do
|
||||
line_item.final_weight_volume = 1
|
||||
|
||||
expect(subject.compute(line_item)).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,10 +40,13 @@ module Spree
|
||||
|
||||
describe "finding line items with and without tax" do
|
||||
let(:tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new) }
|
||||
let!(:adjustment1) { create(:adjustment, adjustable: li1, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) }
|
||||
let!(:adjustment2) { create(:adjustment, adjustable: li1, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) }
|
||||
let!(:adjustment1) { create(:adjustment, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) }
|
||||
|
||||
before { li1; li2 }
|
||||
before do
|
||||
li1
|
||||
li2
|
||||
li1.adjustments << adjustment1
|
||||
end
|
||||
|
||||
it "finds line items with tax" do
|
||||
expect(LineItem.with_tax).to eq([li1])
|
||||
|
||||
@@ -76,9 +76,11 @@ describe Spree.user_class do
|
||||
it "should send a confirmation email" do
|
||||
setup_email
|
||||
|
||||
expect do
|
||||
create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil)
|
||||
end.to send_confirmation_instructions
|
||||
performing_deliveries do
|
||||
expect do
|
||||
create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil)
|
||||
end.to send_confirmation_instructions
|
||||
end
|
||||
|
||||
sent_mail = ActionMailer::Base.deliveries.last
|
||||
expect(sent_mail.to).to eq ['new_user@example.com']
|
||||
|
||||
@@ -50,7 +50,7 @@ describe Api::CachedEnterpriseSerializer do
|
||||
|
||||
context 'when the enterprise is not an active distributor' do
|
||||
let(:enterprise_injection_data) do
|
||||
instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributors: [])
|
||||
instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributor_ids: [])
|
||||
end
|
||||
|
||||
it 'does not duplicate properties' do
|
||||
@@ -69,7 +69,7 @@ describe Api::CachedEnterpriseSerializer do
|
||||
|
||||
context 'when the enterprise is an active distributor' do
|
||||
let(:enterprise_injection_data) do
|
||||
instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributors: [shop])
|
||||
instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributor_ids: [shop.id])
|
||||
end
|
||||
|
||||
it 'does not duplicate properties' do
|
||||
|
||||
@@ -5,14 +5,21 @@ module Permissions
|
||||
let(:user) { double(:user) }
|
||||
let(:permissions) { Permissions::Order.new(user) }
|
||||
let!(:basic_permissions) { OpenFoodNetwork::Permissions.new(user) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise) }
|
||||
let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) }
|
||||
let(:order_completed) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor ) }
|
||||
let(:order_cancelled) { create(:order, order_cycle: order_cycle, distributor: distributor, state: 'canceled' ) }
|
||||
let(:order_cart) { create(:order, order_cycle: order_cycle, distributor: distributor, state: 'cart' ) }
|
||||
let(:order_from_last_year) {
|
||||
create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor,
|
||||
completed_at: Time.zone.now - 1.year)
|
||||
}
|
||||
|
||||
before { allow(OpenFoodNetwork::Permissions).to receive(:new) { basic_permissions } }
|
||||
|
||||
describe "finding orders that are visible in reports" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise) }
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) }
|
||||
let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) }
|
||||
let!(:line_item) { create(:line_item, order: order) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
@@ -64,6 +71,18 @@ module Permissions
|
||||
expect(permissions.visible_orders).to_not include order
|
||||
end
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
it "only returns completed, non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_orders).to include order_completed
|
||||
expect(permissions.visible_orders).to_not include order_cancelled
|
||||
expect(permissions.visible_orders).to_not include order_cart
|
||||
expect(permissions.visible_orders).to_not include order_from_last_year
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "as an enterprise that is a distributor in the order cycle, but not the distributor of the order" do
|
||||
@@ -78,10 +97,7 @@ module Permissions
|
||||
end
|
||||
|
||||
describe "finding line items that are visible in reports" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise) }
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) }
|
||||
let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) }
|
||||
let!(:line_item1) { create(:line_item, order: order) }
|
||||
let!(:line_item2) { create(:line_item, order: order) }
|
||||
@@ -137,6 +153,27 @@ module Permissions
|
||||
expect(permissions.visible_line_items).to_not include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let!(:line_item3) { create(:line_item, order: order_completed) }
|
||||
let!(:line_item4) { create(:line_item, order: order_cancelled) }
|
||||
let!(:line_item5) { create(:line_item, order: order_cart) }
|
||||
let!(:line_item6) { create(:line_item, order: order_from_last_year) }
|
||||
|
||||
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
before do
|
||||
allow(user).to receive(:has_spree_role?) { "admin" }
|
||||
end
|
||||
|
||||
it "only returns line items from completed, non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_line_items).to include order_completed.line_items.first
|
||||
expect(permissions.visible_line_items).to_not include order_cancelled.line_items.first
|
||||
expect(permissions.visible_line_items).to_not include order_cart.line_items.first
|
||||
expect(permissions.visible_line_items).to_not include order_from_last_year.line_items.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user