Compare commits

..

1 Commits

Author SHA1 Message Date
Jean-Baptiste Bellet
a8f88ba687 Workaround: bad interaction btw Turbo and stripe iframe
Found this workaround here: https://github.com/hotwired/turbo/issues/270#issuecomment-1068130327

This js hack persists the original iframe object downloaded from stripe in the new body sent by Turbo (instead of using the new one, in the new body)
2023-01-09 10:35:52 +01:00
181 changed files with 1580 additions and 2620 deletions

View File

@@ -23,7 +23,8 @@ assignees: ''
## Finish on Tuesday
- [ ] Publish and notify [#global-community] (this is automatically posted with a plugin)
- [ ] Publish and notify [#global-community]:
> The next release is ready: https://github.com/openfoodfoundation/openfoodnetwork/releases/latest
- [ ] Deploy the new release to all managed instances.
<details><summary>Command line instructions</summary>
<pre>

View File

@@ -33,7 +33,7 @@ jobs:
- name: Setup Brakeman
env:
BRAKEMAN_VERSION: '5.4.0'
BRAKEMAN_VERSION: '4.10' # SARIF support is provided in Brakeman version 4.10+
run: |
gem install brakeman --version $BRAKEMAN_VERSION

View File

@@ -684,6 +684,17 @@ Rails/ApplicationController:
Exclude:
- 'engines/dfc_provider/app/controllers/dfc_provider/base_controller.rb'
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationJob:
Exclude:
- 'app/jobs/bulk_invoice_job.rb'
- 'app/jobs/heartbeat_job.rb'
- 'app/jobs/order_cycle_closing_job.rb'
- 'app/jobs/order_cycle_notification_job.rb'
- 'app/jobs/subscription_confirm_job.rb'
- 'app/jobs/subscription_placement_job.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationMailer:

View File

@@ -28,7 +28,7 @@ For those new to Rails, the following tutorial will help get you up to speed wit
So you have set up your local environment according to the requirements listed above. If you're planning on contributing code to the project (which we [LOVE](CONTRIBUTING.md)), it is a good idea to begin by forking this repo using the `Fork` button in the top-right corner of this screen. You should then be able to use `git clone` to copy your fork onto your local machine:
git clone git@github.com:YOUR_GITHUB_USERNAME_HERE/openfoodnetwork.git
git clone https://github.com/YOUR_GITHUB_USERNAME_HERE/openfoodnetwork
Jump into your new local copy of the Open Food Network:
@@ -36,7 +36,7 @@ Jump into your new local copy of the Open Food Network:
And then add an `upstream` remote that points to the main repo:
git remote add upstream git@github.com:openfoodfoundation/openfoodnetwork.git
git remote add upstream https://github.com/openfoodfoundation/openfoodnetwork
Fetch the latest version of `master` from `upstream` (ie. the main repo):

View File

@@ -118,7 +118,7 @@ gem 'test-unit', '~> 3.5'
gem 'coffee-rails', '~> 5.0.0'
gem 'mini_racer'
gem 'mini_racer', '0.4.0'
gem 'angular_rails_csrf'

View File

@@ -158,16 +158,16 @@ GEM
awesome_nested_set (3.5.0)
activerecord (>= 4.0.0, < 7.1)
aws-eventstream (1.2.0)
aws-partitions (1.695.0)
aws-sdk-core (3.169.0)
aws-partitions (1.669.0)
aws-sdk-core (3.168.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.62.0)
aws-sdk-kms (1.60.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.118.0)
aws-sdk-s3 (1.117.2)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -177,9 +177,9 @@ GEM
bigdecimal (3.0.2)
bindata (2.4.12)
bindex (0.8.1)
bootsnap (1.16.0)
bootsnap (1.15.0)
msgpack (~> 1.2)
bugsnag (6.25.1)
bugsnag (6.25.0)
concurrent-ruby (~> 1.0)
builder (3.2.4)
bullet (7.0.7)
@@ -221,7 +221,7 @@ GEM
combine_pdf (1.0.22)
matrix
ruby-rc4 (>= 0.1.5)
concurrent-ruby (1.2.0)
concurrent-ruby (1.1.10)
connection_pool (2.3.0)
crack (0.4.5)
rexml
@@ -237,12 +237,10 @@ GEM
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
ddtrace (1.8.0)
debase-ruby_core_source (>= 0.10.16, <= 0.10.18)
libdatadog (~> 0.9.0.1.0)
libddwaf (~> 1.5.1.0.0)
ddtrace (0.54.1)
debase-ruby_core_source (= 0.10.12)
msgpack
debase-ruby_core_source (0.10.18)
debase-ruby_core_source (0.10.12)
debug (1.7.1)
irb (>= 1.5.0)
reline (>= 0.3.1)
@@ -315,7 +313,7 @@ GEM
nokogiri (>= 1.5.11, < 2.0.0)
foreman (0.87.2)
formatador (0.2.5)
fugit (1.8.1)
fugit (1.7.1)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
fuubar (2.5.1)
@@ -326,7 +324,7 @@ GEM
addressable (~> 2.7)
omniauth (>= 1.9, < 3)
openid_connect (~> 1.2)
globalid (1.0.1)
globalid (1.0.0)
activesupport (>= 5.0)
gmaps4rails (2.1.2)
good_migrations (0.2.1)
@@ -383,11 +381,8 @@ GEM
addressable (~> 2.7)
letter_opener (1.8.1)
launchy (>= 2.2, < 3)
libdatadog (0.9.0.1.0)
libddwaf (1.5.1.0.0)
ffi (~> 1.0)
libv8-node (16.10.0.0)
listen (3.8.0)
libv8-node (15.14.0.1)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.19.1)
@@ -407,8 +402,8 @@ GEM
mini_magick (4.11.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_racer (0.6.3)
libv8-node (~> 16.10.0.0)
mini_racer (0.4.0)
libv8-node (~> 15.14.0.0)
minitest (5.17.0)
monetize (1.12.0)
money (~> 6.12)
@@ -458,7 +453,7 @@ GEM
parallel (1.22.1)
paranoia (2.6.1)
activerecord (>= 5.1, < 7.1)
parser (3.2.0.0)
parser (3.1.3.0)
ast (~> 2.4.1)
paypal-sdk-core (0.3.4)
multi_json (~> 1.0)
@@ -477,11 +472,11 @@ GEM
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (5.0.0)
puma (6.0.2)
puma (5.6.5)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.6.1)
rack (2.2.6.2)
rack (2.2.4)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
rack-oauth2 (1.21.3)
@@ -545,12 +540,12 @@ GEM
activerecord (>= 5.2.4)
activesupport (>= 5.2.4)
i18n
rb-fsevent (0.11.2)
rb-fsevent (0.11.0)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.1)
redis (4.8.0)
regexp_parser (2.6.2)
regexp_parser (2.6.1)
reline (0.3.2)
io-console (~> 0.5)
request_store (1.5.0)
@@ -604,16 +599,16 @@ GEM
rswag-ui (2.8.0)
actionpack (>= 3.1, < 7.1)
railties (>= 3.1, < 7.1)
rubocop (1.44.1)
rubocop (1.42.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.0.0)
parser (>= 3.1.2.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.24.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.24.1)
parser (>= 3.1.1.0)
rubocop-rails (2.17.4)
@@ -645,9 +640,10 @@ GEM
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
sidekiq-scheduler (5.0.0)
sidekiq-scheduler (4.0.3)
redis (>= 4.2.0)
rufus-scheduler (~> 3.2)
sidekiq (>= 4, < 8)
sidekiq (>= 4, < 7)
tilt (>= 1.4.0)
simplecov (0.22.0)
docile (~> 1.1)
@@ -658,7 +654,7 @@ GEM
spreadsheet_architect (5.0.0)
caxlsx (>= 3.3.0, < 4)
rodf (>= 1.0.0, < 2)
spring (4.1.1)
spring (4.1.0)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.2)
@@ -702,7 +698,7 @@ GEM
ttfunk (1.7.0)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
unicode-display_width (2.3.0)
uniform_notifier (1.16.0)
valid_email2 (4.0.4)
activemodel (>= 3.2)
@@ -714,7 +710,7 @@ GEM
activemodel (>= 3.0.0)
public_suffix
vcr (6.1.0)
view_component (2.82.0)
view_component (2.80.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
@@ -829,7 +825,7 @@ DEPENDENCIES
mime-types
mimemagic (> 0.3.5)
mini_portile2 (~> 2.8)
mini_racer
mini_racer (= 0.4.0)
monetize (~> 1.11)
oauth2 (~> 1.4.7)
ofn-qz!
@@ -898,4 +894,4 @@ RUBY VERSION
ruby 3.0.3p157
BUNDLED WITH
2.4.3
2.1.4

View File

@@ -9,39 +9,38 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.sharedResource = false
$scope.columns = Columns.columns
$scope.sorting = SortOptions
$scope.pagination = Orders.pagination
$scope.per_page_options = [
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
{id: 50, name: t('js.admin.orders.index.per_page', results: 50)},
{id: 100, name: t('js.admin.orders.index.per_page', results: 100)}
]
$scope.page = 1
$scope.per_page = $scope.per_page_options[0].id
$scope.confirmRefresh = ->
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
$scope.initStartAndEnDate = ->
$scope.startDate = moment().startOf('day').subtract(7, 'days').format('YYYY-MM-DD')
$scope.endDate = moment().startOf('day').format('YYYY-MM-DD')
$scope.resetFilters = ->
$scope.distributorFilter = ''
$scope.supplierFilter = ''
$scope.orderCycleFilter = ''
$scope.quickSearch = ''
$scope.startDate = undefined
$scope.endDate = undefined
event = new CustomEvent('flatpickr:clear')
$scope.initStartAndEnDate()
event = new CustomEvent('flatpickr:change', {
detail: {
startDate: $scope.startDate,
endDate: $scope.endDate
}
})
window.dispatchEvent(event)
$scope.resetSelectFilters = ->
$scope.resetFilters()
$scope.refreshData()
$scope.fetchResults = ->
# creates indirection in order to factorize the code between orders and bulk orders
# used in app/views/admin/shared/_angular_per_page_controls.html.haml
$scope.refreshData()
$scope.refreshData = ->
$scope.formattedStartDate = moment($scope.startDate).format()
$scope.formattedEndDate = moment($scope.endDate).add(1,'day').format()
return unless moment($scope.formattedStartDate).isValid() and moment($scope.formattedEndDate).isValid()
return "cancel" unless $scope.confirmRefresh()
$scope.loadOrders()
@@ -52,24 +51,33 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.dereferenceLoadedData()
$scope.loadOrders = ->
[formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate)
$scope.setOrderCycleDateRange = ->
start_date = OrderCycles.byID[$scope.orderCycleFilter].orders_open_at
end_date = OrderCycles.byID[$scope.orderCycleFilter].orders_close_at
format = "YYYY-MM-DD HH:mm:ss Z"
$scope.startDate = moment(start_date, format).format('YYYY-MM-DD')
$scope.endDate = moment(end_date, format).startOf('day').format('YYYY-MM-DD')
# throw a flatpickr:change event to change the date back in the datepicker
event = new CustomEvent('flatpickr:change', {
detail: {
startDate: $scope.startDate,
endDate: $scope.endDate
}
})
window.dispatchEvent(event)
$scope.loadOrders = ->
RequestMonitor.load $scope.orders = Orders.index(
"q[state_not_eq]": "canceled",
"q[shipment_state_not_eq]": "shipped",
"q[completed_at_not_null]": "true",
"q[distributor_id_eq]": $scope.distributorFilter,
"q[order_cycle_id_eq]": $scope.orderCycleFilter,
"q[completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined,
"q[completed_at_lt]": if formattedEndDate then formattedEndDate else undefined,
"page": $scope.page,
"per_page": $scope.per_page
"q[completed_at_gteq]": $scope.formattedStartDate,
"q[completed_at_lt]": $scope.formattedEndDate
)
$scope.loadLineItems = ->
[formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate)
RequestMonitor.load LineItems.index(
"q[order_state_not_eq]": "canceled",
"q[order_shipment_state_not_eq]": "shipped",
@@ -77,17 +85,10 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
"q[order_distributor_id_eq]": $scope.distributorFilter,
"q[variant_product_supplier_id_eq]": $scope.supplierFilter,
"q[order_order_cycle_id_eq]": $scope.orderCycleFilter,
"q[order_completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined,
"q[order_completed_at_lt]": if formattedEndDate then formattedEndDate else undefined,
"page": $scope.page,
"per_page": $scope.per_page
"q[order_completed_at_gteq]": $scope.formattedStartDate,
"q[order_completed_at_lt]": $scope.formattedEndDate
)
$scope.formatDates = (startDate, endDate) ->
formattedStartDate = moment(startDate).format('YYYY-MM-DD') if startDate
formattedEndDate = moment(endDate).add(1,'day').format('YYYY-MM-DD') if endDate
return [formattedStartDate, formattedEndDate]
$scope.loadAssociatedData = ->
RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}")
@@ -218,7 +219,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.getGroupBySizeFormattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
scale = $scope.getScale(unitsProduct, unitsVariant)
if scale && value
if scale
value = value / scale if scale != 28.35 && scale != 1 && scale != 453.6 # divide by scale if not smallest unit
$scope.getFormattedValueWithUnitName(value, unitsProduct, unitsVariant, scale)
else
@@ -262,8 +263,4 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity
$scope.weightAdjustedPrice(lineItem)
$scope.changePage = (newPage) ->
$scope.page = newPage
$scope.refreshData()
$scope.resetSelectFilters()

View File

@@ -0,0 +1,5 @@
$( document ).ready(function() {
$("#closeie").click(function() {
$("#ie-warning").hide();
});
})

View File

@@ -1,15 +0,0 @@
# frozen_string_literal: true
class ConfirmModalComponent < ModalComponent
def initialize(id:, confirm_actions: nil, controllers: nil)
super(id: id, close_button: true)
@confirm_actions = confirm_actions
@controllers = controllers
end
private
def close_button_class
"secondary"
end
end

View File

@@ -1,8 +0,0 @@
%div{ id: @id, "data-controller": "modal #{@controllers}", "data-action": "keyup@document->modal#closeIfEscapeKey" }
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
.reveal-modal.fade.tiny.help-modal{ "data-modal-target": "modal" }
= content
.modal-actions
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.cancel'), "data-action": "click->modal#close" }
%input{ class: "button icon-plus primary", type: 'button', value: t('js.admin.modals.confirm'), "data-action": @confirm_actions }

View File

@@ -1,4 +0,0 @@
.modal-actions {
display: flex;
justify-content: space-around;
}

View File

@@ -1,7 +1,26 @@
# frozen_string_literal: true
class HelpModalComponent < ModalComponent
class HelpModalComponent < ViewComponent::Base
def initialize(id:, close_button: true)
super(id: id, close_button: close_button)
@id = id
@close_button = close_button
end
private
def close_button_class
if namespace == "admin"
"red"
else
"primary"
end
end
def close_button?
!!@close_button
end
def namespace
helpers.controller_path.split("/").first
end
end

View File

@@ -1,26 +0,0 @@
# frozen_string_literal: true
class ModalComponent < ViewComponent::Base
def initialize(id:, close_button: true)
@id = id
@close_button = close_button
end
private
def close_button_class
if namespace == "admin"
"red"
else
"primary"
end
end
def close_button?
!!@close_button
end
def namespace
helpers.controller_path.split("/").first
end
end

View File

@@ -3,16 +3,11 @@
require "open_food_network/feature_toggle"
class FeatureToggleConstraint
def initialize(feature_name, negate: false)
def initialize(feature_name)
@feature = feature_name
@negate = negate
end
def matches?(request)
enabled?(request) ^ @negate
end
def enabled?(request)
OpenFoodNetwork::FeatureToggle.enabled?(@feature, current_user(request))
end

View File

@@ -19,22 +19,22 @@ module Admin
end
def show
@report = report_class.new(spree_current_user, params, render: render_data?)
@report = report_class.new(spree_current_user, params, request)
if report_format.present?
export_report
else
show_report
render_report
end
end
private
def export_report
send_data render_report_as(report_format), filename: report_filename
send_data @report.render_as(report_format, controller: self), filename: report_filename
end
def show_report
def render_report
assign_view_data
render "show"
end
@@ -43,29 +43,13 @@ module Admin
@report_type = report_type
@report_subtypes = report_subtypes
@report_subtype = report_subtype
@report_title = report_title
@report_title = if report_subtype
report_subtype_title
else
I18n.t(:name, scope: [:admin, :reports, @report_type])
end
@rendering_options = rendering_options
@table = render_report_as(:html) if render_data?
@data = Reporting::FrontendData.new(spree_current_user)
end
def render_data?
request.post?
end
def render_report_as(format)
if OpenFoodNetwork::FeatureToggle.enabled?(:background_reports, spree_current_user)
job = ReportJob.new
JobProcessor.perform_forked(
job,
report_class, spree_current_user, params, format
)
# This result has been rendered by Rails in safe mode already.
job.result.html_safe # rubocop:disable Rails/OutputSafety
else
@report.render_as(format)
end
end
end
end

View File

@@ -39,14 +39,6 @@ module ReportsActions
params[:report_subtype] || report_subtypes_codes.first
end
def report_title
if report_subtype
report_subtype_title
else
I18n.t(:name, scope: [:admin, :reports, report_type])
end
end
def report_subtype_title
report_subtypes.select { |_name, key| key.to_sym == report_subtype.to_sym }.first[0]
end

View File

@@ -36,7 +36,11 @@ class SplitCheckoutController < ::BaseController
advance_order_state
redirect_to_step
else
render_error
flash.now[:error] ||= I18n.t('split_checkout.errors.global')
render status: :unprocessable_entity, operations: cable_car.
replace("#checkout", partial("split_checkout/checkout")).
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
end
rescue Spree::Core::GatewayError => e
flash[:error] = I18n.t(:spree_gateway_error_flash_for_checkout, error: e.message)
@@ -46,17 +50,6 @@ class SplitCheckoutController < ::BaseController
private
def render_error
flash.now[:error] ||= I18n.t(
'split_checkout.errors.saving_failed',
messages: @order.errors.full_messages.to_sentence
)
render status: :unprocessable_entity, operations: cable_car.
replace("#checkout", partial("split_checkout/checkout")).
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
end
def flash_error_when_no_shipping_method_available
flash[:error] = I18n.t('split_checkout.errors.no_shipping_methods_available')
end

View File

@@ -11,7 +11,6 @@ module CheckoutHelper
def checkout_adjustments_for(order, opts = {})
exclude = opts[:exclude] || {}
reject_zero_amount = opts.fetch(:reject_zero_amount, true)
adjustments = order.all_adjustments.eligible.to_a
@@ -33,10 +32,6 @@ module CheckoutHelper
}
end
if reject_zero_amount
adjustments.reject! { |a| a.amount == 0 }
end
adjustments
end

View File

@@ -12,16 +12,6 @@ module TaxHelper
end
end
def display_line_items_taxes(line_item, display_zero: true)
if line_item.included_tax.positive?
Spree::Money.new(line_item.included_tax, currency: line_item.currency)
elsif line_item.added_tax.positive?
Spree::Money.new(line_item.added_tax, currency: line_item.currency)
elsif display_zero
Spree::Money.new(0.00, currency: line_item.currency)
end
end
def display_total_with_tax(taxable)
total = taxable.amount + taxable.additional_tax_total
Spree::Money.new(total, currency: taxable.currency)

View File

@@ -1,10 +0,0 @@
# frozen_string_literal: true
# Rails standard class for common job code.
class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked
# Most jobs are safe to ignore if the underlying records are no longer available
# discard_on ActiveJob::DeserializationError
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class BulkInvoiceJob < ApplicationJob
class BulkInvoiceJob < ActiveJob::Base
def perform(order_ids, filepath)
pdf = CombinePDF.new

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class HeartbeatJob < ApplicationJob
class HeartbeatJob < ActiveJob::Base
def perform
Spree::Config.last_job_queue_heartbeat_at = Time.now.in_time_zone
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class OrderCycleClosingJob < ApplicationJob
class OrderCycleClosingJob < ActiveJob::Base
def perform
return if recently_closed_order_cycles.empty?

View File

@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Delivers an email with a report of the order cycle to each of its suppliers
class OrderCycleNotificationJob < ApplicationJob
class OrderCycleNotificationJob < ActiveJob::Base
def perform(order_cycle_id)
order_cycle = OrderCycle.find(order_cycle_id)
order_cycle.suppliers.each do |supplier|

View File

@@ -1,34 +0,0 @@
# frozen_string_literal: true
# Renders a report and saves it to a temporary file.
class ReportJob < ActiveJob::Base
def perform(report_class, user, params, format)
report = report_class.new(user, params, render: true)
result = report.render_as(format)
write(result)
end
def done?
@done ||= File.file?(filename)
end
def result
@result ||= read_result
end
private
def write(result)
File.write(filename, result)
end
def read_result
File.read(filename)
ensure
File.unlink(filename)
end
def filename
Rails.root.join("tmp/report-#{job_id}")
end
end

View File

@@ -3,7 +3,7 @@
require 'order_management/subscriptions/summarizer'
# Confirms orders of unconfirmed proxy orders in recently closed Order Cycles
class SubscriptionConfirmJob < ApplicationJob
class SubscriptionConfirmJob < ActiveJob::Base
def perform
confirm_proxy_orders!
end

View File

@@ -2,7 +2,7 @@
require 'order_management/subscriptions/summarizer'
class SubscriptionPlacementJob < ApplicationJob
class SubscriptionPlacementJob < ActiveJob::Base
def perform
proxy_orders.each do |proxy_order|
place_order_for(proxy_order)

View File

@@ -1,13 +0,0 @@
# frozen_string_literal: false
module Calculator
class None < Spree::Calculator
def self.description
I18n.t(:none)
end
def compute(_object = nil)
0
end
end
end

View File

@@ -186,10 +186,6 @@ module Spree
adjustments.tax.inclusive.sum(:amount)
end
def added_tax
adjustments.tax.additional.sum(:amount)
end
def tax_rates
product.tax_category&.tax_rates || []
end

View File

@@ -113,7 +113,7 @@ module Spree
end
def init
self.calculator ||= ::Calculator::None.new
self.calculator ||= ::Calculator::FlatRate.new(preferred_amount: 0)
end
def has_distributor?(distributor)

View File

@@ -32,8 +32,6 @@ module Spree
validate :at_least_one_shipping_category
validates :display_on, inclusion: { in: DISPLAY_ON_OPTIONS.values }, allow_nil: true
after_initialize :init
after_save :touch_distributors
scope :managed_by, lambda { |user|
@@ -69,6 +67,10 @@ module Spree
tracking_url.gsub(/:tracking/, tracking) unless tracking.blank? || tracking_url.blank?
end
def self.calculators
spree_calculators.__send__ model_name_without_spree_namespace
end
# Some shipping methods are only meant to be set via backend
def frontend?
display_on != "back_end"
@@ -108,10 +110,6 @@ module Spree
where(display_on: [nil, ""])
end
def init
self.calculator ||= ::Calculator::None.new if new_record?
end
private
def no_active_or_upcoming_order_cycle_distributors_with_only_one_shipping_method?

View File

@@ -16,11 +16,4 @@ class ApplicationReflex < StimulusReflex::Reflex
#
# For code examples, considerations and caveats, see:
# https://docs.stimulusreflex.com/rtfm/patterns#internationalization
include CanCan::ControllerAdditions
delegate :current_user, to: :connection
def current_ability
Spree::Ability.new(current_user)
end
end

View File

@@ -1,13 +0,0 @@
# frozen_string_literal: true
class ResendConfirmationEmailReflex < ApplicationReflex
def confirm(order_ids)
Spree::Order.where(id: order_ids).find_each do |o|
Spree::OrderMailer.confirm_email_for_customer(o.id, true).deliver_later if can? :resend, o
end
flash[:success] = I18n.t("admin.resend_confirmation_emails_feedback", count: order_ids.count)
cable_ready.dispatch_event(name: "modal:close")
morph "#flashes", render(partial: "shared/flashes", locals: { flashes: flash })
end
end

View File

@@ -1,29 +0,0 @@
# frozen_string_literal: true
# Forks into a separate process to contain memory usage and timeout errors.
class JobProcessor
def self.perform_forked(job, *args)
# Reports should abort when puma threads are killed to avoid wasting
# resources. Nobody would be collecting the result. We still need to
# implement a way to email or download reports later.
timeout = ENV.fetch("RACK_TIMEOUT_WAIT_TIMEOUT", "30").to_i
child = fork do
Process.setproctitle("Job worker #{job.job_id}")
Timeout.timeout(timeout) do
job.perform(*args)
end
# Exit is not a good idea within a Rails process but Rubocop doesn't know
# that we are in a forked process.
exit # rubocop:disable Rails/Exit
end
# Wait for all forked child processes to exit
Process.waitall
ensure
# If this Puma thread is interrupted then we need to detach the child
# process to avoid it becoming a zombie.
Process.detach(child)
end
end

View File

@@ -1,12 +1,6 @@
.row
= t(:required_fields)
(
%span.required *
)
.row
.three.columns.alpha
= bf.label :company, t(".company_legal_name")
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :company, { placeholder: t(".company_placeholder") }
@@ -14,7 +8,6 @@
.row
.three.columns.alpha
= bf.label :address1, t('.address1')
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :address1, { placeholder: t(".address1_placeholder") }
@@ -26,10 +19,8 @@
.row
.three.columns.alpha
= bf.label :city, t(:city)
%span.required *
\/
= bf.label :zipcode, t(:postcode)
%span.required *
.four.columns
= bf.text_field :city, { placeholder: t(:city_placeholder) }
.four.columns.omega
@@ -37,10 +28,8 @@
.row{"data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
.three.columns.alpha
= bf.label :country_id, t(:country)
%span.required *
\/
= bf.label :state_id, t(:state)
%span.required *
.four.columns
= bf.select :country_id, options_for_select(available_countries.map { |c| [c.name, c.id] }, @enterprise.business_address.country_id), {}, { "data-controller": "tom-select", "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange", class: "primary" }
.four.columns.omega
@@ -50,7 +39,6 @@
.row
.three.columns.alpha
= bf.label :phone, t(".legal_phone_number")
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :phone, { placeholder: t(".phone_placeholder") }

View File

@@ -3,4 +3,4 @@
{{ enterprise.name }}
= "{{ enterprise.issues_summary_#{type} ? '('+enterprise.issues_summary_#{type}+')' : '' }}"
= f.submit t(".add_#{type}"), 'ng-click' => "add#{type.capitalize}($event)", 'ng-disabled' => "!new_#{type}_id || !OrderCycle.novel#{type.capitalize}(new_#{type}_id)", "class": "secondary"
= f.submit t(".add_#{type}"), 'ng-click' => "add#{type.capitalize}($event)", 'ng-disabled' => "!new_#{type}_id || !OrderCycle.novel#{type.capitalize}(new_#{type}_id)"

View File

@@ -26,16 +26,15 @@
= f.submit t('.add_fee'), 'ng-click' => 'addExchangeFee($event, exchange)', 'ng-hide' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
%td.actions
.flex
%a{'ng-click' => 'removeExchange($event, exchange)', :class => "icon-trash no-text remove-exchange"}
%a{'ng-click' => 'removeExchange($event, exchange)', :class => "icon-trash no-text remove-exchange"}
- if type == 'supplier'
%tr.panel-row{ object: "exchange",
panels: "{products: 'exchange_products_supplied'}",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,selectAllVariants,suppliedVariants,removeDistributionOfVariant,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading",
colspan: if feature?(:admin_style_v2, spree_current_user) then 5 else 4 end }
colspan: 4 }
- if type == 'distributor'
%tr.panel-row{ object: "exchange",
panels: "{products: 'exchange_products_distributed', tags: 'exchange_tags'}",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,incomingExchangeVariantsFor,variantSuppliedToOrderCycle,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading",
colspan: if feature?(:admin_style_v2, spree_current_user) then 6 else 5 end }
colspan: 5 }

View File

@@ -1,16 +1,16 @@
%colgroup
%col{ ng: { show: 'columns.name.visible' } }
%col{ ng: { show: 'columns.schedules.visible' } }
%col{ ng: { show: 'columns.open.visible' } }
%col{ ng: { show: 'columns.close.visible' } }
%col{ ng: { show: 'columns.open.visible' }, style: 'width: 20%;' }
%col{ ng: { show: 'columns.close.visible' }, style: 'width: 20%;' }
- unless simple_index
%col{ ng: { show: 'columns.producers.visible' } }
%col{ ng: { show: 'columns.coordinator.visible' } }
%col{ ng: { show: 'columns.shops.visible' } }
%col{ ng: { show: 'columns.products.visible' } }
%col
%col
%col
%col{ style: 'width: 5%;' }
%col{ style: 'width: 5%;' }
%col{ style: 'width: 5%;' }
%thead
%tr
@@ -32,3 +32,5 @@
%th{ ng: { show: 'columns.products.visible' } }
=t :products
%th.actions
%th.actions
%th.actions

View File

@@ -32,9 +32,8 @@
= t('.variants')
%td.actions
.flex
%a.edit-order-cycle.icon-edit.no-text{ ng: { href: '{{orderCycle.edit_path}}'}, 'ofn-with-tip' => t(:edit) }
%div{ ng: { if: 'orderCycle.viewing_as_coordinator' } }
%a.clone-order-cycle.icon-copy.no-text{ ng: { href: '{{orderCycle.clone_path}}'}, 'ofn-with-tip' => t(:clone) }
%div{ ng: { if: 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }}
%a.delete-order-cycle.icon-trash.no-text{ ng: { href: '{{orderCycle.delete_path}}'}, data: { method: 'delete', confirm: t(:are_you_sure) }, 'ofn-with-tip' => t(:remove) }
%a.edit-order-cycle.icon-edit.no-text{ ng: { href: '{{orderCycle.edit_path}}'}, 'ofn-with-tip' => t(:edit) }
%td.actions{ ng: { if: 'orderCycle.viewing_as_coordinator' } }
%a.clone-order-cycle.icon-copy.no-text{ ng: { href: '{{orderCycle.clone_path}}'}, 'ofn-with-tip' => t(:clone) }
%td.actions{ ng: { if: 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }}
%a.delete-order-cycle.icon-trash.no-text{ ng: { href: '{{orderCycle.delete_path}}'}, data: { method: 'delete', confirm: t(:are_you_sure) }, 'ofn-with-tip' => t(:remove) }

View File

@@ -1,5 +1,5 @@
%ul{style: "margin-left: 12pt"}
- report_subtypes.each do |report_subtype|
%li
- url = main_app.admin_report_path(report_type: report_type, report_subtype: report_subtype[1])
- url = main_app.admin_report_url(report_type: report_type, report_subtype: report_subtype[1])
= link_to report_subtype[0], url

View File

@@ -1,3 +1,5 @@
- report ||= @report
.report__table-container
%table.report__table
%thead

View File

@@ -1,7 +1,7 @@
- content_for :page_title do
= @report_title
= form_for @report.search, :url => url_for do |f|
= form_for @report.search, :url => url_for(only_path: false) do |f|
%fieldset.no-border-bottom.print-hidden
%legend{ align: 'center'}= t(:report_filters)
= render partial: "admin/reports/filters/#{@report_type}", locals: { f: f }
@@ -19,4 +19,7 @@
- if request.post?
%button.btn-print.icon-print{ onclick: "window.print()"}= t(:report_print)
= @table
/ We don't want to render data unless search params are supplied.
/ Compiling data can take a long time.
- if request.post?
= render "table"

View File

@@ -9,7 +9,7 @@
= t :checkout_cart_total
%td.cart-total.text-right= display_checkout_subtotal(@order)
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).each do |adjustment|
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).reject{ |a| a.amount == 0 }.each do |adjustment|
%tr.adjustment
%th= adjustment.label
%td.text-right= adjustment.display_amount.to_html

View File

@@ -36,6 +36,10 @@
= action_cable_meta_tag
%body{ class: body_classes, "body-scroll": "true", "data-turbo": "false" }
/ [if lte IE 8]
= render partial: "shared/ie_warning"
= javascript_include_tag "iehack"
.off-canvas-wrap{ offcanvas: true }
.fixed.off-canvas-fixed
= render "shared/menu/menu" unless @hide_menu

View File

@@ -19,6 +19,10 @@
= csrf_meta_tags
%body.off-canvas{ style: "background-image: url(#{image_pack_path('tile-wide.png')})", "data-turbo": "false" }
/ [if lte IE 8]
= render partial: "shared/ie_warning"
= javascript_include_tag "iehack"
.off-canvas-wrap{offcanvas: true}
.inner-wrap

View File

@@ -2,6 +2,6 @@
- if defined? flashes
- flashes.each do |type, msg|
%alert.animate-show{"data-controller": "flash"}
.flash{type: "#{type}", class: "alert-box #{type == 'error' ? 'alert' : type}"}
%div{type: "#{type}", class: "alert-box #{type == 'error' ? 'alert' : type}"}
%span= msg
%a.small.close{"data-action": "click->flash#close"} ×

View File

@@ -0,0 +1,31 @@
.alert-box.alert#ie-warning{"data-alert" => ""}
.row.ie-msg
.small-4.large-2.columns
%i.ofn-i_012-warning
.small-8.large-10.columns
%h3
= t :ie_warning_headline
%p
= t :ie_warning_text
.row
.small-4.columns.browserbtn
%a.browserlogo{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"}
%img{src: image_pack_path("browser-logos/chrome.png") }
%a{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"}
= t :ie_warning_chrome
.small-4.columns.browserbtn
%a.browserlogo{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"}
%img{src: image_pack_path("browser-logos/firefox.png") }
%a{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"}
= t :ie_warning_firefox
.small-4.columns.browserbtn
%a.browserlogo{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"}
%img{src: image_pack_path("browser-logos/internet-explorer.png") }
%a{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"}
= t :ie_warning_ie
.row.ie-msg
.small-12.large-12.columns
.text-center
%em
= t :ie_warning_other
%a#closeie.close{href: "#"} ×

View File

@@ -3,3 +3,13 @@
= raw render file: "spec/support/fixtures/stripejs-mock.js"
- else
%script{src: "https://js.stripe.com/v3/", type: "text/javascript"}
:javascript
// persist initial stripe iFrame DOM Object across turbo AJAX page requests
let stripeIFrameQuery = 'iframe[src^="https://js.stripe.com"]';
document.addEventListener('turbo:before-render', function (event) {
const stripeIFrame = document.querySelector(stripeIFrameQuery);
const newStripeIFrame = event.detail.newBody.querySelector(stripeIFrameQuery);
if (stripeIFrame && !newStripeIFrame){
event.detail.newBody.appendChild(stripeIFrame)
}
});

View File

@@ -1,3 +1,3 @@
.already-ordered
.panel
.panel.medium-6
= t("split_checkout.already_ordered.message_html", cart: link_to(t('split_checkout.already_ordered.cart'), "#{main_app.cart_path}#bought-products"))

View File

@@ -1,4 +1,5 @@
%checkout.row#checkout
.small-12.medium-12.columns
= render partial: "split_checkout/tabs"
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
= render partial: "split_checkout/form"

View File

@@ -89,7 +89,7 @@
"data-action": "toggle#toggle shippingmethod#selectShippingMethod",
"data-toggle-show": shipping_method.require_ship_address
= shipping_method_form.label shipping_method.id, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
%em.fees= payment_or_shipping_price(shipping_method, @order)
%em= payment_or_shipping_price(shipping_method, @order)
- display_ship_address = display_ship_address || (ship_method_is_selected && shipping_method.require_ship_address)
%div.checkout-input{"data-shippingmethod-target": "shippingMethodDescription", "data-shippingmethodid": shipping_method.id , style: "display: #{ship_method_is_selected ? 'block' : 'none'}" }
#distributor_address.panel

View File

@@ -1,7 +1,7 @@
- content_for :injection_data do
= inject_saved_credit_cards
%div.checkout-step{"class": if checkout_step?(:summary) then "checkout-summary" end}
%div.checkout-step
= form_with url: checkout_update_path(checkout_step), model: @order, method: :put,
data: { remote: "true" } do |form|

View File

@@ -12,12 +12,12 @@
name: "order[payments_attributes][][payment_method_id]",
checked: (payment_method.id == selected_payment_method),
"data-action": "paymentmethod#selectPaymentMethod",
"data-paymentmethod-id": "#{payment_method.id}",
"data-paymentmethod-id": "paymentmethod#{payment_method.id}",
"data-paymentmethod-target": "input"
= f.label :payment_method_id, "#{payment_method.name}", for: "payment_method_#{payment_method.id}"
%em.fees=payment_or_shipping_price(payment_method, @order)
%em=payment_or_shipping_price(payment_method, @order)
.paymentmethod-container{"data-paymentmethod-id": "#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"}
.paymentmethod-container{"data-paymentmethod-id": "paymentmethod#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"}
- if payment_method.description && !payment_method.description.empty?
.paymentmethod-description.panel
#{payment_method.description}

View File

@@ -1,95 +1,81 @@
.summary-main
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
.checkout-substep
.checkout-title
= t("split_checkout.step3.delivery_details.title")
%a.summary-edit{href: main_app.checkout_step_path(:details)}
= t("split_checkout.step3.delivery_details.edit")
.medium-10
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.your_details.title")
.summary-subtitle
= @order.shipping_method.name
%em.fees= payment_or_shipping_price(@order.shipping_method, @order)
.two-columns
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.address")
%span
= @order.bill_address.firstname
= @order.bill_address.lastname
%div
= @order.bill_address.phone
%div
= @order.user.email if @order.user
%br
%div
= @order.bill_address.address1
- unless @order.bill_address.address2.blank?
%div
= @order.bill_address.address2
%div
= @order.bill_address.city
%div
= @order.bill_address.state
%div
= @order.bill_address.zipcode
%div
= @order.bill_address.country
- if @order.shipping_method.description.present?
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.instructions")
%div
= @order.shipping_method.description
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.first_name.label")
%span.summary-value
= @order.bill_address.firstname
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.last_name.label")
%span.summary-value
= @order.bill_address.lastname
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.email.label")
%span.summary-value
= @order.user ? @order.user.email : "Change me"
%hr
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.phone.label")
%span.summary-value
= @order.bill_address.phone
.checkout-substep
.checkout-title
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.billing_address.title")
= render "summary_address", address: @order.bill_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.shipping_address.title")
= render "summary_address", address: @order.shipping_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.delivery_info.title")
%div.summary
%span.summary-label
= t("split_checkout.step1.shipping_info.title")
%span.summary-value
= @order.shipping_method.name
%div.summary-description
= @order.shipping_method.description
%a.summary-edit{href: main_app.checkout_step_path(:details)}
= t("split_checkout.step3.your_details.edit")
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.payment_method.title")
%div.summary
%span.summary-value
= last_payment_method(@order)&.name
%div.summary-description
= last_payment_method(@order)&.description
%a.summary-edit{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.payment_method.edit")
.two-columns
%div
- payment_method = last_payment_method(@order)
= payment_method&.name
%em.fees=payment_or_shipping_price(payment_method, @order)
- if payment_method&.description.present?
%div
.summary-subtitle
= t("split_checkout.step3.payment_method.instructions")
%div
= last_payment_method(@order)&.description
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.order.title")
%a.summary-edit{href: main_app.cart_path}
= t("split_checkout.step3.order.edit")
= render 'spree/orders/summary', order: @order, display_footer: false
= render 'spree/orders/summary', order: @order
.summary-right{ "data-controller": "sticky", "data-sticky-target": "container" }
.summary-right-line.total
.summary-right-line-label= t :order_total_price
.summary-right-line-value#order_total= @order.display_total.to_html
.summary-right-line
.summary-right-line-label= t :order_produce
.summary-right-line-value= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
.summary-right-line
.summary-right-line-label= adjustment.label
.summary-right-line-value= adjustment.display_amount.to_html
- if @order.total_tax > 0
.summary-right-line
.summary-right-line-label= t :order_includes_tax
.summary-right-line-value#tax-row= display_checkout_tax_total(@order)
.checkout-submit
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
.checkout-step3{"data-controller": "sticky", "data-sticky-target": "container"}
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
.medium-6
.checkout-submit
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
%a.button.cancel{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.cancel")

View File

@@ -0,0 +1,36 @@
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address1.label")
%span.summary-value
= address.address1
- unless @order.bill_address.address2.blank?
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address2.label")
%span.summary-value
= address.address2
%div.summary
%span.summary-label
= t("split_checkout.step1.address.city.label")
%span.summary-value
= address.city
%div.summary
%span.summary-label
= t("split_checkout.step1.address.state_id.label")
%span.summary-value
= address.state
%div.summary
%span.summary-label
= t("split_checkout.step1.address.zipcode.label")
%span.summary-value
= address.zipcode
%div.summary
%span.summary-label
= t("split_checkout.step1.address.country_id.label")
%span.summary-value
= address.country

View File

@@ -1,4 +1,4 @@
%div.checkout-substep
%div.checkout-substep.medium-6
%div.checkout-input
- if platform_terms_required? && distributor_terms_required?
= f.check_box :accept_terms, { name: "accept_terms", checked: all_terms_and_conditions_already_accepted? }, 1, nil
@@ -14,3 +14,6 @@
= t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions, target: '_blank'))
= f.error_message_on :terms_and_conditions, standalone: true
%div.checkout-input
= t("split_checkout.step3.agree")

View File

@@ -1,4 +1,4 @@
%div{"data-controller": "stripe-cards", "data-paymentmethod-id": "#{payment_method.id}" }
%div{"data-controller": "stripe-cards"}
- if @saved_credit_cards.any?
.checkout-input
%label

View File

@@ -20,11 +20,11 @@
%td{:align => "right"}
= item.quantity
%td{:align => "right"}
= display_line_items_taxes(item)
= item.included_tax > 0 ? item.display_included_tax : ""
%td{:align => "right"}
= item.display_amount_with_adjustments
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- taxable = adjustment.adjustable_type == "Spree::Shipment" ? adjustment.adjustable : adjustment
%tr
%td

View File

@@ -30,7 +30,7 @@
%td{:align => "right"}
= display_line_item_tax_rates(item)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td
%strong= "#{raw(adjustment.label)}"

View File

@@ -32,7 +32,7 @@
%label{ :for => 'order_cycle_filter' }
= t("admin.order_cycle")
%br
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter' } }
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: "setOrderCycleDateRange()" } }
.date_filter{class: "four columns"}
%label
= t("date_range")
@@ -94,20 +94,14 @@
= t("admin.orders.bulk_management.variants_without_unit_value")
%hr.divider.sixteen.columns.alpha.omega
.clear
%div{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' }, style: "display: flex; justify-content: flex-start; column-gap: 10px; margin-bottom: 15px" }
%div{ style: "flex-grow: 1" }
.controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } }
%div.three.columns.alpha
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
-# This -20px is a hack to make the dropdowns align properly
%div{ style: "margin-right: -20px;" }
%div.three.columns
= render 'admin/shared/bulk_actions_dropdown'
%div
%div.ten.columns
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%div{ style: "flex-grow: 1"}
%div{ style: "float: right;"}
= render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right" }
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
= render partial: "components/admin_spinner"
@@ -190,7 +184,4 @@
%td.actions
%a{ 'ng-click' => "deleteLineItem(line_item)", :class => "delete-line-item icon-trash no-text" }
%div{'ng-show' => "!RequestMonitor.loading && orders.length > 0" }
= render partial: 'admin/shared/angular_pagination'
= render 'spree/admin/shared/custom-confirm'

View File

@@ -30,17 +30,15 @@
="#{t('admin.actions')}".html_safe
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%div.menu_item
%span.name{ "data-controller": "modal-link", "data-action": "click->modal-link#open", "data-modal-link-target-value": "resend_confirmation" }
= t('.resend_confirmation')
%div.menu_item
%span.name.invoices-modal{'ng-controller' => 'bulkInvoiceCtrl', 'ng-click' => 'createBulkInvoice()' }
= t('.print_invoices')
%div.menu_item
%span.name{'ng-controller' => 'bulkCancelCtrl', 'ng-click' => 'cancelSelectedOrders()' }
= t('.cancel_orders')
= render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right" }
= render partial: 'per_page_controls', locals: { position: "right" }
%table#listing_orders.index.responsive{width: "100%", 'ng-init' => 'initialise()', 'ng-show' => "!RequestMonitor.loading && orders.length > 0" }
%colgroup
@@ -65,7 +63,7 @@
%tbody
%tr{ng: {repeat: 'order in orders track by order.id', class: {even: "'even'", odd: "'odd'"}}, 'ng-class' => "{'state-{{order.state}}': true, 'row-loading': rowStatus[order.id] == 'loading'}"}
%td.align-center
%input{type: 'checkbox', 'ng-model' => 'checkboxes[order.id]', 'ng-change' => 'toggleSelection(order.id)', value: '{{order.id}}', name: 'order_ids[]'}
%input{type: 'checkbox', 'ng-model' => 'checkboxes[order.id]', 'ng-change' => 'toggleSelection(order.id)'}
%td.align-center
{{order.distributor_name}}
%td.align-center
@@ -120,7 +118,3 @@
= t('.no_orders_found')
= render 'spree/admin/shared/custom-confirm'
= render ConfirmModalComponent.new(id: "resend_confirmation", confirm_actions: "click->resend-confirmation-email#confirm", controllers: "resend-confirmation-email") do
.margin-bottom-30
= t('.resend_confirmation_confirm_html')

View File

@@ -43,7 +43,7 @@
j(line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false))] }
.join('" + \'\x0A\' + "')}",
'\x0A',
"#{checkout_adjustments_for(@order, exclude: [:line_item], reject_zero_amount: false)
"#{checkout_adjustments_for(@order, exclude: [:line_item])
.reject{ |a| a.amount == 0 }
.reverse.map { |adjustment| '%5s %-27.27s%8.8s' %
["",

View File

@@ -11,8 +11,6 @@
- if flash[:success]
.flash.success= flash[:success]
= render partial: "shared/flashes"
= render partial: "spree/layouts/admin/progress_spinner"
%header#header{"data-hook" => ""}

View File

@@ -40,7 +40,7 @@
= t :email_order_summary_subtotal
%td{align: "right"}
= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td{align: "right", colspan: "3"}
= "#{raw(adjustment.label)}:"

View File

@@ -31,7 +31,7 @@
%span.order-total.item-total= display_checkout_subtotal(@order)
%td
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr.order-adjustment
%td.text-right{:colspan => "3"}
= adjustment.label

View File

@@ -1,5 +1,3 @@
- display_footer = true if display_footer.nil?
%table#line-items{"data-hook" => "order_details"}
%col{valign: "middle"}/
%col{halign: "center", valign: "middle", width: "5%"}/
@@ -28,4 +26,36 @@
%td.text-right.total{"data-hook" => "order_item_total"}
%span= item.display_amount_with_adjustments.to_html
= render partial: "spree/orders/totals_footer", locals: { order: order } if display_footer
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)

View File

@@ -1,33 +0,0 @@
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)

View File

@@ -5,6 +5,15 @@ document.addEventListener("turbolinks:before-cache", () =>
);
export default class extends Controller {
connect() {
setTimeout(this.fadeout.bind(this), 3000);
}
fadeout() {
this.element.classList.add("animate-hide-500");
setTimeout(this.close.bind(this), 500);
}
close() {
this.element.remove();
}

View File

@@ -55,7 +55,6 @@ export default class extends Flatpickr {
mode,
};
window.addEventListener("flatpickr:change", this.onChangeEvent.bind(this));
window.addEventListener("flatpickr:clear", this.clear.bind(this));
}
clear(e) {

View File

@@ -1,10 +1,33 @@
import { Controller } from "stimulus";
import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
connect() {
useOpenAndCloseAsAModal(this);
open() {
this.backgroundTarget.style.display = "block";
this.modalTarget.style.display = "block";
setTimeout(() => {
this.modalTarget.classList.add("in");
this.backgroundTarget.classList.add("in");
document.querySelector("body").classList.add("modal-open");
});
}
close() {
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");
document.querySelector("body").classList.remove("modal-open");
setTimeout(() => {
this.backgroundTarget.style.display = "none";
this.modalTarget.style.display = "none";
}, 200);
}
closeIfEscapeKey(e) {
if (e.code == "Escape") {
this.close();
}
}
}

View File

@@ -1,7 +1,15 @@
import ModalLinkController from "./modal_link_controller";
import { Controller } from "stimulus";
export default class extends ModalLinkController {
getIdentifier() {
return "help-modal";
export default class extends Controller {
static values = { target: String };
open() {
let helpModal = document.getElementById(this.targetValue);
let helpModalController =
this.application.getControllerForElementAndIdentifier(
helpModal,
"help-modal"
);
helpModalController.open();
}
}

View File

@@ -1,31 +0,0 @@
export const useOpenAndCloseAsAModal = (controller) => {
Object.assign(controller, {
open: function () {
this.backgroundTarget.style.display = "block";
this.modalTarget.style.display = "block";
setTimeout(() => {
this.modalTarget.classList.add("in");
this.backgroundTarget.classList.add("in");
document.querySelector("body").classList.add("modal-open");
});
}.bind(controller),
close: function () {
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");
document.querySelector("body").classList.remove("modal-open");
setTimeout(() => {
this.backgroundTarget.style.display = "none";
this.modalTarget.style.display = "none";
}, 200);
}.bind(controller),
closeIfEscapeKey: function (e) {
if (e.code == "Escape") {
this.close();
}
}.bind(controller),
});
};

View File

@@ -1,15 +0,0 @@
import { Controller } from "stimulus";
import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
connect() {
useOpenAndCloseAsAModal(this);
window.addEventListener("modal:close", this.close.bind(this));
}
disconnect() {
window.removeEventListener("modal:close", this.close);
}
}

View File

@@ -1,18 +0,0 @@
import { Controller } from "stimulus";
export default class extends Controller {
static values = { target: String };
open() {
let modal = document.getElementById(this.targetValue);
let modalController = this.application.getControllerForElementAndIdentifier(
modal,
this.getIdentifier()
);
modalController.open();
}
getIdentifier() {
return "modal";
}
}

View File

@@ -12,12 +12,17 @@ export default class extends Controller {
selectPaymentMethod(event) {
this.setPaymentMethod(event.target.dataset.paymentmethodId);
// Send an event to the right (ie. the one with the same paymentmethodId)
// StripeCardsController to initialize the form elements with the selected card
const customEvent = new CustomEvent("stripecards:initSelectedCard", {
detail: event.target.dataset.paymentmethodId,
});
document.dispatchEvent(customEvent);
const stripeCardSelector =
this.application.getControllerForElementAndIdentifier(
document
.querySelector(
`[data-paymentmethod-id="${event.target.dataset.paymentmethodId}"]`
)
.querySelector('[data-controller="stripe-cards"]'),
"stripe-cards"
);
stripeCardSelector?.initSelectedCard();
}
setPaymentMethod(paymentMethodContainerId) {

View File

@@ -1,18 +0,0 @@
import ApplicationController from "./application_controller";
export default class extends ApplicationController {
connect() {
super.connect();
}
confirm() {
const order_ids = [];
document
.querySelectorAll("#listing_orders input[name='order_ids[]']:checked")
.forEach((checkbox) => {
order_ids.push(checkbox.value);
});
this.stimulate("ResendConfirmationEmailReflex#confirm", order_ids);
}
}

View File

@@ -15,7 +15,7 @@ export default class extends Controller {
this.containerTarget.style.bottom = "-1px";
const observer = new IntersectionObserver(
([e]) => {
e.target.classList.toggle("sticked", e.intersectionRatio < 1);
e.target.classList.toggle("sticked", e.intersectionRatio <= 1);
},
{ threshold: [1] }
);

View File

@@ -7,11 +7,6 @@ export default class extends Controller {
connect() {
this.initSelectedCard();
document.addEventListener("stripecards:initSelectedCard", (e) => {
if (e.detail == this.element.dataset.paymentmethodId) {
this.initSelectedCard();
}
});
}
initSelectedCard() {

View File

@@ -127,4 +127,3 @@
@import "app/components/pagination_component/pagination_component";
@import "app/components/table_header_component/table_header_component";
@import "app/components/search_input_component/search_input_component";
@import 'app/components/confirm_modal_component/confirm_modal_component';

View File

@@ -38,7 +38,6 @@
font-size: 120%;
color: $color-1;
font-weight: 600;
margin-top: 0;
&.notice { background-color: rgba($color-notice, 0.8) }
&.success { background-color: rgba($color-success, 0.8) }

View File

@@ -26,26 +26,14 @@ fieldset .filter-actions .button:hover,
}
&.disabled,
&[disabled],
&.disabled.secondary,
&[disabled].secondary {
@include backgroundAndBorder($v2-dark-light-grey);
&[disabled] {
@include backgroundAndBorder($v2-light-grey);
box-shadow: none;
cursor: default;
color: white;
&:hover {
@include backgroundAndBorder($v2-dark-light-grey);
box-shadow: none;
cursor: default;
color: white;
}
}
&.secondary,
&.cancel,
&.icon-remove,
&#clear_all_filters {
&.icon-remove {
background-color: $white;
border: 2px solid $v2-blue-light;
color: $v2-blue-light;

View File

@@ -46,10 +46,6 @@ table tbody tr {
display: flex;
column-gap: 10px;
}
&.actions > .flex {
justify-content: flex-end;
}
}
&.even,
&.odd {
@@ -61,6 +57,7 @@ table tbody tr {
table thead tr th.actions,
table tbody tr td.actions {
background-color: $v2-body-bg !important;
// Special for icons in the actions column
[class*="icon-"],
button[class*="icon-"]:not(.disabled):not([disabled]):not(.secondary):not(.cancel) {
@@ -99,7 +96,7 @@ table tbody tr td.actions {
}
}
table {
table#listing_orders {
thead th.actions,
thead td.actions {
background-color: $v2-medium-light-grey !important;
@@ -108,42 +105,16 @@ table {
background-color: white !important;
}
td {
// When the table is the listing of orders, we need to increase the height of the cells
padding: 20px 0;
&.actions {
padding-left: 20px;
border-bottom: 2px solid $v2-medium-light-grey !important; // needs to be important because of already defined with important
}
}
}
table tbody tr:hover > td {
background-color: #e9f3fc !important; // needs to be important because of already defined with important
}
table#listing_orders {
td {
// When the table is the listing of orders, we need to increase the height of the cells
padding: 20px 0;
&:not(:first-child) {
border-left: none; // Only show left border on the first cells, as it indicates the order state by its color
}
}
}
table#listing_order_cycles tr.open td {
background-color: #d9fccb !important; // needs to be important because of already defined with important
}
table#listing_order_cycles tr.closed td {
background-color: #eee !important; // needs to be important because of already defined with important
}
table#listing_order_cycles tr.upcoming td {
background-color: #fbfccb !important; // needs to be important because of already defined with important
}
tbody.panel-ctrl.expanded > tr:not(.panel-row) > td {
border-bottom: 1px solid #6788a2 !important; // needs to be important because of already defined with important
}
tbody.panel-ctrl.expanded > tr:not(.panel-row) > td.selected {
border-bottom: none !important; // it's a bit annoying to always put that important, but it's the only way to override the default style
}

View File

@@ -1,10 +0,0 @@
tags-input .tags li.tag-item {
background-color: $v2-blue-light;
}
tags-input .tags {
box-shadow: none;
&.focused {
box-shadow: none;
}
}

View File

@@ -1,19 +0,0 @@
ul.wizard-progress li {
a {
color: white;
}
background-color: $v2-dark-light-grey;
&:before,
&:after {
background-color: $v2-dark-light-grey;
}
&.current {
background-color: $v2-blue-light;
&:before,
&:after {
background-color: $v2-blue-light;
}
}
}

View File

@@ -12,10 +12,6 @@
@import "components/sidebar.scss";
@import "components/tom_select.scss";
@import "components/dropdown.scss";
@import "components/wizard_progress.scss";
@import "components/tags-input.scss";
@import "others.scss";
body {
background-color: $v2-body-bg;

View File

@@ -1,6 +0,0 @@
/* The aim of this file is to not create a file for each small modification on components */
#advanced_settings {
background-color: $v2-blue-lightest;
border-color: $v2-blue-dark;
}

View File

@@ -7,7 +7,7 @@
color: $v2-medium-grey !important;
padding-left: 5px;
font-size: 13px;
height: 35px;
padding-top: 3px;
.select2-arrow {
color: $v2-medium-grey;
@@ -17,7 +17,7 @@
&.select2-container-active,
&:hover {
.select2-choice {
background-color: white !important;
background-color: transparent !important;
border-color: $v2-medium-grey !important;
}
}
@@ -45,26 +45,14 @@
}
.select2-choices {
border-color: $v2-medium-grey !important;
min-height: 35px;
.select2-search-choice {
background-color: $v2-blue-light;
}
}
&.select2-drop-above {
.select2-choices {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
}
}
.select2-drop {
border-color: $v2-medium-grey;
&.select2-drop-above.select2-drop-active {
border-color: $v2-medium-grey;
}
}
.select2-search {

View File

@@ -18,10 +18,9 @@ fieldset {
// Change the color of all inputs
color: $v2-medium-grey;
border-color: $v2-light-grey !important;
font-size: 13px;
&:focus {
border-color: $v2-medium-grey !important;
border-color: $v2-medium-grey;
}
}

View File

@@ -12,7 +12,3 @@
a:not(.button) {
@include v2-link-color();
}
h4 {
color: $v2-medium-dark-grey;
}

View File

@@ -9,7 +9,6 @@ $v2-dark-grey: #333333;
$v2-medium-dark-grey: #444444;
$v2-body-grey: $color-4;
$v2-medium-grey: #717171;
$v2-dark-light-grey: #d9d9d9;
$v2-medium-light-grey: #e6e6e6;
$v2-light-grey: #e7e7e7;

View File

@@ -39,6 +39,7 @@
@import 'home_tagline';
@import 'hub_node';
@import 'hubs';
@import 'ie_warning';
@import 'images';
@import 'lists';
@import 'loading';
@@ -76,4 +77,3 @@ ofn-modal {
@import '../admin/shared/scroll_bar';
@import 'app/components/help_modal_component/help_modal_component';
@import 'app/components/confirm_modal_component/confirm_modal_component';

View File

@@ -4,6 +4,17 @@
// ANIMATION FUNCTIONS
@keyframes fade-out-hide {
0% {opacity: 1; visibility: visible;}
99% {opacity: 0; visibility: visible;}
100% {opacity: 0; visibility: hidden;}
}
.animate-hide-500 {
animation: fade-out-hide 0.5s;
}
//
@-webkit-keyframes slideInDown {
0% {
opacity: 0;

View File

@@ -0,0 +1,40 @@
#ie-warning {
margin-bottom: 0;
padding-bottom: 2rem;
.ie-msg {
background: rgba(255, 255, 255, 0.15);
padding: 0.5rem;
margin-bottom: 1rem;
margin-top: 1rem;
}
.browserbtn {
text-align: center;
margin-bottom: 1rem;
a {
color: white;
font-size: 1rem;
filter: alpha(opacity = 70);
opacity: 0.7;
&:hover, &:active, &:focus {
filter: alpha(opacity = 100);
opacity: 1;
}
}
a.browserlogo {
display: block;
width: 100%;
}
}
i {
font-size: 5rem;
color: white;
text-align: center;
display: block;
}
}

View File

@@ -62,9 +62,8 @@
}
.already-ordered {
margin-left: 20px;
.panel {
margin-top: 3rem;
background-color: $grey-250;
border: 1px solid $tiny-blue;
color: $grey-700;
@@ -161,24 +160,22 @@
label {
margin-top: 0.3rem;
& + em {
margin-left: -0.5rem;
font-size: 14px; // same as label
font-weight: bold;
// Add opening and closing parentheses
&:before {
content: "(";
}
&:after {
content: ")";
}
}
}
}
}
em.fees {
margin-left: -0.5rem;
font-size: 14px; // same as label
font-weight: bold;
margin-left: 10px;
// Add opening and closing parentheses
&:before {
content: "(";
}
&:after {
content: ")";
}
}
.checkout-input span.formError, div.error.card-errors {
background-color: rgba(193, 18, 43, 0.1);
color: $red-700;
@@ -206,7 +203,42 @@
@include force-wrap;
}
.checkout-step3 {
padding-left: 15px;
padding-right: 15px;
.checkout-submit {
margin-top: 0;
margin-bottom: 0;
padding-top: 2rem;
.button {
margin-bottom: 1rem;
}
}
&.sticked {
background-color: $white;
box-shadow: 0 -6px 12px -6px rgba(0, 0, 0, 0.33);
border-left: 1px solid $light-grey;
border-right: 1px solid $light-grey;
border-top: 1px solid $light-grey;
}
@media screen and (max-width: 700px) {
&.sticked {
width: auto;
margin-left: -15px;
margin-right: -15px;
box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.33);
.checkout-submit {
width: 100%;
padding-left: 15px;
padding-right: 15px;
}
}
}
}
.checkout-submit {
margin-top: 5rem;
@@ -259,44 +291,24 @@
}
}
.checkout-summary {
margin-top: 0;
.summary {
margin-bottom: 2px;
font-size: 0.875rem;
.checkout-substep {
font-size: 0.875rem;
margin-top: 1rem;
.summary-label {
font-weight: bold;
}
&:first-child {
margin-top: 20px;
}
.two-columns {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 1fr;
grid-column-gap: 10px;
grid-row-gap: 0px;
}
.summary-description {
@include force-wrap;
color: $min-accessible-grey;
}
.summary-edit {
color: $teal-400;
text-decoration: underline;
display: inline-block;
margin-left: 15px;
font-size: 0.875rem;
font-weight: normal;
font-family: $body-font;
&:hover {
color: $teal-500;
text-decoration: underline;
&:after {
color: $teal-500;
}
}
display: block;
margin-top: 5px;
&:after {
background-image: url("../images/edit-with-pen.svg");
content: " ";
@@ -309,94 +321,11 @@
top: 2px;
}
}
.summary-subtitle {
font-weight: bold;
margin-bottom: 20px;
}
}
.checkout-summary {
form {
display: flex;
justify-content: space-between;
.summary-main {
width: 66.66%;
border-right: 1px solid #DDD;
padding-right: 20px;
padding-top: 20px;
}
.summary-right {
width: calc(33.33% - 20px);
padding-left: 20px;
padding-right: 20px;
border-right: 1px solid #DDD;
}
}
}
.summary-right {
padding-top: 40px;
.checkout-submit {
margin-top: 40px;
.button.primary {
background-color: $clr-turquoise;
&:hover {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
}
}
}
.summary-right-line {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.summary-right-line-label {
font-size: 0.875rem;
}
.summary-right-line-value {
font-size: 0.875rem;
text-align: right;
}
&.total {
margin-bottom: 20px;
@include headingFont;
.summary-right-line-label {
font-weight: bold;
font-size: 1.06rem;
}
.summary-right-line-value {
font-size: 1.06rem;
}
}
}
.summary-right {
.checkout-input {
display: flex;
align-items: baseline;
input[type=checkbox] + label {
margin-left: 1rem;
}
}
}
#line-items {
display: block;
overflow-x: auto;
h5 {
background-color: transparent;
}
}
.two-columns-inputs {
@@ -452,70 +381,3 @@
}
}
}
// Handle the mobile view for the summary step
@media screen and (max-width: 800px) {
.checkout-summary form {
display: block;
}
.checkout-summary form .summary-right {
width: calc(100% + 30px);
margin-left: -15px;
background-color: white;
border-right: none;
border-top: 1px solid #DDD;
padding-top: 20px;
&.sticked {
box-shadow: 0 -4px 10px #DDD;
}
.summary-right-line.total {
margin-bottom: 10px;
}
.checkout-submit {
margin-top: 10px;
.checkout-input {
margin-bottom: 10px;
}
.button {
margin-bottom: 10px;
}
}
}
.checkout-summary form .summary-main {
width: 100%;
border-right: none;
}
.checkout-summary .checkout-substep .two-columns {
// only one column actually
grid-template-columns: 1fr;
> :nth-child(2) {
margin-top: 20px;
}
}
.checkout-summary .summary-subtitle {
margin-bottom: 10px;
}
}
// For small screen or for iOS devices, increase to 16px the input font-size
@media screen and (max-width: 700px) {
.checkout-input input {
font-size: 16px;
}
}
@supports(-webkit-overflow-scrolling: touch) {
.checkout-input input {
font-size: 16px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -114,8 +114,7 @@ module Openfoodnetwork
Calculator::FlexiRate,
Calculator::PerItem,
Calculator::PriceSack,
Calculator::Weight,
Calculator::None
Calculator::Weight
]
app.config.spree.calculators.add_class('enterprise_fees')
@@ -134,8 +133,7 @@ module Openfoodnetwork
Calculator::FlatRate,
Calculator::FlexiRate,
Calculator::PerItem,
Calculator::PriceSack,
Calculator::None
Calculator::PriceSack
]
app.config.spree.calculators.add_class('tax_rates')
@@ -215,6 +213,7 @@ module Openfoodnetwork
# Instead, they must be explicitly included below
# http://stackoverflow.com/questions/8012434/what-is-the-purpose-of-config-assets-precompile
config.assets.initialize_on_precompile = true
config.assets.precompile += ['iehack.js']
config.assets.precompile += ['admin/*.js', 'admin/**/*.js']
config.assets.precompile += ['web/all.js']
config.assets.precompile += ['darkswarm/all.js']

View File

@@ -48,9 +48,6 @@ Openfoodnetwork::Application.configure do
reconnect_attempts: 1
}
config.action_cable.url = "#{ENV['OFN_URL']}/cable"
config.action_cable.allowed_request_origins = [/http:\/\/#{ENV['OFN_URL']}\/*/, /https:\/\/#{ENV['OFN_URL']}\/*/]
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"

Some files were not shown because too many files have changed in this diff Show More