workarea-ship_station 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +17 -0
- data/LICENSE +52 -0
- data/README.md +89 -0
- data/Rakefile +57 -0
- data/app/assets/images/workarea/admin/ship_station/.keep +0 -0
- data/app/assets/images/workarea/storefront/ship_station/.keep +0 -0
- data/app/assets/javascripts/workarea/admin/ship_station/.keep +0 -0
- data/app/assets/javascripts/workarea/storefront/ship_station/.keep +0 -0
- data/app/assets/stylesheets/workarea/admin/ship_station/.keep +0 -0
- data/app/assets/stylesheets/workarea/storefront/ship_station/.keep +0 -0
- data/app/controllers/workarea/admin/orders_controller.decorator +50 -0
- data/app/controllers/workarea/storefront/ship_station_webhook_controller.rb +52 -0
- data/app/helpers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/models/workarea/order.decorator +25 -0
- data/app/services/workarea/ship_station/order.rb +161 -0
- data/app/services/workarea/ship_station/webhook.rb +27 -0
- data/app/services/workarea/ship_station/webhook/item_ship_notify.rb +33 -0
- data/app/views/.keep +0 -0
- data/app/views/workarea/admin/orders/_ship_station.html.haml +12 -0
- data/app/views/workarea/admin/orders/_ship_station_bar_actions.html.haml +7 -0
- data/app/views/workarea/admin/orders/hold_date.html.haml +27 -0
- data/app/workers/workarea/ship_station/save_order.rb +24 -0
- data/bin/rails +25 -0
- data/config/initializers/appends.rb +9 -0
- data/config/initializers/workarea.rb +11 -0
- data/config/locales/en.yml +20 -0
- data/config/routes.rb +13 -0
- data/lib/workarea/ship_station.rb +39 -0
- data/lib/workarea/ship_station/bogus_gateway.rb +297 -0
- data/lib/workarea/ship_station/engine.rb +10 -0
- data/lib/workarea/ship_station/gateway.rb +92 -0
- data/lib/workarea/ship_station/response.rb +17 -0
- data/lib/workarea/ship_station/version.rb +5 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +15 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +25 -0
- data/test/dummy/bin/update +25 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +34 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +52 -0
- data/test/dummy/config/environments/production.rb +83 -0
- data/test/dummy/config/environments/test.rb +45 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +12 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +34 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/integration/workarea/admin/ship_station_integration_test.rb +36 -0
- data/test/integration/workarea/storefront/ship_station_webhook_test.rb +37 -0
- data/test/integration/workarea/storefront/ship_station_webhooks/notify_shipment_test.rb +56 -0
- data/test/services/workarea/ship_station/order_test.rb +67 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/test/workers/workarea/ship_station/save_order_test.rb +16 -0
- data/workarea-ship_station.gemspec +20 -0
- metadata +157 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
class ShipStationWebhookController < Storefront::ApplicationController
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
|
6
|
+
def event
|
7
|
+
body = JSON.parse(request.body.read)
|
8
|
+
|
9
|
+
# return a bad response if the resource url in the
|
10
|
+
# body is not shipstation.
|
11
|
+
uri = URI(body["resource_url"])
|
12
|
+
return unsuccessful_response unless !!uri.host.match(/.shipstation.com/)
|
13
|
+
|
14
|
+
begin
|
15
|
+
ShipStation::Webhook.process(body)
|
16
|
+
successful_response
|
17
|
+
|
18
|
+
rescue Mongoid::Errors::DocumentNotFound => error
|
19
|
+
not_found_response(params: error.params, problem: error.problem)
|
20
|
+
rescue ShipStation::Webhook::Error::NotFound, ShipStation::Webhook::Error::UnhandledWebhook => error
|
21
|
+
not_found_response(error: "UnhandledWebhook: #{error}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def verify_signature
|
28
|
+
request_valid = ShipStation::WebhookRequestSignature.valid?(
|
29
|
+
request_signature: request.headers['X-Flow-Signature'],
|
30
|
+
request_body: request.raw_post
|
31
|
+
)
|
32
|
+
unsuccessful_response unless request_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
def successful_response
|
36
|
+
render json: { status: 200 }
|
37
|
+
end
|
38
|
+
|
39
|
+
def unsuccessful_response
|
40
|
+
head :bad_request
|
41
|
+
end
|
42
|
+
|
43
|
+
def error_response(payload)
|
44
|
+
render json: payload, status: :unprocessable_entity
|
45
|
+
end
|
46
|
+
|
47
|
+
def not_found_response(payload)
|
48
|
+
render json: payload, status: :not_found
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/app/helpers/.keep
ADDED
File without changes
|
data/app/mailers/.keep
ADDED
File without changes
|
data/app/models/.keep
ADDED
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Order, with: :ship_station do
|
3
|
+
decorated do
|
4
|
+
field :ship_station_order_id, type: String
|
5
|
+
field :ship_station_exported_at, type: Time
|
6
|
+
field :ship_station_on_hold_until, type: Time
|
7
|
+
|
8
|
+
index({ ship_station_order_id: 1}, { background: true })
|
9
|
+
end
|
10
|
+
|
11
|
+
def ship_station_exported?
|
12
|
+
!!ship_station_exported_at
|
13
|
+
end
|
14
|
+
|
15
|
+
def ship_station_on_hold?
|
16
|
+
!!ship_station_on_hold_until
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_ship_station_exported_at!
|
20
|
+
update!(
|
21
|
+
ship_station_exported_at: Time.current
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module Workarea
|
2
|
+
module ShipStation
|
3
|
+
class Order
|
4
|
+
module ProductImageUrl
|
5
|
+
include Workarea::ApplicationHelper
|
6
|
+
include Workarea::I18n::DefaultUrlOptions
|
7
|
+
include ActionView::Helpers::AssetUrlHelper
|
8
|
+
include Core::Engine.routes.url_helpers
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def mounted_core
|
12
|
+
self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :order
|
17
|
+
|
18
|
+
def initialize(order_id)
|
19
|
+
wa_order = Workarea::Order.find(order_id)
|
20
|
+
@order = Workarea::Storefront::OrderViewModel.new(wa_order)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_h
|
24
|
+
{
|
25
|
+
orderNumber: order.id,
|
26
|
+
orderKey: order.id,
|
27
|
+
orderDate: order.placed_at,
|
28
|
+
paymentDate: order.placed_at,
|
29
|
+
orderStatus: 'awaiting_shipment',
|
30
|
+
customerUsername: order.email,
|
31
|
+
customerEmail: order.email,
|
32
|
+
billTo: address(order.billing_address),
|
33
|
+
shipTo: address(order.shipping_address),
|
34
|
+
items: items,
|
35
|
+
amountPaid: order.total_price.to_s,
|
36
|
+
taxAmount: order.tax_total.to_s,
|
37
|
+
shippingAmount: order.shipping_total.to_s,
|
38
|
+
paymentMethod: payment_methods,
|
39
|
+
requestedShippingService: shipping_service_name,
|
40
|
+
serviceCode: shipping_service_code,
|
41
|
+
shipByDate: ship_by_date
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def ship_by_date
|
48
|
+
return unless Workarea::ShipStation.config.ship_by_date_lead_days.present?
|
49
|
+
|
50
|
+
Time.current + Workarea::ShipStation.config.ship_by_date_lead_days.days
|
51
|
+
end
|
52
|
+
|
53
|
+
def shipping
|
54
|
+
@shipping = Workarea::Shipping.find_by_order(order.id)
|
55
|
+
end
|
56
|
+
|
57
|
+
def shipping_service_code
|
58
|
+
return unless shipping.present?
|
59
|
+
shipping.shipping_service.service_code
|
60
|
+
end
|
61
|
+
|
62
|
+
def shipping_service_name
|
63
|
+
return unless shipping.present?
|
64
|
+
shipping.shipping_service.name
|
65
|
+
end
|
66
|
+
|
67
|
+
def payment
|
68
|
+
@payment = Workarea::Payment.find(order.id)
|
69
|
+
end
|
70
|
+
|
71
|
+
def address(obj)
|
72
|
+
return unless obj.present?
|
73
|
+
{
|
74
|
+
name: obj.first_name + ' ' + obj.last_name,
|
75
|
+
company: obj.company,
|
76
|
+
street1: obj.street,
|
77
|
+
street2: obj.street_2,
|
78
|
+
city: obj.city,
|
79
|
+
state: obj.region,
|
80
|
+
postalCode: obj.postal_code,
|
81
|
+
country: obj.country.alpha2,
|
82
|
+
phone: obj.phone_number
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def items
|
87
|
+
order_items = order.items.map do |order_item|
|
88
|
+
|
89
|
+
hash = {
|
90
|
+
lineItemKey: order_item.id,
|
91
|
+
sku: order_item.sku,
|
92
|
+
name: order_item.product_name,
|
93
|
+
imageUrl: ProductImageUrl.product_image_url(order_item.image, :detail),
|
94
|
+
quantity: order_item.quantity,
|
95
|
+
unitPrice: order_item.original_unit_price.to_f,
|
96
|
+
taxAmount: item_tax(order_item).to_f,
|
97
|
+
options: item_options(order_item),
|
98
|
+
adjustment: false
|
99
|
+
}
|
100
|
+
|
101
|
+
item_shipping_sku = shipping_sku(order_item.sku)
|
102
|
+
if item_shipping_sku.present?
|
103
|
+
weight_data = {
|
104
|
+
weight: {
|
105
|
+
value: item_shipping_sku.weight,
|
106
|
+
units: item_shipping_sku.weight_units.to_s
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
hash.merge!(weight_data)
|
111
|
+
end
|
112
|
+
|
113
|
+
hash
|
114
|
+
end
|
115
|
+
|
116
|
+
order_items + discount_items
|
117
|
+
end
|
118
|
+
|
119
|
+
def shipping_sku(sku)
|
120
|
+
return unless shipping.present?
|
121
|
+
Workarea::Shipping::Sku.find(sku) rescue nil
|
122
|
+
end
|
123
|
+
|
124
|
+
def item_tax(order_item)
|
125
|
+
return unless shipping.present?
|
126
|
+
item = shipping.price_adjustments.adjusting('tax').detect { |pa| pa["data"]["order_item_id"].to_s == order_item.id.to_s }
|
127
|
+
return 0 unless item.present?
|
128
|
+
item.amount.to_f
|
129
|
+
end
|
130
|
+
|
131
|
+
def item_options(order_item)
|
132
|
+
order_item.details.map { |k, v| { name: k, value: v } }
|
133
|
+
end
|
134
|
+
|
135
|
+
def payment_methods
|
136
|
+
payment.tenders.map(&:slug).join(',')
|
137
|
+
end
|
138
|
+
|
139
|
+
def discount_items
|
140
|
+
discounts = order.price_adjustments.select { |p| p.discount? }
|
141
|
+
return [] unless discounts.present?
|
142
|
+
|
143
|
+
discounts.map do |d|
|
144
|
+
{
|
145
|
+
lineItemKey: nil,
|
146
|
+
sku: "DISCOUNT CODE",
|
147
|
+
name: d.description,
|
148
|
+
imageUrl: nil,
|
149
|
+
weight: {
|
150
|
+
value: 0,
|
151
|
+
units: "ounces"
|
152
|
+
},
|
153
|
+
quantity: 1,
|
154
|
+
unitPrice: d.amount.to_f,
|
155
|
+
adjustment: true
|
156
|
+
}
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Workarea
|
2
|
+
module ShipStation
|
3
|
+
class Webhook
|
4
|
+
class Error < RuntimeError; end
|
5
|
+
class Error::NotFound < RuntimeError; end
|
6
|
+
class Error::UnhandledWebhook < RuntimeError; end
|
7
|
+
|
8
|
+
def self.process(attrs)
|
9
|
+
resource = attrs["resource_type"]
|
10
|
+
begin
|
11
|
+
klass = "Workarea::ShipStation::Webhook::#{resource.downcase.classify}".constantize
|
12
|
+
rescue NameError => _error
|
13
|
+
raise Error::UnhandledWebhook, "no class defined to handle #{resource}"
|
14
|
+
end
|
15
|
+
klass.new(attrs).process
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :attrs
|
19
|
+
|
20
|
+
def initialize(attrs)
|
21
|
+
@attrs = attrs
|
22
|
+
end
|
23
|
+
|
24
|
+
def process; end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Workarea
|
2
|
+
module ShipStation
|
3
|
+
class Webhook
|
4
|
+
class ItemShipNotify < Webhook
|
5
|
+
class ShipStationItemShipNotifyError < StandardError; end
|
6
|
+
|
7
|
+
def process
|
8
|
+
uri = URI(attrs["resource_url"])
|
9
|
+
rest_endpoint = "https://" + uri.host
|
10
|
+
query_hash = Rack::Utils.parse_query(uri.query)
|
11
|
+
|
12
|
+
response = gateway(rest_endpoint).get_shipping(query_hash)
|
13
|
+
|
14
|
+
raise ShipStationItemShipNotifyError, response.body["ExceptionMessage"] unless response.success?
|
15
|
+
|
16
|
+
response.body["shipments"].each do |shipment|
|
17
|
+
fulfillment = Workarea::Fulfillment.find(shipment["orderKey"])
|
18
|
+
tracking_number = shipment["trackingNumber"]
|
19
|
+
items = shipment["shipmentItems"].map { |item| { id: item["lineItemKey"], quantity: item["quantity"] } }
|
20
|
+
|
21
|
+
fulfillment.ship_items(tracking_number, items)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def gateway(rest_endpoint)
|
28
|
+
Workarea::ShipStation.gateway(rest_endpoint)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/app/views/.keep
ADDED
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
%li
|
2
|
+
%strong= t('workarea.admin.orders.attributes.checkout.ship_station_exported_at')
|
3
|
+
- if @order.ship_station_exported?
|
4
|
+
= local_time_ago(@order.ship_station_exported_at)
|
5
|
+
- else
|
6
|
+
"-"
|
7
|
+
%li
|
8
|
+
%strong= t('workarea.admin.orders.attributes.checkout.ship_station_order_id')
|
9
|
+
= @order.ship_station_order_id.presence || "-"
|
10
|
+
%li
|
11
|
+
%strong= t('workarea.admin.orders.attributes.checkout.ship_station_on_hold_until')
|
12
|
+
= @order.ship_station_on_hold_until.presence || "-"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
- if @order.ship_station_order_id.present?
|
2
|
+
.grid__cell
|
3
|
+
%button.workflow-bar__button= link_to t('workarea.admin.orders.place_on_hold'), hold_date_order_path
|
4
|
+
- if @order.ship_station_on_hold?
|
5
|
+
.grid__cell
|
6
|
+
= form_tag clear_hold_date_order_path, method: :patch do
|
7
|
+
%button.workflow-bar__button{ type: :submit }= t('workarea.admin.orders.clear_on_hold')
|
@@ -0,0 +1,27 @@
|
|
1
|
+
- @page_title = @order.name
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--right
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to_index_for(@order)
|
9
|
+
%h1= t('workarea.admin.orders.order_hold', id: @order.name)
|
10
|
+
.grid__cell.grid__cell--25
|
11
|
+
= render_aux_navigation_for(@order)
|
12
|
+
|
13
|
+
.view__container.view__container--narrow
|
14
|
+
.grid
|
15
|
+
.grid__cell.grid__cell--80
|
16
|
+
%p= t('workarea.admin.orders.hold_until_note')
|
17
|
+
|
18
|
+
- if @order.ship_station_on_hold?
|
19
|
+
%strong= t('workarea.admin.orders.on_hold_until', date: @order.ship_station_on_hold_until.try(:to_s, :date_only))
|
20
|
+
|
21
|
+
= form_tag save_hold_date_order_path, method: 'patch' do
|
22
|
+
.property__name
|
23
|
+
= label_tag 'hold_until', t('workarea.admin.orders.hold_until_date'), class: 'property__name'
|
24
|
+
= datetime_picker_tag 'hold_until', @order.ship_station_on_hold_until.try(:to_s, :date_only), class: 'text-box text-box', data: { datepicker_field: { } }
|
25
|
+
.workflow-bar
|
26
|
+
.grid.grid--auto.grid--right.grid--middle
|
27
|
+
.grid__cell= button_tag t('workarea.admin.orders.place_on_hold'), value: 'place_on_hold', class: 'workflow-bar__button workflow-bar__button--create'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Workarea
|
2
|
+
module ShipStation
|
3
|
+
class SaveOrder
|
4
|
+
class ShipStationSaveOrderError < StandardError; end
|
5
|
+
include Sidekiq::Worker
|
6
|
+
include Sidekiq::CallbacksWorker
|
7
|
+
|
8
|
+
sidekiq_options(
|
9
|
+
enqueue_on: { Workarea::Order => [:place] },
|
10
|
+
unique: :until_executing
|
11
|
+
)
|
12
|
+
|
13
|
+
def perform(id)
|
14
|
+
order = Workarea::Order.find(id)
|
15
|
+
shipstation_details = Workarea::ShipStation::Order.new(id).to_h
|
16
|
+
response = ShipStation.gateway.create_order(shipstation_details)
|
17
|
+
|
18
|
+
raise ShipStationSaveOrderError, response.body["ExceptionMessage"] unless response.success?
|
19
|
+
order.ship_station_order_id = response.body["orderId"]
|
20
|
+
order.set_ship_station_exported_at!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('..', __dir__)
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/workarea/ship_station/engine', __dir__)
|
7
|
+
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
8
|
+
|
9
|
+
# Set up gems listed in the Gemfile.
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
+
|
13
|
+
require "rails"
|
14
|
+
# Pick the frameworks you want:
|
15
|
+
require "active_model/railtie"
|
16
|
+
require "active_job/railtie"
|
17
|
+
# require "active_record/railtie"
|
18
|
+
# require "active_storage/engine"
|
19
|
+
require "action_controller/railtie"
|
20
|
+
require "action_mailer/railtie"
|
21
|
+
require "action_view/railtie"
|
22
|
+
# require "action_cable/engine"
|
23
|
+
require "sprockets/railtie"
|
24
|
+
require "rails/test_unit/railtie"
|
25
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Workarea.configure do |config|
|
2
|
+
config.ship_station = ActiveSupport::Configurable::Configuration.new
|
3
|
+
config.ship_station.api_timeout = 10
|
4
|
+
config.ship_station.open_timeout = 10
|
5
|
+
|
6
|
+
# setting this config value will set a ship_by_date for new orders.
|
7
|
+
# This value will be added to the current date and sent in the ship_by_date field.
|
8
|
+
#
|
9
|
+
# This value must be an integer.
|
10
|
+
config.ship_station.ship_by_date_lead_days = nil
|
11
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
en:
|
2
|
+
workarea:
|
3
|
+
admin:
|
4
|
+
orders:
|
5
|
+
attributes:
|
6
|
+
checkout:
|
7
|
+
ship_station_exported_at: Exported To ShipStation At
|
8
|
+
ship_station_order_id: ShipStation Order ID
|
9
|
+
ship_station_order_id: ShipStation Order ID
|
10
|
+
ship_station_on_hold_until: ShipStation Hold Until
|
11
|
+
clear_on_hold: Clear Order Hold
|
12
|
+
clear_on_hold_success: The order's hold has been cleared.
|
13
|
+
clear_on_hold_error: The order's hold could not be cleard. Please try again.
|
14
|
+
hold_until_date: Hold Until Date
|
15
|
+
hold_until_note: Setting a hold date will set this order's status to "on hold" in ShipStation.
|
16
|
+
on_hold_until: This order is currently on hold until %{date}
|
17
|
+
order_hold: Place %{id} on Hold
|
18
|
+
place_on_hold: Place Order on Hold
|
19
|
+
placed_on_hold_success: The order has been placed on hold.
|
20
|
+
placed_on_hold_error: The order could not be placed on hold. Please try again.
|