mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-04 02:31:33 +00:00
Compare commits
1 Commits
v4.4.7
...
v4.4.5-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0262dcd11b |
6
.env
6
.env
@@ -61,9 +61,3 @@ SMTP_PASSWORD="f00d"
|
||||
# STRIPE_INSTANCE_PUBLISHABLE_KEY="pk_test_xxxx" # This can be a test key or a live key
|
||||
# STRIPE_CLIENT_ID="ca_xxxx" # This can be a development ID or a production ID
|
||||
# STRIPE_ENDPOINT_SECRET="whsec_xxxx"
|
||||
|
||||
# New relic settings
|
||||
# see: https://one.eu.newrelic.com/admin-portal/, Administration > API keys to get the license key
|
||||
# NEW_RELIC_AGENT_ENABLED=true
|
||||
# NEW_RELIC_APP_NAME="Open Food Network"
|
||||
# NEW_RELIC_LICENSE_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
@@ -13,8 +13,7 @@ postcss.config.js
|
||||
|
||||
# SCSS
|
||||
# Enabled: most of admin
|
||||
/app/webpacker/css/admin/globals/mixins.scss
|
||||
/app/webpacker/css/admin/globals/variables.scss
|
||||
/app/webpacker/css/admin/globals/
|
||||
/app/webpacker/css/admin/shared/
|
||||
/app/webpacker/css/admin_v3/globals/variables.scss
|
||||
/app/webpacker/css/darkswarm/
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.55.1.
|
||||
# using RuboCop version 1.55.0.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 67
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
||||
# URISchemes: http, https
|
||||
Layout/LineLength:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/users_controller.rb'
|
||||
- 'app/models/customer.rb'
|
||||
- 'app/models/spree/line_item.rb'
|
||||
- 'spec/controllers/admin/order_cycles_controller_spec.rb'
|
||||
- 'spec/controllers/spree/admin/orders_controller_spec.rb'
|
||||
- 'spec/lib/reports/customers_report_spec.rb'
|
||||
- 'spec/migrations/migrate_customer_names_spec.rb'
|
||||
- 'spec/models/order_cycle_spec.rb'
|
||||
- 'spec/models/product_importer_spec.rb'
|
||||
- 'spec/models/spree/adjustment_spec.rb'
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
- 'spec/models/spree/variant_spec.rb'
|
||||
- 'spec/services/products_renderer_spec.rb'
|
||||
- 'spec/system/admin/adjustments_spec.rb'
|
||||
- 'spec/system/admin/bulk_order_management_spec.rb'
|
||||
- 'spec/system/admin/customers_spec.rb'
|
||||
- 'spec/system/admin/order_cycles/simple_spec.rb'
|
||||
- 'spec/system/admin/orders_spec.rb'
|
||||
- 'spec/system/admin/product_import_spec.rb'
|
||||
- 'spec/system/consumer/shopping/cart_spec.rb'
|
||||
- 'spec/system/consumer/shopping/products_spec.rb'
|
||||
|
||||
# Offense count: 17
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: enums
|
||||
@@ -415,6 +443,39 @@ Naming/VariableNumber:
|
||||
- 'spec/models/spree/tax_rate_spec.rb'
|
||||
- 'spec/requests/api/orders_spec.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: ExpectedOrder, Include.
|
||||
# ExpectedOrder: index, show, new, edit, create, update, destroy
|
||||
# Include: app/controllers/**/*.rb
|
||||
Rails/ActionOrder:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/resource_controller.rb'
|
||||
- 'app/controllers/api/v0/orders_controller.rb'
|
||||
- 'app/controllers/spree/admin/images_controller.rb'
|
||||
- 'app/controllers/spree/admin/invoices_controller.rb'
|
||||
- 'app/controllers/spree/admin/products_controller.rb'
|
||||
- 'app/controllers/spree/admin/taxons_controller.rb'
|
||||
- 'app/controllers/spree/admin/variants_controller.rb'
|
||||
- 'app/controllers/user_confirmations_controller.rb'
|
||||
|
||||
# Offense count: 12
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/ActiveRecordCallbacksOrder:
|
||||
Exclude:
|
||||
- 'app/models/customer.rb'
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/enterprise_group.rb'
|
||||
- 'app/models/enterprise_relationship.rb'
|
||||
- 'app/models/spree/order.rb'
|
||||
- 'app/models/spree/payment.rb'
|
||||
- 'app/models/spree/product.rb'
|
||||
- 'app/models/spree/return_authorization.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
- 'app/models/spree/variant.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: Severity, Include.
|
||||
# Include: app/models/**/*.rb
|
||||
@@ -450,6 +511,27 @@ Rails/CompactBlank:
|
||||
- 'lib/reporting/report_ruler.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/parameters.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Rails/DotSeparatedKeys:
|
||||
Exclude:
|
||||
- 'app/controllers/api/v1/base_controller.rb'
|
||||
|
||||
# Offense count: 27
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Rails/DurationArithmetic:
|
||||
Exclude:
|
||||
- 'app/services/create_order_cycle.rb'
|
||||
- 'spec/jobs/order_cycle_closing_job_spec.rb'
|
||||
- 'spec/jobs/order_cycle_opened_job_spec.rb'
|
||||
- 'spec/services/permissions/order_spec.rb'
|
||||
- 'spec/services/terms_of_service_spec.rb'
|
||||
- 'spec/system/admin/bulk_order_management_spec.rb'
|
||||
- 'spec/system/admin/order_cycles/list_spec.rb'
|
||||
- 'spec/system/admin/orders_spec.rb'
|
||||
- 'spec/system/admin/reports/orders_and_fulfillment_spec.rb'
|
||||
- 'spec/system/admin/reports/packing_report_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Rails/ExpandedDateRange:
|
||||
@@ -1026,7 +1108,7 @@ Style/HashLikeCase:
|
||||
Exclude:
|
||||
- 'app/models/enterprise.rb'
|
||||
|
||||
# Offense count: 1792
|
||||
# Offense count: 1781
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
|
||||
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
|
||||
|
||||
6
Gemfile
6
Gemfile
@@ -103,8 +103,8 @@ gem 'redis', '>= 4.0', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'sidekiq'
|
||||
gem 'sidekiq-scheduler'
|
||||
|
||||
gem "cable_ready", "5.0.1"
|
||||
gem "stimulus_reflex", "3.5.0.rc3"
|
||||
gem "cable_ready", "5.0.0.rc2"
|
||||
gem "stimulus_reflex", "3.5.0.rc2"
|
||||
|
||||
gem 'combine_pdf'
|
||||
gem 'wicked_pdf'
|
||||
@@ -138,8 +138,6 @@ gem 'mini_portile2', '~> 2.8'
|
||||
gem "faraday"
|
||||
gem "private_address_check"
|
||||
|
||||
gem 'newrelic_rpm'
|
||||
|
||||
group :production, :staging do
|
||||
gem 'sd_notify' # For better Systemd process management. Used by Puma.
|
||||
end
|
||||
|
||||
40
Gemfile.lock
40
Gemfile.lock
@@ -169,7 +169,6 @@ GEM
|
||||
aws-sigv4 (~> 1.6)
|
||||
aws-sigv4 (1.6.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
base64 (0.1.1)
|
||||
bcrypt (3.1.18)
|
||||
bigdecimal (3.0.2)
|
||||
bindata (2.4.15)
|
||||
@@ -182,7 +181,7 @@ GEM
|
||||
bullet (7.0.7)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.1)
|
||||
cable_ready (5.0.0.rc2)
|
||||
actionpack (>= 5.2)
|
||||
actionview (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
@@ -232,8 +231,8 @@ GEM
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
datafoodconsortium-connector (1.0.0.pre.alpha.8)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
|
||||
datafoodconsortium-connector (1.0.0.pre.alpha.6)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.4)
|
||||
date (3.3.3)
|
||||
debug (1.8.0)
|
||||
irb (>= 1.5.0)
|
||||
@@ -353,20 +352,20 @@ GEM
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.6.3)
|
||||
json-canonicalization (0.3.2)
|
||||
json-canonicalization (0.3.1)
|
||||
json-jwt (1.16.3)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
json-ld (3.2.5)
|
||||
json-ld (3.2.3)
|
||||
htmlentities (~> 4.3)
|
||||
json-canonicalization (~> 0.3, >= 0.3.2)
|
||||
json-canonicalization (~> 0.3)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
multi_json (~> 1.15)
|
||||
rack (>= 2.2, < 4)
|
||||
rdf (~> 3.2, >= 3.2.10)
|
||||
rack (~> 2.2)
|
||||
rdf (~> 3.2, >= 3.2.9)
|
||||
json-schema (3.0.0)
|
||||
addressable (>= 2.8)
|
||||
json_spec (1.1.5)
|
||||
@@ -375,7 +374,7 @@ GEM
|
||||
jsonapi-serializer (2.2.0)
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.7.1)
|
||||
knapsack_pro (5.3.5)
|
||||
knapsack_pro (5.3.4)
|
||||
rake
|
||||
language_server-protocol (3.17.0.3)
|
||||
launchy (2.5.0)
|
||||
@@ -397,9 +396,9 @@ GEM
|
||||
marcel (1.0.2)
|
||||
matrix (0.4.2)
|
||||
method_source (1.0.0)
|
||||
mime-types (3.5.0)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2023.0218.1)
|
||||
mime-types-data (3.2021.0225)
|
||||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
@@ -423,7 +422,6 @@ GEM
|
||||
timeout
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
newrelic_rpm (9.3.1)
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.3)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
@@ -558,7 +556,7 @@ GEM
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rdf (3.2.11)
|
||||
rdf (3.2.9)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
redcarpet (3.6.0)
|
||||
redis (4.8.1)
|
||||
@@ -618,8 +616,7 @@ GEM
|
||||
rswag-ui (2.10.1)
|
||||
actionpack (>= 3.1, < 7.1)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rubocop (1.56.0)
|
||||
base64 (~> 0.1.1)
|
||||
rubocop (1.55.0)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
@@ -695,12 +692,12 @@ GEM
|
||||
state_machines-activerecord (0.9.0)
|
||||
activerecord (>= 6.0)
|
||||
state_machines-activemodel (>= 0.9.0)
|
||||
stimulus_reflex (3.5.0.rc3)
|
||||
stimulus_reflex (3.5.0.rc2)
|
||||
actioncable (>= 5.2, < 8)
|
||||
actionpack (>= 5.2, < 8)
|
||||
actionview (>= 5.2, < 8)
|
||||
activesupport (>= 5.2, < 8)
|
||||
cable_ready (~> 5.0)
|
||||
cable_ready (>= 5.0.0.rc2)
|
||||
nokogiri (~> 1.0)
|
||||
rack (>= 2, < 4)
|
||||
railties (>= 5.2, < 8)
|
||||
@@ -740,7 +737,7 @@ GEM
|
||||
rails (>= 5.2, < 8.0)
|
||||
stimulus_reflex (>= 3.5.0.pre2)
|
||||
view_component (>= 2.28.0)
|
||||
virtual_assembly-semantizer (1.0.5)
|
||||
virtual_assembly-semantizer (1.0.4)
|
||||
json-ld (~> 3.2, >= 3.2.3)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
@@ -799,7 +796,7 @@ DEPENDENCIES
|
||||
bootsnap
|
||||
bugsnag
|
||||
bullet
|
||||
cable_ready (= 5.0.1)
|
||||
cable_ready (= 5.0.0.rc2)
|
||||
cancancan (~> 1.15.0)
|
||||
capybara
|
||||
catalog!
|
||||
@@ -850,7 +847,6 @@ DEPENDENCIES
|
||||
mimemagic (> 0.3.5)
|
||||
mini_portile2 (~> 2.8)
|
||||
monetize (~> 1.11)
|
||||
newrelic_rpm
|
||||
oauth2 (~> 1.4.7)
|
||||
omniauth-rails_csrf_protection
|
||||
omniauth_openid_connect
|
||||
@@ -898,7 +894,7 @@ DEPENDENCIES
|
||||
spring
|
||||
spring-commands-rspec
|
||||
state_machines-activerecord
|
||||
stimulus_reflex (= 3.5.0.rc3)
|
||||
stimulus_reflex (= 3.5.0.rc2)
|
||||
stringex (~> 2.8.5)
|
||||
stripe
|
||||
timecop
|
||||
|
||||
@@ -135,7 +135,6 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
display_name: null
|
||||
on_hand: null
|
||||
price: null
|
||||
tax_category_id: null
|
||||
DisplayProperties.setShowVariants product.id, true
|
||||
|
||||
|
||||
@@ -347,6 +346,9 @@ filterSubmitProducts = (productsToFilter) ->
|
||||
if product.hasOwnProperty("category_id")
|
||||
filteredProduct.primary_taxon_id = product.category_id
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("tax_category_id")
|
||||
filteredProduct.tax_category_id = product.tax_category_id
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("inherits_properties")
|
||||
filteredProduct.inherits_properties = product.inherits_properties
|
||||
hasUpdatableProperty = true
|
||||
@@ -387,9 +389,6 @@ filterSubmitVariant = (variant) ->
|
||||
if variant.hasOwnProperty("display_name")
|
||||
filteredVariant.display_name = variant.display_name
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("tax_category_id")
|
||||
filteredVariant.tax_category_id = variant.tax_category_id
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("display_as")
|
||||
filteredVariant.display_as = variant.display_as
|
||||
hasUpdatableProperty = true
|
||||
|
||||
@@ -9,9 +9,10 @@ angular.module('Darkswarm').controller "RegistrationFormCtrl", ($scope, Registra
|
||||
$scope.create = (form) ->
|
||||
if ($scope.valid(form))
|
||||
$scope.disableButton()
|
||||
EnterpriseRegistrationService.create($scope.enableButton).then(() ->
|
||||
EnterpriseRegistrationService.create().then(() ->
|
||||
$scope.enableButton()
|
||||
)
|
||||
end
|
||||
|
||||
$scope.update = (nextStep, form) ->
|
||||
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
|
||||
|
||||
@@ -16,7 +16,7 @@ nav {
|
||||
|
||||
&.inactive {
|
||||
cursor: default;
|
||||
color: $dark-grey;
|
||||
color: $disabled-dark;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ nav {
|
||||
}
|
||||
|
||||
.pagination-gap {
|
||||
color: $dark-grey;
|
||||
color: $disabled-dark;
|
||||
}
|
||||
|
||||
.pagination-page {
|
||||
|
||||
@@ -40,7 +40,7 @@ class ProductComponent < ViewComponentReflex::Component
|
||||
when 'on_demand'
|
||||
@product.on_demand
|
||||
when 'tax_category'
|
||||
@product.variant.tax_category.name
|
||||
@product.tax_category.name
|
||||
when 'inherits_properties'
|
||||
@product.inherits_properties
|
||||
when 'import_date'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.search-input {
|
||||
border: 1px solid $light-grey;
|
||||
border: 1px solid $disabled-light;
|
||||
height: 3em;
|
||||
display: flex;
|
||||
line-height: 3em;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
position: relative;
|
||||
|
||||
.selector-main {
|
||||
border: 1px solid $light-grey;
|
||||
border: 1px solid $disabled-light;
|
||||
height: 3em;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
@@ -30,7 +30,7 @@
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 5px solid $light-grey;
|
||||
border-top: 5px solid $disabled-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
z-index: 1;
|
||||
background-color: white;
|
||||
margin-top: -1px;
|
||||
border: 1px solid $light-grey;
|
||||
border: 1px solid $disabled-light;
|
||||
|
||||
.selector-items {
|
||||
overflow-y: auto;
|
||||
@@ -51,7 +51,7 @@
|
||||
.selector-item {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border-bottom: 1px solid $light-grey;
|
||||
border-bottom: 1px solid $disabled-light;
|
||||
position: relative;
|
||||
height: 3em;
|
||||
line-height: 3em;
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
|
||||
.selector-wrapper {
|
||||
.super-selector-search {
|
||||
border-bottom: 1px solid $light-grey;
|
||||
border-bottom: 1px solid $disabled-light;
|
||||
padding: 10px 5px;
|
||||
|
||||
input {
|
||||
border: 1px solid $light-grey;
|
||||
border: 1px solid $disabled-light;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
|
||||
@@ -55,15 +55,6 @@ module Admin
|
||||
@report_title = report_title
|
||||
@rendering_options = rendering_options
|
||||
@data = Reporting::FrontendData.new(spree_current_user)
|
||||
|
||||
variant_id_in = params[:variant_id_in]&.compact_blank
|
||||
load_selected_variant if variant_id_in.present?
|
||||
end
|
||||
|
||||
# Orders and Fulfillment Reports include a per product filter, load any selected product
|
||||
def load_selected_variant
|
||||
variant = Spree::Variant.find(params[:variant_id_in][0])
|
||||
@variant_serialized = Api::Admin::VariantSerializer.new(variant)
|
||||
end
|
||||
|
||||
def render_data?
|
||||
|
||||
@@ -24,10 +24,9 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@object.attributes = permitted_resource_params
|
||||
if @object.save
|
||||
flash[:success] = flash_message_for(@object, :successfully_created)
|
||||
def update
|
||||
if @object.update(permitted_resource_params)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
respond_with(@object) do |format|
|
||||
format.html { redirect_to location_after_save }
|
||||
format.js { render layout: false }
|
||||
@@ -37,9 +36,10 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @object.update(permitted_resource_params)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
def create
|
||||
@object.attributes = permitted_resource_params
|
||||
if @object.save
|
||||
flash[:success] = flash_message_for(@object, :successfully_created)
|
||||
respond_with(@object) do |format|
|
||||
format.html { redirect_to location_after_save }
|
||||
format.js { render layout: false }
|
||||
|
||||
@@ -5,6 +5,11 @@ module Api
|
||||
class OrdersController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
end
|
||||
|
||||
def index
|
||||
authorize! :admin, Spree::Order
|
||||
|
||||
@@ -21,11 +26,6 @@ module Api
|
||||
}
|
||||
end
|
||||
|
||||
def show
|
||||
authorize! :read, order
|
||||
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :admin, order
|
||||
|
||||
|
||||
@@ -69,14 +69,14 @@ module Api
|
||||
end
|
||||
|
||||
def missing_parameter(error)
|
||||
message = I18n.t('api.missing_parameter', param: error.param)
|
||||
message = I18n.t(:missing_parameter, param: error.param, scope: :api)
|
||||
|
||||
render status: :unprocessable_entity,
|
||||
json: json_api_error(message)
|
||||
end
|
||||
|
||||
def unpermitted_parameters(error)
|
||||
message = I18n.t('api.unpermitted_parameters', params: error.params.join(", "))
|
||||
message = I18n.t(:unpermitted_parameters, params: error.params.join(", "), scope: :api)
|
||||
|
||||
render status: :unprocessable_entity,
|
||||
json: json_api_error(message)
|
||||
|
||||
@@ -20,10 +20,6 @@ module Spree
|
||||
render layout: !request.xhr?
|
||||
end
|
||||
|
||||
def edit
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def create
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
set_viewable
|
||||
@@ -38,6 +34,10 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def update
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
set_viewable
|
||||
|
||||
@@ -10,13 +10,6 @@ module Spree
|
||||
authorize! :invoice, @order
|
||||
end
|
||||
|
||||
def show
|
||||
invoice_id = params[:id]
|
||||
invoice_pdf = BulkInvoiceService.new.filepath(invoice_id)
|
||||
|
||||
send_file(invoice_pdf, type: 'application/pdf', disposition: :inline)
|
||||
end
|
||||
|
||||
def create
|
||||
Spree::Order.where(id: params[:order_ids]).find_each do |order|
|
||||
authorize! :invoice, order
|
||||
@@ -30,10 +23,30 @@ module Spree
|
||||
def generate
|
||||
@order = Order.find_by(number: params[:order_id])
|
||||
authorize! :invoice, @order
|
||||
OrderInvoiceGenerator.new(@order).generate_or_update_latest_invoice
|
||||
|
||||
@comparator = OrderInvoiceComparator.new(@order)
|
||||
if @comparator.can_generate_new_invoice?
|
||||
@order.invoices.create!(
|
||||
date: Time.zone.today,
|
||||
number: @order.invoices.count + 1,
|
||||
data: invoice_data
|
||||
)
|
||||
elsif @comparator.can_update_latest_invoice?
|
||||
@order.invoices.last.update!(
|
||||
date: Time.zone.today,
|
||||
data: invoice_data
|
||||
)
|
||||
end
|
||||
redirect_back(fallback_location: spree.admin_dashboard_path)
|
||||
end
|
||||
|
||||
def show
|
||||
invoice_id = params[:id]
|
||||
invoice_pdf = BulkInvoiceService.new.filepath(invoice_id)
|
||||
|
||||
send_file(invoice_pdf, type: 'application/pdf', disposition: :inline)
|
||||
end
|
||||
|
||||
def poll
|
||||
invoice_id = params[:invoice_id]
|
||||
|
||||
@@ -43,6 +56,12 @@ module Spree
|
||||
render json: { created: false }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def invoice_data
|
||||
@invoice_data ||= InvoiceDataGenerator.new(@order).generate
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,24 +16,10 @@ module Spree
|
||||
before_action :load_spree_api_key, only: [:index, :variant_overrides]
|
||||
before_action :strip_new_properties, only: [:create, :update]
|
||||
|
||||
def index
|
||||
@current_user = spree_current_user
|
||||
@show_latest_import = params[:latest_import] || false
|
||||
end
|
||||
|
||||
def show
|
||||
session[:return_to] ||= request.referer
|
||||
redirect_to( action: :edit )
|
||||
end
|
||||
|
||||
def new
|
||||
@object.shipping_category = DefaultShippingCategory.find_or_create
|
||||
end
|
||||
|
||||
def edit
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def create
|
||||
delete_stock_params_and_set_after do
|
||||
@object.attributes = permitted_resource_params
|
||||
@@ -49,6 +35,20 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
session[:return_to] ||= request.referer
|
||||
redirect_to( action: :edit )
|
||||
end
|
||||
|
||||
def index
|
||||
@current_user = spree_current_user
|
||||
@show_latest_import = params[:latest_import] || false
|
||||
end
|
||||
|
||||
def edit
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def update
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
|
||||
|
||||
@@ -5,12 +5,6 @@ module Spree
|
||||
class TaxonsController < Spree::Admin::BaseController
|
||||
respond_to :html, :json, :js
|
||||
|
||||
def edit
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.find(params[:id])
|
||||
@permalink_part = @taxon.permalink.split("/").last
|
||||
end
|
||||
|
||||
def create
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.build(params[:taxon])
|
||||
@@ -32,6 +26,12 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.find(params[:id])
|
||||
@permalink_part = @taxon.permalink.split("/").last
|
||||
end
|
||||
|
||||
def update
|
||||
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
||||
@taxon = @taxonomy.taxons.find(params[:id])
|
||||
|
||||
@@ -7,17 +7,28 @@ module Spree
|
||||
class VariantsController < ::Admin::ResourceController
|
||||
belongs_to 'spree/product'
|
||||
|
||||
before_action :load_data, only: [:new, :edit]
|
||||
|
||||
def index
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def new
|
||||
def edit
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
def edit
|
||||
def update
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
|
||||
if @object.update(permitted_resource_params)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
redirect_to spree.admin_product_variants_url(params[:product_id], @url_filters)
|
||||
else
|
||||
redirect_to spree.edit_admin_product_variant_url(params[:product_id],
|
||||
@object,
|
||||
@url_filters)
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
@@ -42,19 +53,6 @@ module Spree
|
||||
@object.on_hand = on_hand.to_i if on_hand.present?
|
||||
end
|
||||
|
||||
def update
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
|
||||
if @object.update(permitted_resource_params)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
redirect_to spree.admin_product_variants_url(params[:product_id], @url_filters)
|
||||
else
|
||||
redirect_to spree.edit_admin_product_variant_url(params[:product_id],
|
||||
@object,
|
||||
@url_filters)
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
scoper = OpenFoodNetwork::ScopeVariantsForSearch.new(variant_search_params)
|
||||
@variants = scoper.search
|
||||
@@ -109,12 +107,6 @@ module Spree
|
||||
:include_out_of_stock
|
||||
).to_h.with_indifferent_access
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_data
|
||||
@tax_categories = TaxCategory.order(:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -69,10 +69,6 @@ module Spree
|
||||
if @order.contents.update_cart(order_params)
|
||||
@order.recreate_all_fees! # Enterprise fees on line items and on the order itself
|
||||
|
||||
# Re apply the voucher
|
||||
VoucherAdjustmentsService.new(@order).update
|
||||
@order.update_totals_and_states
|
||||
|
||||
if @order.complete?
|
||||
@order.update_payment_fees!
|
||||
@order.create_tax_charge!
|
||||
|
||||
@@ -49,10 +49,8 @@ module Spree
|
||||
render cable_ready: cable_car.inner_html(
|
||||
"#signup-feedback",
|
||||
partial("layouts/alert",
|
||||
locals: {
|
||||
type: "success",
|
||||
message: t('devise.user_registrations.spree_user.signed_up_but_unconfirmed')
|
||||
})
|
||||
locals: { type: "success",
|
||||
message: t('devise.user_registrations.spree_user.signed_up_but_unconfirmed') })
|
||||
)
|
||||
else
|
||||
render status: :unprocessable_entity, cable_ready: cable_car.morph(
|
||||
|
||||
@@ -5,13 +5,6 @@ class UserConfirmationsController < DeviseController
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include CablecarResponses
|
||||
|
||||
# GET /resource/confirmation?confirmation_token=abcdef
|
||||
def show
|
||||
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
||||
|
||||
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource) }
|
||||
end
|
||||
|
||||
# GET /resource/confirmation/new
|
||||
def new
|
||||
build_resource({})
|
||||
@@ -40,6 +33,13 @@ class UserConfirmationsController < DeviseController
|
||||
respond_with_navigational(resource){ redirect_to login_path }
|
||||
end
|
||||
|
||||
# GET /resource/confirmation?confirmation_token=abcdef
|
||||
def show
|
||||
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
||||
|
||||
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource) }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_return_url
|
||||
|
||||
@@ -5,6 +5,9 @@ class VoucherAdjustmentsController < BaseController
|
||||
|
||||
def create
|
||||
if add_voucher
|
||||
VoucherAdjustmentsService.calculate(@order)
|
||||
@order.update_totals_and_states
|
||||
|
||||
update_payment_section
|
||||
elsif @order.errors.present?
|
||||
render_error
|
||||
@@ -18,9 +21,6 @@ class VoucherAdjustmentsController < BaseController
|
||||
@order.voucher_adjustments.where(originator_id: adjustment.originator_id)&.destroy_all
|
||||
end
|
||||
|
||||
# Update order to make sure we display the appropriate payment method
|
||||
@order.update_totals_and_states
|
||||
|
||||
update_payment_section
|
||||
end
|
||||
|
||||
@@ -45,17 +45,12 @@ class VoucherAdjustmentsController < BaseController
|
||||
|
||||
adjustment = voucher.create_adjustment(voucher.code, @order)
|
||||
|
||||
unless adjustment.persisted?
|
||||
unless adjustment.valid?
|
||||
@order.errors.add(:voucher_code, I18n.t('split_checkout.errors.add_voucher_error'))
|
||||
adjustment.errors.each { |error| @order.errors.import(error) }
|
||||
return false
|
||||
end
|
||||
|
||||
clear_payments
|
||||
|
||||
VoucherAdjustmentsService.new(@order).update
|
||||
@order.update_totals_and_states
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
@@ -83,9 +78,4 @@ class VoucherAdjustmentsController < BaseController
|
||||
def voucher_params
|
||||
params.require(:order).permit(:voucher_code)
|
||||
end
|
||||
|
||||
# Clear payments and payment fees, to not affect voucher adjustment calculation
|
||||
def clear_payments
|
||||
@order.payments.incomplete.destroy_all
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,7 +42,7 @@ module Admin
|
||||
{ name: 'shipping_methods', icon_class: "icon-truck", show: show_shipping_methods },
|
||||
{ name: 'payment_methods', icon_class: "icon-money", show: show_payment_methods },
|
||||
{ name: 'enterprise_fees', icon_class: "icon-tasks", show: show_enterprise_fees },
|
||||
{ name: 'vouchers', icon_class: "icon-ticket", show: is_shop },
|
||||
{ name: 'vouchers', icon_class: "icon-ticket", show: true },
|
||||
{ name: 'enterprise_permissions', icon_class: "icon-plug", show: true,
|
||||
href: admin_enterprise_relationships_path },
|
||||
{ name: 'inventory_settings', icon_class: "icon-list-ol", show: is_shop },
|
||||
|
||||
@@ -5,9 +5,13 @@ class BulkInvoiceJob < ApplicationJob
|
||||
delegate :render, to: ActionController::Base
|
||||
|
||||
def perform(order_ids, filepath, options = {})
|
||||
orders = sorted_orders(order_ids)
|
||||
orders.filter!(&:invoiceable?) if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
|
||||
orders.each(&method(:generate_invoice))
|
||||
pdf = CombinePDF.new
|
||||
|
||||
sorted_orders(order_ids).each do |order|
|
||||
invoice = renderer.render_to_string(order)
|
||||
|
||||
pdf << CombinePDF.parse(invoice)
|
||||
end
|
||||
|
||||
ensure_directory_exists filepath
|
||||
|
||||
@@ -28,17 +32,6 @@ class BulkInvoiceJob < ApplicationJob
|
||||
@renderer ||= InvoiceRenderer.new
|
||||
end
|
||||
|
||||
def generate_invoice(order)
|
||||
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
|
||||
OrderInvoiceGenerator.new(order).generate_or_update_latest_invoice
|
||||
order.invoices.first.presenter
|
||||
else
|
||||
order
|
||||
end
|
||||
invoice = renderer.render_to_string(renderer_data)
|
||||
pdf << CombinePDF.parse(invoice)
|
||||
end
|
||||
|
||||
def broadcast(filepath, channel)
|
||||
file_id = filepath.split("/").last.split(".").first
|
||||
|
||||
@@ -54,8 +47,4 @@ class BulkInvoiceJob < ApplicationJob
|
||||
def ensure_directory_exists(filepath)
|
||||
FileUtils.mkdir_p(File.dirname(filepath))
|
||||
end
|
||||
|
||||
def pdf
|
||||
@pdf ||= CombinePDF.new
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,14 +48,7 @@ module Spree
|
||||
|
||||
def invoice_email(order_or_order_id)
|
||||
@order = find_order(order_or_order_id)
|
||||
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
|
||||
OrderInvoiceGenerator.new(@order).generate_or_update_latest_invoice
|
||||
@order.invoices.first.presenter
|
||||
else
|
||||
@order
|
||||
end
|
||||
|
||||
pdf = InvoiceRenderer.new.render_to_string(renderer_data)
|
||||
pdf = InvoiceRenderer.new.render_to_string(@order)
|
||||
|
||||
attach_file("invoice-#{@order.number}.pdf", pdf)
|
||||
I18n.with_locale valid_locale(@order.user) do
|
||||
|
||||
@@ -45,7 +45,7 @@ module Calculator
|
||||
|
||||
def line_items_total(order)
|
||||
matched_line_items = order.line_items.select do |line_item|
|
||||
line_item.variant.tax_category == rate.tax_category
|
||||
line_item.product.tax_category == rate.tax_category
|
||||
end
|
||||
|
||||
matched_line_items.sum(&:total)
|
||||
@@ -70,7 +70,7 @@ module Calculator
|
||||
def applicable_rate?(applicator, line_item)
|
||||
fee = applicator.enterprise_fee
|
||||
(!fee.inherits_tax_category && fee.tax_category == rate.tax_category) ||
|
||||
(fee.inherits_tax_category && line_item.variant.tax_category == rate.tax_category)
|
||||
(fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category)
|
||||
end
|
||||
|
||||
# Finds relevant fees for whole order,
|
||||
|
||||
@@ -19,9 +19,6 @@ class Customer < ApplicationRecord
|
||||
belongs_to :enterprise
|
||||
belongs_to :user, class_name: "Spree::User", optional: true
|
||||
has_many :orders, class_name: "Spree::Order"
|
||||
before_validation :downcase_email
|
||||
before_validation :empty_code
|
||||
before_create :associate_user
|
||||
before_destroy :update_orders_and_delete_canceled_subscriptions
|
||||
|
||||
belongs_to :bill_address, class_name: "Spree::Address", optional: true
|
||||
@@ -32,6 +29,9 @@ class Customer < ApplicationRecord
|
||||
alias_attribute :shipping_address, :ship_address
|
||||
accepts_nested_attributes_for :ship_address
|
||||
|
||||
before_validation :downcase_email
|
||||
before_validation :empty_code
|
||||
|
||||
validates :code, uniqueness: { scope: :enterprise_id, allow_nil: true }
|
||||
validates :email, presence: true, 'valid_email_2/email': true,
|
||||
uniqueness: {
|
||||
@@ -41,11 +41,13 @@ class Customer < ApplicationRecord
|
||||
|
||||
scope :of, ->(enterprise) { where(enterprise_id: enterprise) }
|
||||
scope :managed_by, ->(user) {
|
||||
user&.persisted? ? where(user: user).or(of(Enterprise.managed_by(user))) : none
|
||||
}
|
||||
user&.persisted? ? where(user: user).or(of(Enterprise.managed_by(user))) : none
|
||||
}
|
||||
scope :created_manually, -> { where(created_manually: true) }
|
||||
scope :visible, -> { where(id: Spree::Order.complete.select(:customer_id)).or(created_manually) }
|
||||
|
||||
before_create :associate_user
|
||||
|
||||
attr_accessor :gateway_recurring_payment_client_secret, :gateway_shop_id
|
||||
|
||||
def full_name
|
||||
|
||||
@@ -91,7 +91,7 @@ class Enterprise < ApplicationRecord
|
||||
end
|
||||
has_one_attached :white_label_logo, service: image_service do |attachment|
|
||||
attachment.variant :default, resize_to_fill: [217, 44]
|
||||
attachment.variant :mobile, resize_to_fill: [128, 26]
|
||||
attachment.variant :mobile, resize_to_fill: [75, 26]
|
||||
end
|
||||
|
||||
validates :logo,
|
||||
@@ -125,12 +125,13 @@ class Enterprise < ApplicationRecord
|
||||
before_validation :set_unused_address_fields
|
||||
after_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? }
|
||||
|
||||
after_touch :touch_distributors
|
||||
after_create :set_default_contact
|
||||
after_create :relate_to_owners_enterprises
|
||||
after_rollback :restore_permalink
|
||||
after_touch :touch_distributors
|
||||
after_create_commit :send_welcome_email
|
||||
|
||||
after_rollback :restore_permalink
|
||||
|
||||
scope :by_name, -> { order('name') }
|
||||
scope :visible, -> { where(visible: "public") }
|
||||
scope :not_hidden, -> { where.not(visible: "hidden") }
|
||||
|
||||
@@ -14,13 +14,13 @@ class EnterpriseGroup < ApplicationRecord
|
||||
validates :address, presence: true, associated: true
|
||||
before_validation :set_undefined_address_fields
|
||||
before_validation :set_unused_address_fields
|
||||
before_validation :sanitize_permalink
|
||||
after_save :unset_undefined_address_fields
|
||||
after_find :unset_undefined_address_fields
|
||||
after_save :unset_undefined_address_fields
|
||||
|
||||
validates :name, presence: true
|
||||
validates :description, presence: true
|
||||
|
||||
before_validation :sanitize_permalink
|
||||
validates :permalink, uniqueness: true, presence: true
|
||||
|
||||
delegate :phone, :address1, :address2, :city, :zipcode, :state, :country, to: :address
|
||||
|
||||
@@ -11,9 +11,9 @@ class EnterpriseRelationship < ApplicationRecord
|
||||
message: I18n.t('validation_msg_relationship_already_established')
|
||||
}
|
||||
|
||||
after_save :update_permissions_of_child_variant_overrides
|
||||
before_destroy :revoke_all_child_variant_overrides
|
||||
before_destroy :destroy_related_exchanges
|
||||
after_save :update_permissions_of_child_variant_overrides
|
||||
|
||||
scope :with_enterprises, -> {
|
||||
joins("
|
||||
|
||||
@@ -5,7 +5,6 @@ class Invoice < ApplicationRecord
|
||||
serialize :data, Hash
|
||||
before_validation :serialize_order
|
||||
after_create :cancel_previous_invoices
|
||||
default_scope { order(created_at: :desc) }
|
||||
|
||||
def presenter
|
||||
@presenter ||= Invoice::DataPresenter.new(self)
|
||||
|
||||
@@ -4,8 +4,7 @@ class Invoice
|
||||
class DataPresenter
|
||||
attr_reader :invoice
|
||||
|
||||
delegate :data, to: :invoice
|
||||
delegate :number, :date, to: :invoice, prefix: true
|
||||
delegate :data, :date, to: :invoice
|
||||
|
||||
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
|
||||
|
||||
@@ -79,14 +78,14 @@ class Invoice
|
||||
end.sort_by { |tax| tax[:rate_amount] }
|
||||
end
|
||||
|
||||
def display_date
|
||||
I18n.l(invoice_date.to_date, format: :long)
|
||||
end
|
||||
|
||||
def all_tax_adjustments
|
||||
all_eligible_adjustments.select { |a| a.originator_type == 'Spree::TaxRate' }
|
||||
end
|
||||
|
||||
def invoice_date
|
||||
date
|
||||
end
|
||||
|
||||
def paid?
|
||||
data[:payment_state] == 'paid' || data[:payment_state] == 'credit_owed'
|
||||
end
|
||||
|
||||
@@ -24,10 +24,6 @@ class Invoice
|
||||
render_address([address1, address2, city, zipcode, state&.name])
|
||||
end
|
||||
|
||||
def blank?
|
||||
@data.nil?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_address(address_parts)
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
class Invoice
|
||||
class DataPresenter
|
||||
class Distributor < Invoice::DataPresenter::Base
|
||||
attributes :name, :abn, :acn, :logo_url, :display_invoice_logo, :invoice_text, :email_address,
|
||||
:phone
|
||||
attributes :name, :abn, :acn, :logo_url, :display_invoice_logo, :invoice_text, :email_address
|
||||
attributes_with_presenter :contact, :address, :business_address
|
||||
|
||||
def display_invoice_logo?
|
||||
|
||||
@@ -234,6 +234,7 @@ module Spree
|
||||
can [:admin, :index, :read, :create, :edit, :update, :destroy], Spree::Image
|
||||
|
||||
can [:admin, :index, :read, :search], Spree::Taxon
|
||||
can [:admin, :index, :read, :create, :edit], Spree::Classification
|
||||
|
||||
can [:admin, :index, :guide, :import, :save, :save_data,
|
||||
:validate_data, :reset_absent_products], ProductImport::ProductImporter
|
||||
|
||||
21
app/models/spree/classification.rb
Normal file
21
app/models/spree/classification.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class Classification < ApplicationRecord
|
||||
self.table_name = 'spree_products_taxons'
|
||||
belongs_to :product, class_name: "Spree::Product", touch: true
|
||||
belongs_to :taxon, class_name: "Spree::Taxon", touch: true
|
||||
|
||||
before_destroy :dont_destroy_if_primary_taxon
|
||||
|
||||
private
|
||||
|
||||
def dont_destroy_if_primary_taxon
|
||||
return unless product.primary_taxon == taxon
|
||||
|
||||
errors.add :base, I18n.t(:spree_classification_primary_taxon_error, taxon: taxon.name,
|
||||
product: product.name)
|
||||
throw :abort
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -50,8 +50,7 @@ module Spree
|
||||
|
||||
delegate :product, :variant_unit, :unit_description, :display_name, :display_as, to: :variant
|
||||
|
||||
# Allows manual skipping of Stock::AvailabilityValidator
|
||||
attr_accessor :skip_stock_check, :target_shipment
|
||||
attr_accessor :skip_stock_check, :target_shipment # Allows manual skipping of Stock::AvailabilityValidator
|
||||
|
||||
attribute :restock_item, type: :boolean, default: true
|
||||
|
||||
@@ -122,7 +121,7 @@ module Spree
|
||||
def copy_tax_category
|
||||
return unless variant
|
||||
|
||||
self.tax_category = variant.tax_category
|
||||
self.tax_category = variant.product.tax_category
|
||||
end
|
||||
|
||||
def copy_dimensions
|
||||
@@ -193,7 +192,7 @@ module Spree
|
||||
end
|
||||
|
||||
def tax_rates
|
||||
variant&.tax_category&.tax_rates || []
|
||||
product.tax_category&.tax_rates || []
|
||||
end
|
||||
|
||||
def price_with_adjustments
|
||||
|
||||
@@ -16,8 +16,7 @@ module Spree
|
||||
searchable_attributes :number, :state, :shipment_state, :payment_state, :distributor_id,
|
||||
:order_cycle_id, :email, :total, :customer_id
|
||||
searchable_associations :shipping_method, :bill_address, :distributor
|
||||
searchable_scopes :complete, :incomplete, :sort_by_billing_address_name_asc,
|
||||
:sort_by_billing_address_name_desc
|
||||
searchable_scopes :complete, :incomplete
|
||||
|
||||
checkout_flow do
|
||||
go_to_state :address
|
||||
@@ -105,9 +104,9 @@ module Spree
|
||||
before_validation :clone_billing_address, if: :use_billing?
|
||||
before_validation :ensure_customer
|
||||
|
||||
before_create :link_by_email
|
||||
before_save :update_shipping_fees!, if: :complete?
|
||||
before_save :update_payment_fees!, if: :complete?
|
||||
before_create :link_by_email
|
||||
|
||||
after_create :create_tax_charge!
|
||||
after_save :reapply_tax_on_changed_address
|
||||
@@ -146,14 +145,6 @@ module Spree
|
||||
end
|
||||
}
|
||||
|
||||
scope :sort_by_billing_address_name_asc, -> {
|
||||
joins(:bill_address).order("spree_addresses.lastname ASC, spree_addresses.firstname ASC")
|
||||
}
|
||||
|
||||
scope :sort_by_billing_address_name_desc, -> {
|
||||
joins(:bill_address).order("spree_addresses.lastname DESC, spree_addresses.firstname DESC")
|
||||
}
|
||||
|
||||
scope :with_line_items_variants_and_products_outer, lambda {
|
||||
left_outer_joins(line_items: { variant: :product })
|
||||
}
|
||||
@@ -208,10 +199,6 @@ module Spree
|
||||
completed_at.present?
|
||||
end
|
||||
|
||||
def invoiceable?
|
||||
complete? || resumed?
|
||||
end
|
||||
|
||||
# Indicates whether or not the user is allowed to proceed to checkout.
|
||||
# Currently this is implemented as a check for whether or not there is at
|
||||
# least one LineItem in the Order. Feel free to override this logic in your
|
||||
@@ -361,10 +348,6 @@ module Spree
|
||||
complete? || resumed? || awaiting_return? || returned?
|
||||
end
|
||||
|
||||
def can_show_invoice?
|
||||
complete? || resumed? || canceled?
|
||||
end
|
||||
|
||||
# Finalizes an in progress order after checkout is complete.
|
||||
# Called after transition to complete state when payments will have been processed
|
||||
def finalize!
|
||||
|
||||
@@ -81,12 +81,6 @@ module Spree
|
||||
order.create_tax_charge!
|
||||
order.update_totals_and_states
|
||||
end
|
||||
|
||||
after_transition to: :confirmation do |order|
|
||||
VoucherAdjustmentsService.new(order).update
|
||||
order.update_totals_and_states
|
||||
end
|
||||
|
||||
after_transition to: :complete, do: :finalize!
|
||||
after_transition to: :resumed, do: :after_resume
|
||||
after_transition to: :canceled, do: :after_cancel
|
||||
|
||||
@@ -25,15 +25,14 @@ module Spree
|
||||
has_one :adjustment, as: :adjustable, dependent: :destroy
|
||||
|
||||
validate :validate_source
|
||||
after_initialize :build_source
|
||||
before_create :set_unique_identifier
|
||||
|
||||
# invalidate previously entered payments
|
||||
after_create :invalidate_old_payments
|
||||
after_save :create_payment_profile, if: :profiles_supported?
|
||||
|
||||
# update the order totals, etc.
|
||||
after_save :ensure_correct_adjustment, :update_order
|
||||
# invalidate previously entered payments
|
||||
after_create :invalidate_old_payments
|
||||
|
||||
# Skips the validation of the source (for example, credit card) of the payment.
|
||||
#
|
||||
@@ -44,6 +43,8 @@ module Spree
|
||||
attr_accessor :skip_source_validation
|
||||
attr_accessor :source_attributes
|
||||
|
||||
after_initialize :build_source
|
||||
|
||||
scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
|
||||
scope :with_state, ->(s) { where(state: s.to_s) }
|
||||
scope :completed, -> { with_state('completed') }
|
||||
|
||||
@@ -31,6 +31,7 @@ module Spree
|
||||
searchable_associations :supplier, :properties, :primary_taxon, :variants
|
||||
searchable_scopes :active, :with_properties
|
||||
|
||||
belongs_to :tax_category, class_name: 'Spree::TaxCategory'
|
||||
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory'
|
||||
belongs_to :supplier, class_name: 'Enterprise', touch: true
|
||||
belongs_to :primary_taxon, class_name: 'Spree::Taxon', touch: true
|
||||
@@ -39,10 +40,14 @@ module Spree
|
||||
|
||||
has_many :product_properties, dependent: :destroy
|
||||
has_many :properties, through: :product_properties
|
||||
has_many :variants, -> { order("spree_variants.id ASC") }, class_name: 'Spree::Variant',
|
||||
dependent: :destroy
|
||||
has_many :classifications, dependent: :delete_all
|
||||
has_many :taxons, through: :classifications
|
||||
has_many :variants, -> { order("spree_variants.position ASC") }, class_name: 'Spree::Variant',
|
||||
dependent: :destroy
|
||||
|
||||
has_many :prices, -> { order('spree_variants.id, currency') }, through: :variants
|
||||
has_many :prices, -> {
|
||||
order('spree_variants.position, spree_variants.id, currency')
|
||||
}, through: :variants
|
||||
|
||||
has_many :stock_items, through: :variants
|
||||
has_many :supplier_properties, through: :supplier, source: :properties
|
||||
@@ -54,6 +59,8 @@ module Spree
|
||||
|
||||
validates :supplier, presence: true
|
||||
validates :primary_taxon, presence: true
|
||||
validates :tax_category, presence: true,
|
||||
if: proc { Spree::Config[:products_require_tax_category] }
|
||||
|
||||
validates :variant_unit, presence: true
|
||||
validates :unit_value, presence:
|
||||
@@ -72,8 +79,11 @@ module Spree
|
||||
|
||||
# Transient attributes used temporarily when creating a new product,
|
||||
# these values are persisted on the product's variant
|
||||
attr_accessor :price, :display_as, :unit_value, :unit_description, :tax_category_id
|
||||
attr_accessor :price, :display_as, :unit_value, :unit_description
|
||||
|
||||
before_save :add_primary_taxon_to_taxons
|
||||
|
||||
after_save :remove_previous_primary_taxon_from_taxons
|
||||
after_create :ensure_standard_variant
|
||||
after_save :update_units
|
||||
|
||||
@@ -195,6 +205,14 @@ module Spree
|
||||
group(column_names.map { |col_name| "#{table_name}.#{col_name}" })
|
||||
end
|
||||
|
||||
def tax_category
|
||||
if self[:tax_category_id].nil?
|
||||
TaxCategory.find_by(is_default: true)
|
||||
else
|
||||
TaxCategory.find(self[:tax_category_id])
|
||||
end
|
||||
end
|
||||
|
||||
# for adding products which are closely related to existing ones
|
||||
def duplicate
|
||||
duplicator = Spree::Core::ProductDuplicator.new(self)
|
||||
@@ -283,6 +301,16 @@ module Spree
|
||||
Enterprise.distributing_products(id).each(&:touch)
|
||||
end
|
||||
|
||||
def add_primary_taxon_to_taxons
|
||||
taxons << primary_taxon unless taxons.include? primary_taxon
|
||||
end
|
||||
|
||||
def remove_previous_primary_taxon_from_taxons
|
||||
return unless saved_change_to_primary_taxon_id? && primary_taxon_id_before_last_save
|
||||
|
||||
taxons.destroy(primary_taxon_id_before_last_save)
|
||||
end
|
||||
|
||||
def ensure_standard_variant
|
||||
return unless variants.empty?
|
||||
|
||||
@@ -292,7 +320,6 @@ module Spree
|
||||
variant.display_as = display_as
|
||||
variant.unit_value = unit_value
|
||||
variant.unit_description = unit_description
|
||||
variant.tax_category_id = tax_category_id
|
||||
variants << variant
|
||||
end
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ module Spree
|
||||
|
||||
has_many :inventory_units, inverse_of: :return_authorization
|
||||
has_one :stock_location
|
||||
before_save :force_positive_amount
|
||||
before_create :generate_number
|
||||
before_save :force_positive_amount
|
||||
|
||||
validates :order, presence: true
|
||||
validates :amount, numericality: true
|
||||
|
||||
@@ -5,8 +5,8 @@ module Spree
|
||||
acts_as_nested_set dependent: :destroy
|
||||
|
||||
belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true
|
||||
has_many :products, class_name: "Spree::Product", foreign_key: "primary_taxon_id",
|
||||
inverse_of: :primary_taxon, dependent: :restrict_with_error
|
||||
has_many :classifications, dependent: :destroy
|
||||
has_many :products, through: :classifications
|
||||
|
||||
before_create :set_permalink
|
||||
|
||||
@@ -39,6 +39,10 @@ module Spree
|
||||
permalink
|
||||
end
|
||||
|
||||
def active_products
|
||||
products.active
|
||||
end
|
||||
|
||||
def pretty_name
|
||||
ancestor_chain = ancestors.inject("") do |name, ancestor|
|
||||
name + "#{ancestor.name} -> "
|
||||
|
||||
@@ -23,7 +23,6 @@ module Spree
|
||||
has_many :spree_orders, class_name: "Spree::Order"
|
||||
|
||||
before_validation :set_login
|
||||
after_create :associate_customers, :associate_orders
|
||||
before_destroy :check_completed_orders
|
||||
|
||||
roles_table_name = Role.table_name
|
||||
@@ -47,6 +46,8 @@ module Spree
|
||||
accepts_nested_attributes_for :bill_address
|
||||
accepts_nested_attributes_for :ship_address
|
||||
|
||||
after_create :associate_customers, :associate_orders
|
||||
|
||||
validates :email, 'valid_email_2/email': { mx: true }, if: :email_changed?
|
||||
validate :limit_owned_enterprises
|
||||
validates :uid, uniqueness: true, if: lambda { uid.present? }
|
||||
|
||||
@@ -28,10 +28,9 @@ module Spree
|
||||
supplier_name).join('_or_')}_cont".freeze
|
||||
|
||||
belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product'
|
||||
belongs_to :tax_category, class_name: 'Spree::TaxCategory'
|
||||
|
||||
delegate_belongs_to :product, :name, :description, :shipping_category_id,
|
||||
:meta_keywords, :shipping_category
|
||||
delegate_belongs_to :product, :name, :description, :tax_category_id, :shipping_category_id,
|
||||
:meta_keywords, :tax_category, :shipping_category
|
||||
|
||||
has_many :inventory_units, inverse_of: :variant
|
||||
has_many :line_items, inverse_of: :variant
|
||||
@@ -62,9 +61,8 @@ module Spree
|
||||
localize_number :price, :weight
|
||||
|
||||
validate :check_currency
|
||||
validates :price, numericality: { greater_than_or_equal_to: 0 }, presence: true
|
||||
validates :tax_category, presence: true,
|
||||
if: proc { Spree::Config[:products_require_tax_category] }
|
||||
validates :price, numericality: { greater_than_or_equal_to: 0 },
|
||||
presence: true
|
||||
|
||||
validates :unit_value, presence: true, if: ->(variant) {
|
||||
%w(weight volume).include?(variant.product&.variant_unit)
|
||||
@@ -85,10 +83,13 @@ module Spree
|
||||
variant.new_record? || variant.changed_attributes.keys.intersection(NAME_FIELDS).any?
|
||||
}
|
||||
|
||||
after_create :create_stock_items
|
||||
around_destroy :destruction
|
||||
after_save :save_default_price
|
||||
|
||||
after_create :create_stock_items
|
||||
after_create :set_position
|
||||
|
||||
around_destroy :destruction
|
||||
|
||||
# default variant scope only lists non-deleted variants
|
||||
scope :deleted, lambda { where('deleted_at IS NOT NULL') }
|
||||
|
||||
@@ -165,14 +166,6 @@ module Spree
|
||||
select("spree_variants.id"))
|
||||
end
|
||||
|
||||
def tax_category
|
||||
if self[:tax_category_id].nil?
|
||||
TaxCategory.find_by(is_default: true)
|
||||
else
|
||||
TaxCategory.find(self[:tax_category_id])
|
||||
end
|
||||
end
|
||||
|
||||
def price_with_fees(distributor, order_cycle)
|
||||
price + fees_for(distributor, order_cycle)
|
||||
end
|
||||
@@ -230,6 +223,10 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def set_position
|
||||
update_column(:position, product.variants.maximum(:position).to_i + 1)
|
||||
end
|
||||
|
||||
def update_weight_from_unit_value
|
||||
return unless product.variant_unit == 'weight' && unit_value.present?
|
||||
|
||||
|
||||
@@ -21,11 +21,12 @@ class Voucher < ApplicationRecord
|
||||
# but vouchers have complicated calculation so we can't easily use Spree::Calculator. We keep
|
||||
# the same method to stay as consistent as possible.
|
||||
#
|
||||
# Creates a new voucher adjustment for the given order with an amount of 0
|
||||
# The amount will be calculated via VoucherAdjustmentsService#update
|
||||
# Creates a new voucher adjustment for the given order
|
||||
def create_adjustment(label, order)
|
||||
amount = compute_amount(order)
|
||||
|
||||
adjustment_attributes = {
|
||||
amount: 0,
|
||||
amount: amount,
|
||||
originator: self,
|
||||
order: order,
|
||||
label: label,
|
||||
|
||||
@@ -72,7 +72,7 @@ module Admin
|
||||
def send_invoices(params)
|
||||
count = 0
|
||||
editable_orders.where(id: params[:bulk_ids]).find_each do |o|
|
||||
next unless o.distributor.can_invoice? && o.invoiceable?
|
||||
next unless o.distributor.can_invoice? && (o.resumed? || o.complete?)
|
||||
|
||||
Spree::OrderMailer.invoice_email(o.id).deliver_later
|
||||
count += 1
|
||||
|
||||
@@ -4,8 +4,8 @@ module Api
|
||||
module Admin
|
||||
class ProductSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :sku, :variant_unit, :variant_unit_scale, :variant_unit_name,
|
||||
:inherits_properties, :on_hand, :price, :import_date, :image_url,
|
||||
:thumb_url, :variants
|
||||
:inherits_properties, :on_hand, :price, :tax_category_id, :import_date,
|
||||
:image_url, :thumb_url, :variants
|
||||
|
||||
has_one :supplier, key: :producer_id, embed: :id
|
||||
has_one :primary_taxon, key: :category_id, embed: :id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
module Api
|
||||
module Admin
|
||||
class VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :producer_name, :image, :sku, :import_date, :tax_category_id,
|
||||
attributes :id, :name, :producer_name, :image, :sku, :import_date,
|
||||
:options_text, :unit_value, :unit_description, :unit_to_display,
|
||||
:display_as, :display_name, :name_to_display, :variant_overrides_count,
|
||||
:price, :on_demand, :on_hand, :in_stock, :stock_location_id, :stock_location_name
|
||||
|
||||
@@ -10,6 +10,7 @@ class Api::ProductSerializer < ActiveModel::Serializer
|
||||
has_many :variants, serializer: Api::VariantSerializer
|
||||
|
||||
has_one :primary_taxon, serializer: Api::TaxonSerializer
|
||||
has_many :taxons, serializer: Api::IdSerializer
|
||||
|
||||
has_one :image, serializer: Api::ImageSerializer
|
||||
has_one :supplier, serializer: Api::IdSerializer
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
class Invoice
|
||||
class EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :abn, :acn, :invoice_text, :email_address, :display_invoice_logo, :logo_url,
|
||||
:phone
|
||||
attributes :name, :abn, :acn, :invoice_text, :email_address, :display_invoice_logo, :logo_url
|
||||
has_one :contact, serializer: Invoice::UserSerializer
|
||||
has_one :business_address, serializer: Invoice::AddressSerializer
|
||||
has_one :address, serializer: Invoice::AddressSerializer
|
||||
|
||||
@@ -38,7 +38,7 @@ class CreateOrderCycle
|
||||
coordinator_id: enterprise.id,
|
||||
name: 'Monthly order cycle',
|
||||
orders_open_at: Time.zone.now,
|
||||
orders_close_at: 1.month.from_now
|
||||
orders_close_at: Time.zone.now + 1.month
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ class OrderInvoiceComparator
|
||||
end
|
||||
|
||||
def latest_invoice
|
||||
@latest_invoice ||= invoices.first.presenter
|
||||
@latest_invoice ||= invoices.last.presenter
|
||||
end
|
||||
|
||||
def serialize_for_invoice
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderInvoiceGenerator
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def generate_or_update_latest_invoice
|
||||
if comparator.can_generate_new_invoice?
|
||||
order.invoices.create!(
|
||||
date: Time.zone.today,
|
||||
number: order.invoices.count + 1,
|
||||
data: invoice_data
|
||||
)
|
||||
elsif comparator.can_update_latest_invoice?
|
||||
order.invoices.last.update!(
|
||||
date: Time.zone.today,
|
||||
data: invoice_data
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order
|
||||
|
||||
def comparator
|
||||
@comparator ||= OrderInvoiceComparator.new(order)
|
||||
end
|
||||
|
||||
def invoice_data
|
||||
@invoice_data ||= InvoiceDataGenerator.new(order).generate
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,7 @@ module PermittedAttributes
|
||||
[
|
||||
:id, :sku, :on_hand, :on_demand,
|
||||
:price, :unit_value, :unit_description,
|
||||
:display_name, :display_as, :tax_category_id,
|
||||
:display_name, :display_as,
|
||||
:weight, :height, :width, :depth
|
||||
]
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ class TaxRateFinder
|
||||
|
||||
def line_item_tax_category(enterprise_fee, line_item)
|
||||
if enterprise_fee.inherits_tax_category?
|
||||
line_item.variant.tax_category
|
||||
line_item.product.tax_category
|
||||
else
|
||||
enterprise_fee.tax_category
|
||||
end
|
||||
|
||||
@@ -1,80 +1,68 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class VoucherAdjustmentsService
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def update
|
||||
return if @order.nil?
|
||||
def self.calculate(order)
|
||||
return if order.nil?
|
||||
|
||||
# Find open Voucher Adjustment
|
||||
return if @order.voucher_adjustments.empty?
|
||||
return if order.voucher_adjustments.empty?
|
||||
|
||||
# We only support one voucher per order right now, we could just loop on voucher_adjustments
|
||||
adjustment = @order.voucher_adjustments.first
|
||||
adjustment = order.voucher_adjustments.first
|
||||
|
||||
# Calculate value
|
||||
amount = adjustment.originator.compute_amount(@order)
|
||||
# Recalculate value
|
||||
amount = adjustment.originator.compute_amount(order)
|
||||
|
||||
# It is quite possible to have an order with both tax included in and tax excluded from price.
|
||||
# We should be able to caculate the relevant amount apply the current calculation.
|
||||
#
|
||||
# For now we just assume it is either all tax included in price or all tax excluded from price.
|
||||
if @order.additional_tax_total.positive?
|
||||
handle_tax_excluded_from_price(amount)
|
||||
elsif @order.included_tax_total.positive?
|
||||
handle_tax_included_in_price(amount)
|
||||
if order.additional_tax_total.positive?
|
||||
handle_tax_excluded_from_price(order, amount)
|
||||
elsif order.included_tax_total.positive?
|
||||
handle_tax_included_in_price(order, amount)
|
||||
else
|
||||
adjustment.amount = amount
|
||||
adjustment.save
|
||||
end
|
||||
|
||||
# Move to closed state
|
||||
adjustment.close
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_tax_excluded_from_price(amount)
|
||||
voucher_rate = amount / @order.pre_discount_total
|
||||
|
||||
adjustment = @order.voucher_adjustments.first
|
||||
def self.handle_tax_excluded_from_price(order, amount)
|
||||
voucher_rate = amount / order.total
|
||||
|
||||
# Adding the voucher tax part
|
||||
tax_amount = voucher_rate * @order.additional_tax_total
|
||||
tax_amount = voucher_rate * order.additional_tax_total
|
||||
|
||||
update_tax_adjustment_for(adjustment, tax_amount)
|
||||
adjustment = order.voucher_adjustments.first
|
||||
adjustment_attributes = {
|
||||
amount: tax_amount,
|
||||
originator: adjustment.originator,
|
||||
order: order,
|
||||
label: "Tax #{adjustment.label}",
|
||||
mandatory: false,
|
||||
state: 'closed',
|
||||
tax_category: nil,
|
||||
included_tax: 0
|
||||
}
|
||||
order.adjustments.create(adjustment_attributes)
|
||||
|
||||
# Update the adjustment amount
|
||||
adjustment_amount = voucher_rate * (@order.pre_discount_total - @order.additional_tax_total)
|
||||
amount = voucher_rate * (order.total - order.additional_tax_total)
|
||||
|
||||
adjustment.update_columns(
|
||||
amount: adjustment_amount,
|
||||
amount: amount,
|
||||
updated_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
def update_tax_adjustment_for(adjustment, tax_amount)
|
||||
adjustment_attributes = {
|
||||
originator: adjustment.originator,
|
||||
order: @order,
|
||||
label: "Tax #{adjustment.label}",
|
||||
mandatory: false,
|
||||
state: 'open',
|
||||
tax_category: nil,
|
||||
included_tax: 0
|
||||
}
|
||||
|
||||
# Update the amount if tax adjustment already exist, create if not
|
||||
tax_adjustment = @order.adjustments.find_or_initialize_by(adjustment_attributes)
|
||||
tax_adjustment.amount = tax_amount
|
||||
tax_adjustment.save
|
||||
end
|
||||
|
||||
def handle_tax_included_in_price(amount)
|
||||
voucher_rate = amount / @order.pre_discount_total
|
||||
included_tax = voucher_rate * @order.included_tax_total
|
||||
def self.handle_tax_included_in_price(order, amount)
|
||||
voucher_rate = amount / order.total
|
||||
included_tax = voucher_rate * order.included_tax_total
|
||||
|
||||
# Update Adjustment
|
||||
adjustment = @order.voucher_adjustments.first
|
||||
adjustment = order.voucher_adjustments.first
|
||||
|
||||
return unless amount != adjustment.amount || included_tax != 0
|
||||
|
||||
@@ -84,4 +72,6 @@ class VoucherAdjustmentsService
|
||||
updated_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
private_class_method :handle_tax_included_in_price, :handle_tax_excluded_from_price
|
||||
end
|
||||
|
||||
@@ -39,8 +39,9 @@
|
||||
%td.align-left
|
||||
.line-clamp-1= product.supplier.name
|
||||
%td.align-left
|
||||
.line-clamp-1= product.primary_taxon.name
|
||||
.line-clamp-1= product.taxons.map(&:name).join(', ')
|
||||
%td.align-left
|
||||
.line-clamp-1= product.tax_category&.name || "None" # TODO: convert to dropdown, else translate hardcoded string.
|
||||
%td.align-left
|
||||
.line-clamp-1= product.inherits_properties ? 'YES' : 'NO' #TODO: consider using https://github.com/RST-J/human_attribute_values, else use I18n.t (also below)
|
||||
- product.variants.each do |variant|
|
||||
@@ -60,7 +61,7 @@
|
||||
%td.align-left
|
||||
-# empty
|
||||
%td.align-left
|
||||
.line-clamp-1= variant.tax_category&.name || "None" # TODO: convert to dropdown, else translate hardcoded string.
|
||||
-# empty
|
||||
%td.align-left
|
||||
-# empty
|
||||
|
||||
|
||||
@@ -12,9 +12,3 @@
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
.row
|
||||
.alpha.two.columns= label_tag :add_variant_id, Spree.t(:name_or_sku)
|
||||
.omega.fourteen.columns
|
||||
- variant_json = @variant_serialized.present? ? @variant_serialized.to_json() : {}
|
||||
= select_tag(:variant_id_in, params[:variant_id_in], { class: "fullwidth", multiple: true , data: { controller: "select-variant", "select-variant-selected-value": "#{variant_json}" } })
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
%checkout.row#checkout
|
||||
.small-12.medium-12.columns
|
||||
.checkout-step
|
||||
%div.checkout-guest-title
|
||||
= t :checkout_headline
|
||||
.checkout-step
|
||||
.medium-10
|
||||
%div.checkout-guest-title
|
||||
= t :checkout_headline
|
||||
|
||||
%div.checkout-submit{ class: "#{@order.distributor.allow_guest_orders? ? 'checkout-submit-inline' : 'medium-6' }" }
|
||||
%button.button.primary{ "data-action": "click->guest-checkout#login" }
|
||||
= t :label_login
|
||||
-if @order.distributor.allow_guest_orders?
|
||||
%span.checkout-submit-or
|
||||
|
||||
%button.button.cancel{ "data-action": "click->guest-checkout#guestSelected" }
|
||||
= t :checkout_as_guest
|
||||
%div.checkout-submit{ class: "#{@order.distributor.allow_guest_orders? ? 'checkout-submit-inline' : 'medium-6' }" }
|
||||
%button.button.primary{ "data-action": "click->guest-checkout#login" }
|
||||
= t :label_login
|
||||
-if @order.distributor.allow_guest_orders?
|
||||
%span.checkout-submit-or
|
||||
|
||||
%button.button.cancel{ "data-action": "click->guest-checkout#guestSelected" }
|
||||
= t :checkout_as_guest
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- tr_id = spree_dom_id(invoice)
|
||||
%tr{:class => tr_class, "data-hook" => "invoice_row", :id => tr_id}
|
||||
%td.align-center.created_at
|
||||
= invoice.presenter.display_date
|
||||
= pretty_time(invoice.date)
|
||||
%td.align-center.label
|
||||
= invoice.number
|
||||
%td.align-center.label
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
- content_for :page_actions do
|
||||
- if show_generate_invoice_button?(@order)
|
||||
%li= button_link_to t(:create_or_update_invoice), generate_admin_order_invoices_path(@order), :icon => 'icon-plus', data: { method: 'post' }
|
||||
%li= button_link_to t(:new_invoice), generate_admin_order_invoices_path(@order), :icon => 'icon-plus', data: { method: 'post' }
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
%th
|
||||
= t(:products_distributor)
|
||||
|
||||
- columns = ['completed_at', 'number', 'state', 'payment_state', 'shipment_state', 'email', 'billing_address_name', 'total']
|
||||
- columns = ['completed_at', 'number', 'state', 'payment_state', 'shipment_state', 'email', 'bill_address_lastname', 'total']
|
||||
|
||||
= render partial: "spree/admin/shared/stimulus_sortable_header", collection: columns, as: :column,
|
||||
locals: { sorted: params.dig(:q, :s), default: "completed_at desc" }
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
%a{ href: "mailto:#{order.email}", target: "_blank" }
|
||||
= order.email
|
||||
%td
|
||||
= order.bill_address.full_name_for_sorting
|
||||
= order.bill_address.full_name
|
||||
%td.align-center
|
||||
%span
|
||||
= order.display_total
|
||||
|
||||
@@ -7,20 +7,11 @@
|
||||
%h6
|
||||
= "#{t('spree.admin.orders.invoice.issued_on')}: "
|
||||
= l @order.invoice_date
|
||||
%tr{ valign: "top" }
|
||||
%td{ :align => "left", colspan: 3 }
|
||||
%h6
|
||||
= "#{t('spree.admin.orders.invoice.order_number')}: "
|
||||
= @order.number
|
||||
%tr{ valign: "top" }
|
||||
%td{ :align => "left", colspan: 3 }
|
||||
%h6
|
||||
= "#{t('spree.admin.orders.invoice.invoice_number')}: "
|
||||
= @order.invoice_number
|
||||
%tr{ valign: "top" }
|
||||
%td{ :align => "left" }
|
||||
%h4
|
||||
= "#{t('spree.admin.orders.invoice.tax_invoice')}"
|
||||
= "#{t('spree.admin.orders.invoice.tax_invoice')}: "
|
||||
= "#{@order.number}"
|
||||
%td{width: "10%" }
|
||||
|
||||
%td{ :align => "right" }
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
%td{ :align => "left", colspan: 2 }
|
||||
%tr{ valign: "top" }
|
||||
%td{ :align => "left" }
|
||||
%br
|
||||
= "#{t :invoice_number}:"
|
||||
= @order.invoice_number
|
||||
%br
|
||||
= t :invoice_issued_on
|
||||
= l @order.invoice_date
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
= f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, {}, { :class => 'select2' })
|
||||
= f.error_message_on :shipping_category
|
||||
|
||||
= f.field_container :tax_category do
|
||||
= f.label :tax_category_id, t(:tax_category)
|
||||
= f.collection_select(:tax_category_id, @tax_categories, :id, :name, { :include_blank => t(:none) }, { :class => 'select2' })
|
||||
= f.error_message_on :tax_category
|
||||
|
||||
.clear
|
||||
|
||||
%div
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
%td.category{ 'ng-if' => 'columns.category.visible' }
|
||||
%input.fullwidth{ :type => 'text', id: "p{{product.id}}_category_id", 'ng-model' => 'product.category_id', 'ofn-taxon-autocomplete' => '', 'ofn-track-product' => 'category_id', 'multiple-selection' => 'false', placeholder: 'Category' }
|
||||
%td.tax_category{ 'ng-if' => 'columns.tax_category.visible' }
|
||||
%select.select2{ name: 'product_tax_category_id', 'ofn-track-product' => 'tax_category_id', ng: {model: 'product.tax_category_id', options: 'tax_category.id as tax_category.name for tax_category in tax_categories'} }
|
||||
%option{value: ''}= t(:none)
|
||||
%td.inherits_properties{ 'ng-show' => 'columns.inherits_properties.visible' }
|
||||
%input{ 'ng-model' => 'product.inherits_properties', :name => 'inherits_properties', 'ofn-track-product' => 'inherits_properties', type: "checkbox" }
|
||||
%td.import_date{ 'ng-show' => 'columns.import_date.visible' }
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
%input.field{ 'ng-model' => 'variant.on_demand', :name => 'variant_on_demand', 'ofn-track-variant' => 'on_demand', :type => 'checkbox' }
|
||||
%td{ 'ng-show' => 'columns.category.visible' }
|
||||
%td{ 'ng-show' => 'columns.tax_category.visible' }
|
||||
%select.select2{ name: 'variant_tax_category_id', 'ofn-track-variant': 'tax_category_id', ng: { model: 'variant.tax_category_id', options: 'tax_category.id as tax_category.name for tax_category in tax_categories' } }
|
||||
%option{ value: '' }= t(:none)
|
||||
%td{ 'ng-show' => 'columns.inherits_properties.visible' }
|
||||
%td{ 'ng-show' => 'columns.import_date.visible' }
|
||||
%span {{variant.import_date | date:"MMMM dd, yyyy HH:mm"}}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
%li{ class: adjustments_classes }
|
||||
= link_to_with_icon 'icon-cogs', t(:adjustments), spree.admin_order_adjustments_url(@order)
|
||||
|
||||
- if feature?(:invoices) && @order.can_show_invoice?
|
||||
- if feature?(:invoices)
|
||||
- invoices_classes = "active" if current == 'Invoices'
|
||||
%li{ class: invoices_classes }
|
||||
= link_to_with_icon 'icon-cogs', t(:invoices), spree.admin_order_invoices_url(@order)
|
||||
|
||||
@@ -64,8 +64,4 @@
|
||||
- value = number_with_precision(@variant.send(field), precision: 2)
|
||||
= f.number_field field, value: value, class: 'fullwidth', step: 0.01
|
||||
|
||||
.field
|
||||
= f.label :tax_category_id, t(:tax_category)
|
||||
= f.collection_select(:tax_category_id, @tax_categories, :id, :name, { include_blank: t(:none) }, { class: 'select2 fullwidth' })
|
||||
|
||||
.clear
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
import TomSelectController from "./tom_select_controller";
|
||||
|
||||
// This is simalar to the "variantAutocomplete" directive that uses "select2", but it doesn't
|
||||
// have all the same feature
|
||||
//
|
||||
export default class extends TomSelectController {
|
||||
static values = { options: Object, distributor: Number, selected: Object };
|
||||
|
||||
connect() {
|
||||
const options = {
|
||||
valueField: "id",
|
||||
searchField: ["name", "sku"],
|
||||
load: this.#load.bind(this),
|
||||
shouldLoad: (query) => query.length > 2,
|
||||
render: {
|
||||
option: this.#renderOption.bind(this),
|
||||
item: this.#renderItem.bind(this),
|
||||
},
|
||||
};
|
||||
super.connect(options);
|
||||
// Add the selected value if any and select it.
|
||||
// It will need to include data used in the templates below:
|
||||
// - id
|
||||
// - image
|
||||
// - name
|
||||
// - producer_name
|
||||
// - sku
|
||||
// - on_demand
|
||||
// - on_hand
|
||||
// - options_text
|
||||
//
|
||||
if (this.hasSelectedValue && Object.keys(this.selectedValue).length > 0) {
|
||||
this.control.addOption(this.selectedValue);
|
||||
this.control.addItem(this.selectedValue.id);
|
||||
}
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
#load(query, callback) {
|
||||
const url = "/admin/variants/search.json?q=" + encodeURIComponent(query);
|
||||
fetch(url)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
callback(json);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
#renderOption(variant, escape) {
|
||||
return `<div class='variant-autocomplete-item'>
|
||||
<figure class='variant-image'>
|
||||
${variant.image ? `<img src='${variant.image}' />` : "<img src='/noimage/mini.png' />"}
|
||||
</figure>
|
||||
<div class='variant-details'>
|
||||
<h6 class="variant-name">${escape(variant.name)}</h6>
|
||||
<ul>
|
||||
<li>
|
||||
<strong> ${I18n.t("spree.admin.variants.autocomplete.producer_name")}: </strong>
|
||||
${escape(variant.producer_name)}
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='variant-data'>
|
||||
<li class='variant-sku'>
|
||||
<strong>${I18n.t("admin.sku")}: </strong>
|
||||
${escape(variant.sku)}
|
||||
</li>
|
||||
${
|
||||
variant.on_demand
|
||||
? `<li class='variant-on_demand'><strong>${I18n.t("on_demand")}</strong></li>`
|
||||
: `<li class='variant-on_hand'>
|
||||
<strong>${I18n.t("on_hand")}:</strong> ${escape(variant.on_hand)}
|
||||
</li>`
|
||||
}
|
||||
<li class='variant-options_text'>
|
||||
<strong> ${I18n.t("spree.admin.variants.autocomplete.unit")}: </strong>
|
||||
${escape(variant.options_text)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
#renderItem(variant, escape) {
|
||||
return `<span>${escape(variant.name)}</span>`;
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,8 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
simulateClick(tab, panel) {
|
||||
this.updateActivePanel(panel);
|
||||
this.updateActiveTab(tab);
|
||||
this.updateActivePanel(panel);
|
||||
}
|
||||
|
||||
changeActivePanel(event) {
|
||||
@@ -49,7 +49,9 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
updateActivePanel(panel_id) {
|
||||
const newActivePanel = this.panelTargets.find((panel) => panel.id == panel_id);
|
||||
const newActivePanel = this.panelTargets.find(
|
||||
(panel) => panel.id == panel_id
|
||||
);
|
||||
|
||||
if (newActivePanel === undefined) {
|
||||
// No panel found
|
||||
@@ -82,6 +84,8 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
get currentActivePanel() {
|
||||
return this.panelTargets.find((panel) => panel.id == `${this.currentActiveTab.id}_panel`);
|
||||
return this.panelTargets.find(
|
||||
(panel) => panel.id == `${this.currentActiveTab.id}_panel`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $color-warning;
|
||||
color: $color-warning;
|
||||
border-color: $warning-red;
|
||||
color: $warning-red;
|
||||
|
||||
h6 {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
@import "globals/functions";
|
||||
@import "globals/palette";
|
||||
@import "globals/variables";
|
||||
@import "variables";
|
||||
@import "globals/mixins";
|
||||
|
||||
@import "plugins/font-awesome";
|
||||
@@ -110,6 +111,7 @@
|
||||
@import "tag_rules";
|
||||
@import "terms_of_service_files";
|
||||
@import "validation";
|
||||
@import "variables";
|
||||
@import "variant_overrides";
|
||||
@import "welcome";
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
@import "../darkswarm/branding";
|
||||
@import "../darkswarm/mixins";
|
||||
|
||||
#change_type {
|
||||
section {
|
||||
margin: 2em 0 0 0;
|
||||
|
||||
@@ -69,7 +69,7 @@ button:not(.plain):not(.trix-button),
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
}
|
||||
&.success {
|
||||
background-color: $spree-green;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
&.error {
|
||||
.message {
|
||||
.icon {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@import "../../darkswarm/branding";
|
||||
|
||||
.container {
|
||||
input {
|
||||
&[readonly] {
|
||||
background-color: $light-grey;
|
||||
background-color: $disabled-light;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ light: #ccc
|
||||
|
||||
&:hover {
|
||||
&:before {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
.errorExplanation {
|
||||
padding: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid very-light($color-error, 12);
|
||||
background-color: very-light($color-error, 6);
|
||||
border-radius: 3px;
|
||||
color: $color-error;
|
||||
color: very-light($color-error, 30);
|
||||
margin-bottom: 15px;
|
||||
|
||||
h2 {
|
||||
font-size: 140%;
|
||||
color: $color-error;
|
||||
color: very-light($color-error, 30);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: $color-btn-disabled-bg;
|
||||
background-color: $disabled_button;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
color: $spree-blue;
|
||||
|
||||
&.error {
|
||||
color: $color-error;
|
||||
color: $red-500;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
width: 300px;
|
||||
|
||||
.close-reveal-modal {
|
||||
color: $color-modal-close-btn;
|
||||
color: $modal-close-button-color;
|
||||
font-size: 23px;
|
||||
right: 0.45rem;
|
||||
top: 0.35rem;
|
||||
|
||||
:hover {
|
||||
color: $color-modal-close-btn-hover;
|
||||
color: $modal-close-button-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
.ts-wrapper.single .ts-control,
|
||||
.ts-dropdown.single {
|
||||
border-color: $color-tbl-border;
|
||||
border-color: $admin-table-border;
|
||||
}
|
||||
|
||||
.ts-control,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@import "../darkswarm/mixins";
|
||||
|
||||
.dashboard_item.single-ent {
|
||||
.header {
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
@@ -19,11 +19,11 @@ div.dashboard_item {
|
||||
}
|
||||
|
||||
&.red {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
}
|
||||
|
||||
&.orange {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-orange;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,20 +40,20 @@ div.dashboard_item {
|
||||
}
|
||||
|
||||
&.red {
|
||||
border-color: $color-warning;
|
||||
border-color: $warning-red;
|
||||
border-width: 3px;
|
||||
|
||||
h3 {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
&.orange {
|
||||
border-color: $color-warning;
|
||||
border-color: $warning-orange;
|
||||
border-width: 3px;
|
||||
|
||||
h3 {
|
||||
color: $color-warning;
|
||||
color: $warning-orange;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +141,12 @@ div.dashboard_item {
|
||||
}
|
||||
|
||||
.icon-warning-sign {
|
||||
color: $color-warning;
|
||||
color: $warning-orange;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.icon-remove-sign {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
@@ -156,13 +156,13 @@ div.dashboard_item {
|
||||
}
|
||||
|
||||
&.orange {
|
||||
color: $color-warning;
|
||||
border: solid $color-warning;
|
||||
color: $warning-orange;
|
||||
border: solid $warning-orange;
|
||||
}
|
||||
|
||||
&.red {
|
||||
color: $color-warning;
|
||||
border: solid $color-warning;
|
||||
color: $warning-red;
|
||||
border: solid $warning-red;
|
||||
}
|
||||
|
||||
&.orange,
|
||||
@@ -217,7 +217,7 @@ div.dashboard_item {
|
||||
text-align: center;
|
||||
|
||||
&.orange {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-orange;
|
||||
}
|
||||
|
||||
&.blue {
|
||||
@@ -225,7 +225,7 @@ div.dashboard_item {
|
||||
}
|
||||
|
||||
&.red {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
font-size: 1.5rem;
|
||||
|
||||
&.issue {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
form[name="enterprise_form"] {
|
||||
div.row.warning {
|
||||
color: $color-warning;
|
||||
color: $warning-orange;
|
||||
}
|
||||
|
||||
table.managers {
|
||||
@@ -29,7 +29,7 @@ form[name="enterprise_form"] {
|
||||
}
|
||||
|
||||
.admin-enterprises-index-admin-actions-divider {
|
||||
background-color: $color-tbl-border;
|
||||
background-color: $admin-table-border;
|
||||
border-width: 0;
|
||||
height: 1px;
|
||||
margin-bottom: 1em;
|
||||
@@ -38,7 +38,7 @@ form[name="enterprise_form"] {
|
||||
|
||||
table .enterprise-actions {
|
||||
.warning-icon {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
// Make color very close to white
|
||||
@function very-light($color, $adjust: 3) {
|
||||
@if type-of($adjust) == "number" and $adjust > 0 {
|
||||
@function very-light($color, $adjust: 3){
|
||||
@if type-of($adjust) == 'number' and $adjust > 0 {
|
||||
@for $i from 0 through 100 {
|
||||
@if lighten($color, $i) == white and ($i - $adjust) > $adjust {
|
||||
@return lighten($color, $i - $adjust);
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
@debug "Please correct $adjust value. It should be number and larger then 0. Currently it is '#{type-of($adjust)}' with value '#{$adjust}'";
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@debug "Please correct $adjust value. It should be number and larger then 0. Currently it is '#{type-of($adjust)}' with value '#{$adjust}'"
|
||||
}
|
||||
};
|
||||
|
||||
// Quick fix for dynamic variables missing in SASS
|
||||
@function get-value($prop, $val, $search) {
|
||||
$n1: index($prop, $search);
|
||||
$n2: index($val, $search);
|
||||
|
||||
@if ($n1) {
|
||||
@if($n1) {
|
||||
@return nth($val, $n1);
|
||||
} @else {
|
||||
@return nth($prop, $n2);
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
// Basic color palette for admin
|
||||
$spree-green: #9fc820;
|
||||
$spree-blue: #5498da;
|
||||
$spree-light-blue: #eff5fc;
|
||||
$pale-blue: #cee1f4;
|
||||
$bright-orange: #ffa92e;
|
||||
$medium-grey: #919191;
|
||||
$light-grey: #ccc;
|
||||
|
||||
$color-1: #ffffff !default; // White
|
||||
$color-2: $spree-green !default; // Green
|
||||
$color-3: $spree-blue !default; // Light Blue
|
||||
$color-4: #6788a2 !default; // Dark Blue
|
||||
$color-5: #c60f13 !default; // Red
|
||||
$color-6: #ff9300 !default; // Yellow
|
||||
|
||||
$dark-grey: #333;
|
||||
$light-grey: #ddd;
|
||||
$near-black: #222;
|
||||
$color-1: #FFFFFF !default; // White
|
||||
$color-2: #9FC820 !default; // Green
|
||||
$color-3: #5498DA !default; // Light Blue
|
||||
$color-4: #6788A2 !default; // Dark Blue
|
||||
$color-5: #C60F13 !default; // Red
|
||||
$color-6: #FF9300 !default; // Yellow
|
||||
|
||||
@@ -23,21 +23,18 @@ $color-border: very-light($color-3, 12) !default;
|
||||
// Basic flash colors
|
||||
$color-success: $color-2 !default;
|
||||
$color-notice: $color-6 !default;
|
||||
$color-warning: $color-5 !default;
|
||||
$color-error: $color-5 !default;
|
||||
|
||||
// Table colors
|
||||
$color-tbl-odd: $color-1 !default;
|
||||
$color-tbl-even: very-light($color-3, 4) !default;
|
||||
$color-tbl-thead: very-light($color-3, 4) !default;
|
||||
$color-tbl-border: $pale-blue !default;
|
||||
|
||||
// Button colors
|
||||
$color-btn-bg: $color-3 !default;
|
||||
$color-btn-text: $color-1 !default;
|
||||
$color-btn-hover-bg: $color-2 !default;
|
||||
$color-btn-hover-text: $color-1 !default;
|
||||
$color-btn-disabled-bg: $light-grey !default;
|
||||
|
||||
// Actions colors
|
||||
$color-action-edit-bg: very-light($color-success, 5 ) !default;
|
||||
@@ -68,10 +65,6 @@ $color-txt-brd: $color-border !default;
|
||||
$color-txt-text: $color-3 !default;
|
||||
$color-txt-hover-brd: $color-2 !default;
|
||||
|
||||
// Modal colors
|
||||
$color-modal-close-btn: $color-5 !default;
|
||||
$color-modal-close-btn-hover: darken($color-5, 5%) !default;
|
||||
|
||||
// States label colors
|
||||
$color-ste-complete-bg: $color-success !default;
|
||||
$color-ste-complete-text: $color-1 !default;
|
||||
|
||||
@@ -6,7 +6,7 @@ tbody.panel-ctrl {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.3rem;
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
&:hover {
|
||||
background-color: #cd4e4f;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ tbody.panel-ctrl {
|
||||
font-size: 2rem;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
content: "\f071";
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
|
||||
&.status {
|
||||
@@ -38,7 +38,7 @@ tbody.panel-ctrl {
|
||||
|
||||
i.issue::before {
|
||||
content: "\f071";
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
|
||||
i.warning::before {
|
||||
|
||||
@@ -34,7 +34,7 @@ text-angular .ta-editor {
|
||||
|
||||
span.error,
|
||||
div.error:not(.flash) {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
|
||||
/* Fix conflict between Spree and elRTE's styles */
|
||||
@@ -46,7 +46,7 @@ div.error:not(.flash) {
|
||||
input.red,
|
||||
a.button.red,
|
||||
button.red {
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
margin-right: 5px;
|
||||
color: #ffffff;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ button.red {
|
||||
a.button.red {
|
||||
&:not(:hover) {
|
||||
color: #fff;
|
||||
background-color: $color-warning;
|
||||
background-color: $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,12 +208,12 @@ table#listing_enterprise_groups {
|
||||
// TODO: remove this, use class below
|
||||
#no_results {
|
||||
font-weight: bold;
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
font-weight: bold;
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
@@ -221,12 +221,12 @@ table#listing_enterprise_groups {
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
.field_with_errors > input {
|
||||
border-color: $color-error;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
// textAngular wysiwyg
|
||||
@@ -269,7 +269,7 @@ text-angular {
|
||||
}
|
||||
|
||||
span.required {
|
||||
color: $color-5;
|
||||
color: red;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ input.show-dirty {
|
||||
&.ng-dirty {
|
||||
border: solid 1px orange;
|
||||
&.update-error {
|
||||
border: solid 1px $color-warning;
|
||||
border: solid 1px $warning-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ input.show-dirty {
|
||||
input,
|
||||
div {
|
||||
&.update-error {
|
||||
border: solid 1px $color-warning;
|
||||
border: solid 1px $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ table.edit-note-table {
|
||||
float: right;
|
||||
|
||||
&:disabled {
|
||||
background-color: $color-btn-disabled-bg;
|
||||
background-color: $disabled-button;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ table.edit-note-table {
|
||||
}
|
||||
|
||||
.error {
|
||||
color: $color-warning;
|
||||
color: $warning-red;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user