spree_zaez_billet 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +11 -0
  6. data/Guardfile +90 -0
  7. data/LICENSE +26 -0
  8. data/README.md +81 -0
  9. data/Rakefile +21 -0
  10. data/app/assets/javascripts/spree/backend/app/billet_settings/billet_setting.js.coffee +66 -0
  11. data/app/assets/javascripts/spree/backend/spree_zaez_billet.js +1 -0
  12. data/app/assets/javascripts/spree/frontend/spree_zaez_billet.js +2 -0
  13. data/app/assets/stylesheets/spree/backend/spree_zaez_billet.css +3 -0
  14. data/app/assets/stylesheets/spree/frontend/spree_zaez_billet.css +4 -0
  15. data/app/controllers/spree/admin/billet_settings_controller.rb +29 -0
  16. data/app/controllers/spree/admin/billets_controller.rb +61 -0
  17. data/app/controllers/spree/billets_controller.rb +35 -0
  18. data/app/models/spree/address_decorator.rb +17 -0
  19. data/app/models/spree/billet.rb +257 -0
  20. data/app/models/spree/payment_method/billet.rb +83 -0
  21. data/app/overrides/spree/admin/shared/_main_menu/add_payment_tab_to_main_menu.html.erb.deface +6 -0
  22. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_billet_settings_tab.html.erb.deface +2 -0
  23. data/app/overrides/spree/payments/_payment/add_billet_info_to_order_details.html.erb.deface +6 -0
  24. data/app/views/spree/admin/billet_settings/edit.html.erb +154 -0
  25. data/app/views/spree/admin/billets/return.html.erb +40 -0
  26. data/app/views/spree/admin/billets/return_info.html.erb +32 -0
  27. data/app/views/spree/admin/billets/shipping.html.erb +39 -0
  28. data/app/views/spree/admin/payments/source_forms/_billet.html.erb +4 -0
  29. data/app/views/spree/admin/payments/source_views/_billet.html.erb +39 -0
  30. data/app/views/spree/admin/shared/sub_menu/_payment.html.erb +4 -0
  31. data/app/views/spree/checkout/payment/_billet.html.erb +4 -0
  32. data/bin/rails +7 -0
  33. data/config/locales/en.yml +58 -0
  34. data/config/locales/pt-br.yml +57 -0
  35. data/config/routes.rb +13 -0
  36. data/db/migrate/20150617193744_create_spree_billets.rb +14 -0
  37. data/lib/generators/spree_zaez_billet/install/install_generator.rb +31 -0
  38. data/lib/spree/billet_configuration.rb +31 -0
  39. data/lib/spree_zaez_billet.rb +5 -0
  40. data/lib/spree_zaez_billet/engine.rb +31 -0
  41. data/lib/spree_zaez_billet/factories.rb +34 -0
  42. data/spec/features/admin/billet_payments_spec.rb +85 -0
  43. data/spec/features/admin/billet_settings_spec.rb +207 -0
  44. data/spec/features/admin/billets_return_spec.rb +39 -0
  45. data/spec/features/admin/billets_shipping_spec.rb +87 -0
  46. data/spec/features/checkout_with_billet_spec.rb +84 -0
  47. data/spec/fixtures/files/cnab240.ret +16 -0
  48. data/spec/fixtures/files/cnab400.ret +54 -0
  49. data/spec/lib/spree/billet_configuration_spec.rb +14 -0
  50. data/spec/models/spree/address_decorator_spec.rb +13 -0
  51. data/spec/models/spree/billet_spec.rb +366 -0
  52. data/spec/spec_helper.rb +95 -0
  53. data/spec/support/capybara_login.rb +13 -0
  54. data/spec/support/shared_contexts/checkout_setup.rb +10 -0
  55. data/spec/support/verify_input_field.rb +16 -0
  56. data/spree_zaez_billet.gemspec +38 -0
  57. metadata +72 -3
@@ -0,0 +1,35 @@
1
+ class Spree::BilletsController < Spree::StoreController
2
+
3
+ before_action :load_data, only: :show
4
+
5
+ def show
6
+ if @billet.due_date.past?
7
+ # voids the old payment
8
+ old_payment = @billet.payment
9
+ old_payment.void_transaction!
10
+
11
+ # creates the new payment
12
+ params = {order: @billet.order,
13
+ amount: old_payment.amount,
14
+ payment_method: @billet.payment_method,
15
+ source_attributes: {order: @billet.order,
16
+ user: @billet.user,
17
+ status: 'pending'}}
18
+ new_payment = Spree::Payment.new(params)
19
+ new_payment.pend!
20
+ new_payment.process!
21
+
22
+ @billet = new_payment.source
23
+ end
24
+ # generate the billet document
25
+ @document = @billet.generate_document
26
+ send_data @document.to_pdf, filename: "boleto_#{@billet.order.number}.pdf"
27
+ end
28
+
29
+ private
30
+
31
+ def load_data
32
+ @billet = Spree::Billet.find params[:id] || params[:billet_id]
33
+ end
34
+
35
+ end
@@ -0,0 +1,17 @@
1
+ Spree::Address.class_eval do
2
+
3
+ # Return full address in same string
4
+ #
5
+ # @author Isabella Santos
6
+ #
7
+ # @return [String]
8
+ #
9
+ def full_address
10
+ full = address1
11
+ full << ", #{address2}" if address2.present?
12
+ full << " - #{zipcode}" if zipcode.present?
13
+ full << " - #{city}" if city.present?
14
+ full << "/#{state.abbr}" if state.present?
15
+ full
16
+ end
17
+ end
@@ -0,0 +1,257 @@
1
+ module Spree
2
+ class Billet < ActiveRecord::Base
3
+
4
+ has_one :payment, as: :source
5
+ belongs_to :order
6
+ belongs_to :user
7
+ belongs_to :payment_method
8
+
9
+ scope :unregistered, -> { where(status: 'waiting_registry') }
10
+
11
+ # Displays what actions can be done according to payment method
12
+ #
13
+ # @author Isabella Santos
14
+ #
15
+ # @return [Array]
16
+ #
17
+ def actions
18
+ act = []
19
+ act << 'capture' if can_capture? payment
20
+ act << 'void' if can_void? payment
21
+ act
22
+ end
23
+
24
+ # Save the amount of the billet
25
+ # if amount is a string, convert to a BigDecimal
26
+ #
27
+ # copy of Spree::Payment.amount
28
+ #
29
+ def amount=(amount)
30
+ self[:amount] =
31
+ case amount
32
+ when String
33
+ separator = I18n.t('number.currency.format.separator')
34
+ number = amount.delete("^0-9-#{separator}\.").tr(separator, '.')
35
+ number.to_d if number.present?
36
+ end || amount
37
+ end
38
+
39
+ # Determines whether can capture the payment
40
+ # (only can capture when the state is checkout or pending)
41
+ #
42
+ # @author Isabella Santos
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def can_capture?(payment)
47
+ payment.pending? || payment.checkout?
48
+ end
49
+
50
+ # Determines whether can void the payment
51
+ # (only can void when the state is different of void, failure or invalid)
52
+ #
53
+ # @author Isabella Santos
54
+ #
55
+ # @return [Boolean]
56
+ #
57
+ def can_void?(payment)
58
+ !%w(void failure invalid).include?(payment.state)
59
+ end
60
+
61
+ # Defines the currency of the billet
62
+ # based in te currency of the order
63
+ #
64
+ # copy of Spree::Payment.currency
65
+ #
66
+ def currency
67
+ order.currency
68
+ end
69
+
70
+ # Calculates the due date
71
+ # according to created at
72
+ #
73
+ # @author Isabella Santos
74
+ #
75
+ # @return [Date]
76
+ #
77
+ def due_date
78
+ created_at + Spree::BilletConfig.due_date.days
79
+ end
80
+
81
+ # Generate the object from gem brcobranca
82
+ #
83
+ # @author Isabella Santos
84
+ #
85
+ # @return [Brcobranca::Boleto::Base]
86
+ #
87
+ def generate_document
88
+ config = Spree::BilletConfig
89
+ doc_user = user.attributes[config.doc_customer_attr] rescue ''
90
+
91
+ params = {cedente: config.corporate_name,
92
+ documento_cedente: config.document,
93
+ cedente_endereco: config.address,
94
+ sacado: self.customer_name,
95
+ sacado_documento: doc_user,
96
+ sacado_endereco: order.bill_address.full_address,
97
+ numero_documento: document_number,
98
+ dias_vencimento: config.due_date,
99
+ data_documento: Date.parse(created_at.to_s),
100
+ valor: amount,
101
+ aceite: config.acceptance,
102
+ agencia: config.agency,
103
+ conta_corrente: config.account,
104
+ convenio: config.agreement,
105
+ carteira: config.wallet,
106
+ variacao: config.variation_wallet
107
+ }
108
+ (1..6).each { |cont| params["instrucao#{cont}".to_sym] = config["instruction_#{cont}"] }
109
+ if config.bank == 'sicredi' then
110
+ params.merge!({posto: config.office_code,
111
+ byte_idt: config.byte_idt})
112
+ end
113
+
114
+ document = case config.bank
115
+ when 'banco_brasil' then Brcobranca::Boleto::BancoBrasil.new params
116
+ when 'bradesco' then Brcobranca::Boleto::Bradesco.new params
117
+ when 'caixa' then Brcobranca::Boleto::Caixa.new params
118
+ when 'santander' then Brcobranca::Boleto::Santander.new params
119
+ when 'itau' then Brcobranca::Boleto::Itau.new params
120
+ when 'sicredi' then Brcobranca::Boleto::Sicredi.new params
121
+ else
122
+ raise 'It is necessary set the billet config'
123
+ end
124
+ document
125
+ end
126
+
127
+ # Return the amount converted to Money
128
+ # according to currency
129
+ #
130
+ # copy of Spree::Payment.money
131
+ #
132
+ def money
133
+ Spree::Money.new(amount, { currency: currency })
134
+ end
135
+ alias display_amount money
136
+
137
+ # Returns the name of the customer according
138
+ # to bill address of order
139
+ #
140
+ # @author Isabella Santos
141
+ #
142
+ # @return [String]
143
+ #
144
+ def customer_name
145
+ "#{order.bill_address.firstname} #{order.bill_address.lastname}"
146
+ rescue
147
+ ''
148
+ end
149
+
150
+ # Returns if billet is paid
151
+ #
152
+ # @author Isabella Santos
153
+ #
154
+ # @return [Boolean]
155
+ #
156
+ def paid?
157
+ status == 'paid'
158
+ end
159
+
160
+ # Returns if billet is pending
161
+ #
162
+ # @author Isabella Santos
163
+ #
164
+ # @return [Boolean]
165
+ #
166
+ def pending?
167
+ status == 'pending'
168
+ end
169
+
170
+ # Returns if billet is waiting registry
171
+ #
172
+ # @author Isabella Santos
173
+ #
174
+ # @return [Boolean]
175
+ #
176
+ def waiting_registry?
177
+ status == 'waiting_registry'
178
+ end
179
+
180
+ # Return if it is possible generate the document
181
+ # (when status is waiting registry or pending)
182
+ #
183
+ # @author Isabella Santos
184
+ #
185
+ # @return [Boolean]
186
+ #
187
+ def can_generate_document?
188
+ %w(waiting_registry pending).include?(status)
189
+ end
190
+
191
+ # Chanege the status to pending
192
+ #
193
+ # @author Isabella Santos
194
+ #
195
+ def to_pending!
196
+ self.status = 'pending'
197
+ self.save
198
+ end
199
+
200
+ def self.generate_shipping
201
+ return {reason: :there_are_not_any_billets_to_registry, messages: []} if unregistered.empty?
202
+ config = Spree::BilletConfig
203
+ params = {empresa_mae: config.corporate_name,
204
+ agencia: config.agency,
205
+ conta_corrente: config.account,
206
+ sequencial_remessa: config.shipping_number}
207
+ document = case config.bank
208
+ when 'banco_brasil'
209
+ Brcobranca::Remessa::Cnab240::BancoBrasil.new(params.merge!({convenio: config.agreement,
210
+ carteira: config.wallet,
211
+ documento_cedente: config.document,
212
+ variacao: config.variation_wallet}))
213
+ when 'bradesco'
214
+ Brcobranca::Remessa::Cnab400::Bradesco.new(params.merge!({digito_conta: config.account_digit,
215
+ carteira: config.wallet,
216
+ codigo_empresa: config.company_code}))
217
+ when 'caixa'
218
+ Brcobranca::Remessa::Cnab240::Caixa.new(params.merge!({convenio: config.agreement,
219
+ digito_conta: config.account_digit,
220
+ documento_cedente: config.document,
221
+ versao_aplicativo: config.app_version}))
222
+ when 'itau'
223
+ Brcobranca::Remessa::Cnab400::Itau.new(params.merge!({carteira: config.wallet,
224
+ documento_cedente: config.document,
225
+ digito_conta: config.account_digit}))
226
+ else
227
+ return {reason: :billet_bank_not_implemented, messages: []}
228
+ end
229
+ document.pagamentos = []
230
+ unregistered.each do |billet|
231
+ next if billet.user.nil?
232
+ doc_user = billet.user.attributes[config.doc_customer_attr] rescue ''
233
+ user_address = billet.order.bill_address
234
+ payment = Brcobranca::Remessa::Pagamento.new(valor: billet.amount,
235
+ data_vencimento: billet.due_date,
236
+ nosso_numero: billet.document_number,
237
+ documento_sacado: doc_user,
238
+ nome_sacado: billet.customer_name,
239
+ endereco_sacado: user_address.address1,
240
+ bairro_sacado: user_address.address2,
241
+ cep_sacado: user_address.zipcode,
242
+ cidade_sacado: user_address.city,
243
+ uf_sacado: user_address.state.abbr)
244
+ document.pagamentos << payment
245
+ end
246
+ shipping = document.gera_arquivo
247
+ if shipping.is_a? String
248
+ config.shipping_number += 1
249
+ # change the status of billets to pending
250
+ unregistered.each { |billet| billet.to_pending! }
251
+ end
252
+ shipping
253
+ rescue Brcobranca::RemessaInvalida => invalid
254
+ {reason: :invalid_billets, messages: invalid.to_s.split(', ')}
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,83 @@
1
+ module Spree
2
+ class PaymentMethod::Billet < PaymentMethod
3
+
4
+ def payment_source_class
5
+ Spree::Billet
6
+ end
7
+
8
+ # Purchases the payment
9
+ # saving the amount, document number (payment ID)
10
+ # on source object (Spree::Billet)
11
+ # This method is called when th payment method is set to auto capture
12
+ # so, this will create the billet with status paid
13
+ #
14
+ # @author Isabella Santos
15
+ #
16
+ # @return [ActiveMerchant::Billing::Response]
17
+ #
18
+ def purchase(amount, source, *args)
19
+ source.amount = amount.to_d / 100
20
+ source.document_number = source.payment.id
21
+ source.status = 'paid'
22
+
23
+ source.payment.response_code = source.document_number
24
+ ret = source.save
25
+
26
+ ActiveMerchant::Billing::Response.new(ret, '', {}, authorization: source.document_number)
27
+ end
28
+
29
+ # Authorizes the payment
30
+ # saving the amount, document number (payment ID)
31
+ # on source object (Spree::Billet)
32
+ #
33
+ # @author Isabella Santos
34
+ #
35
+ # @return [ActiveMerchant::Billing::Response]
36
+ #
37
+ def authorize(amount, source, *args)
38
+ source.amount = amount.to_d / 100
39
+ source.document_number = source.payment.id
40
+
41
+ ret = source.save
42
+
43
+ ActiveMerchant::Billing::Response.new(ret, '', {}, authorization: source.document_number)
44
+ end
45
+
46
+ # Captures the payment
47
+ # modifying the status and amount and saving the paid date
48
+ # of the source (Spree::Billet)
49
+ #
50
+ # @author Isabella Santos
51
+ #
52
+ # @return [ActiveMerchant::Billing::Response]
53
+ #
54
+ def capture(amount, response_code, gateway_options)
55
+ billet = Spree::Billet.find_by document_number: response_code
56
+ billet.amount = amount.to_d / 100
57
+ billet.paid_in = Date.today
58
+ billet.status = 'paid'
59
+ billet.save
60
+
61
+ ActiveMerchant::Billing::Response.new(true, 'Billet Method: Successfully captured', {}, authorization: response_code)
62
+ rescue
63
+ ActiveMerchant::Billing::Response.new(false, 'Billet Method: Failed when try capture', {}, {})
64
+ end
65
+
66
+ # Voids the payment
67
+ # modifying the status of the source (Spree::Billet)
68
+ #
69
+ # @author Isabella Santos
70
+ #
71
+ # @return [ActiveMerchant::Billing::Response]
72
+ #
73
+ def void(response_code, gateway_options)
74
+ billet = Spree::Billet.find_by document_number: response_code
75
+ billet.status = 'void'
76
+ billet.save
77
+
78
+ ActiveMerchant::Billing::Response.new(true, 'Billet Method: Successfully voided', {}, authorization: response_code)
79
+ rescue
80
+ ActiveMerchant::Billing::Response.new(false, 'Billet Method: Failed when try void', {}, {})
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,6 @@
1
+ <!-- insert_before "erb[silent]:contains('if can? :admin, Spree::Product')" -->
2
+ <% if can? :admin, Spree::Payment %>
3
+ <ul class="nav nav-sidebar">
4
+ <%= main_menu_tree Spree.t(:payments), icon: "usd", sub_menu: "payment", url: "#sidebar-payment" %>
5
+ </ul>
6
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <!-- insert_bottom "[data-hook='admin_configurations_sidebar_menu'], #admin_configurations_sidebar_menu[data-hook]" -->
2
+ <%= configurations_sidebar_menu_item t(:billet_settings), edit_admin_billet_settings_path %>
@@ -0,0 +1,6 @@
1
+ <!-- replace "erb[silent]:contains('else')" -->
2
+ <% elsif source.is_a?(Spree::Billet) %>
3
+ <label><%= Spree.t(:payment_method_billet) %></label><br />
4
+ <span><%= "#{Spree.t(:due_date)}: #{source.due_date.strftime(t('date.formats.default'))}" %></span><br />
5
+ <%= link_to Spree.t(:generate_billet), billet_path(source.id), target: '_blank', class: 'btn btn-sm btn-info' if source.can_generate_document? %>
6
+ <% else %>
@@ -0,0 +1,154 @@
1
+ <%= render :partial => 'spree/admin/shared/sub_menu/configuration' %>
2
+
3
+ <% content_for :page_title do %>
4
+ <%= Spree.t(:billet_settings) %>
5
+ <% end %>
6
+
7
+ <%= form_tag admin_billet_settings_path, :method => :put do |form| %>
8
+ <div id="billet_preferences" data-hook="billet_preferences">
9
+ <div class="panel panel-default">
10
+ <div class="panel-heading">
11
+ <h1 class="panel-title">
12
+ <%= Spree.t(:settings) %>
13
+ </h1>
14
+ </div>
15
+ <div class="panel-body">
16
+ <div class="row">
17
+ <div class="col-sm-12">
18
+ <%= label_tag(:corporate_name, Spree.t(:corporate_name) + ': ') + tag(:br) %>
19
+ <%= text_field_tag :corporate_name, @config.corporate_name, class: 'form-control' %>
20
+ </div>
21
+ </div>
22
+ <div class="row">
23
+ <div class="col-sm-4">
24
+ <%= label_tag(:document, Spree.t(:document) + ': ') + tag(:br) %>
25
+ <%= text_field_tag :document, @config.document, class: 'form-control' %>
26
+ </div>
27
+ <div class="col-sm-8">
28
+ <%= label_tag(:address, Spree.t(:address) + ': ') + tag(:br) %>
29
+ <%= text_field_tag :address, @config.address, class: 'form-control' %>
30
+ </div>
31
+ </div>
32
+ <div class="row">
33
+ <div class="col-sm-12">
34
+ <%= check_box_tag :registered, true, @config.registered %>
35
+ <%= label_tag(:registered) %>
36
+ </div>
37
+ </div>
38
+ <div class="row">
39
+ <div class="col-sm-4">
40
+ <%= label_tag(:shipping_number, Spree.t(:shipping_number) + ': ') + tag(:br) %>
41
+ <%= text_field_tag :shipping_number, @config.shipping_number, class: 'form-control', disabled: true %>
42
+ </div>
43
+ <div class="col-sm-4">
44
+ <%= label_tag(:clear_shipping_number, ' ') + tag(:br) %>
45
+ <%= link_to_with_icon 'trash', Spree.t(:clear_shipping_number), admin_clear_shipping_url, class: 'btn btn-warning',
46
+ id: 'clear_shipping' %>
47
+ </div>
48
+ </div>
49
+ <div class="row">
50
+ <div class="col-sm-12">
51
+ <%= label_tag(:bank, Spree.t(:bank) + ': ') + tag(:br) %>
52
+ <%= select_tag :bank,
53
+ options_for_select(@banks.collect { |item| [Spree.t("bank_#{item}"), item] }, @config.bank),
54
+ class: 'select2', include_blank: true %>
55
+ </div>
56
+ </div>
57
+ <div class="row">
58
+ <div class="col-sm-4">
59
+ <%= label_tag(:agency, Spree.t(:agency) + ': ') + tag(:br) %>
60
+ <%= text_field_tag :agency, @config.agency, class: 'form-control' %>
61
+ </div>
62
+ <div class="col-sm-4">
63
+ <%= label_tag(:account, Spree.t(:account) + ': ') + tag(:br) %>
64
+ <%= text_field_tag :account, @config.account, class: 'form-control' %>
65
+ </div>
66
+ <div class="col-sm-4" id="account_digit_box">
67
+ <%= label_tag(:account_digit, Spree.t(:account_digit) + ': ') + tag(:br) %>
68
+ <%= text_field_tag :account_digit, @config.account_digit, class: 'form-control' %>
69
+ </div>
70
+ <div class="col-sm-4" id="agreement_box">
71
+ <%= label_tag(:agreement, Spree.t(:agreement) + ': ') + tag(:br) %>
72
+ <%= text_field_tag :agreement, @config.agreement, class: 'form-control' %>
73
+ </div>
74
+ <div class="col-sm-4" id="wallet_box">
75
+ <%= label_tag(:wallet, Spree.t(:wallet) + ': ') + tag(:br) %>
76
+ <%= text_field_tag :wallet, @config.wallet, class: 'form-control' %>
77
+ </div>
78
+ <div class="col-sm-4" id="variation_wallet_box">
79
+ <%= label_tag(:variation_wallet, Spree.t(:variation_wallet) + ': ') + tag(:br) %>
80
+ <%= text_field_tag :variation_wallet, @config.variation_wallet, class: 'form-control' %>
81
+ </div>
82
+ <div class="col-sm-4" id="app_version_box">
83
+ <%= label_tag(:app_version, Spree.t(:app_version) + ': ') + tag(:br) %>
84
+ <%= text_field_tag :app_version, @config.app_version, class: 'form-control' %>
85
+ </div>
86
+ <div class="col-sm-4" id="company_code_box">
87
+ <%= label_tag(:company_code, Spree.t(:company_code) + ': ') + tag(:br) %>
88
+ <%= text_field_tag :company_code, @config.company_code, class: 'form-control' %>
89
+ </div>
90
+ <div class="col-sm-4" id="byte_idt_box">
91
+ <%= label_tag(:byte_idt, Spree.t(:byte_idt) + ': ') + tag(:br) %>
92
+ <%= text_field_tag :byte_idt, @config.byte_idt, class: 'form-control' %>
93
+ </div>
94
+ <div class="col-sm-4" id="office_code_box">
95
+ <%= label_tag(:office_code, Spree.t(:office_code) + ': ') + tag(:br) %>
96
+ <%= text_field_tag :office_code, @config.office_code, class: 'form-control' %>
97
+ </div>
98
+ </div>
99
+ <div class="row">
100
+ <div class="col-sm-4">
101
+ <%= label_tag(:due_date, Spree.t(:due_date) + ': ') + tag(:br) %>
102
+ <%= number_field_tag :due_date, @config.due_date, class: 'form-control' %>
103
+ </div>
104
+ <div class="col-sm-8">
105
+ <%= label_tag(:acceptance, Spree.t(:acceptance) + ': ') + tag(:br) %>
106
+ <%= radio_button_tag :acceptance, 'S', @config.acceptance == 'S' %>
107
+ <%= label_tag(:acceptance_s, Spree.t(:yes)) %>
108
+ <%= radio_button_tag :acceptance, 'N', @config.acceptance == 'N' %>
109
+ <%= label_tag(:acceptance_n, Spree.t(:no)) %>
110
+ </div>
111
+ </div>
112
+ <div class="row">
113
+ <div class="col-sm-6">
114
+ <%= label_tag(:instruction_1, Spree.t(:instruction_1) + ': ') + tag(:br) %>
115
+ <%= text_field_tag :instruction_1, @config.instruction_1, class: 'form-control' %>
116
+ </div>
117
+ <div class="col-sm-6">
118
+ <%= label_tag(:instruction_2, Spree.t(:instruction_2) + ': ') + tag(:br) %>
119
+ <%= text_field_tag :instruction_2, @config.instruction_2, class: 'form-control' %>
120
+ </div>
121
+ <div class="col-sm-6">
122
+ <%= label_tag(:instruction_3, Spree.t(:instruction_3) + ': ') + tag(:br) %>
123
+ <%= text_field_tag :instruction_3, @config.instruction_3, class: 'form-control' %>
124
+ </div>
125
+ <div class="col-sm-6">
126
+ <%= label_tag(:instruction_4, Spree.t(:instruction_4) + ': ') + tag(:br) %>
127
+ <%= text_field_tag :instruction_4, @config.instruction_4, class: 'form-control' %>
128
+ </div>
129
+ <div class="col-sm-6">
130
+ <%= label_tag(:instruction_5, Spree.t(:instruction_5) + ': ') + tag(:br) %>
131
+ <%= text_field_tag :instruction_5, @config.instruction_5, class: 'form-control' %>
132
+ </div>
133
+ <div class="col-sm-6">
134
+ <%= label_tag(:instruction_6, Spree.t(:instruction_6) + ': ') + tag(:br) %>
135
+ <%= text_field_tag :instruction_6, @config.instruction_6, class: 'form-control' %>
136
+ </div>
137
+ </div>
138
+ <div class="row">
139
+ <div class="col-sm-12">
140
+ <%= label_tag(:doc_customer_attr, Spree.t(:doc_customer_attr) + ': ') + tag(:br) %>
141
+ <%= select_tag :doc_customer_attr,
142
+ options_for_select(@user_attr.collect { |item| [Spree.t(item), item] }, @config.doc_customer_attr),
143
+ class: 'select2', include_blank: true %>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ <%= render partial: 'spree/admin/shared/edit_resource_links', locals: { collection_url: edit_admin_billet_settings_url } %>
150
+ <% end %>
151
+
152
+ <script type="text/javascript">
153
+ new window.BilletSetting();
154
+ </script>