spree_tradebyte 0.1.12.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.byebug_history +39 -0
  3. data/.gitignore +22 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +24 -0
  6. data/.travis.yml +31 -0
  7. data/Appraisals +29 -0
  8. data/Gemfile +16 -0
  9. data/LICENSE +26 -0
  10. data/README.md +59 -0
  11. data/Rakefile +21 -0
  12. data/app/assets/javascripts/spree/backend/spree_tradebyte.js +2 -0
  13. data/app/assets/javascripts/spree/frontend/spree_tradebyte.js +2 -0
  14. data/app/assets/stylesheets/spree/backend/spree_tradebyte.css +4 -0
  15. data/app/assets/stylesheets/spree/frontend/spree_tradebyte.css +4 -0
  16. data/app/jobs/spree_tradebyte/application_job.rb +7 -0
  17. data/app/jobs/spree_tradebyte/export_products_job.rb +229 -0
  18. data/app/jobs/spree_tradebyte/export_stock_job.rb +39 -0
  19. data/app/jobs/spree_tradebyte/import_orders_job.rb +70 -0
  20. data/app/jobs/spree_tradebyte/order/processor.rb +158 -0
  21. data/app/mailers/application_mailer.rb +5 -0
  22. data/app/mailers/spree_tradebyte/error_notification_mailer.rb +9 -0
  23. data/app/models/spree/order/mail_defuser.rb +15 -0
  24. data/app/models/spree/order/tradebyte_message_builder.rb +133 -0
  25. data/app/models/spree/order_decorator.rb +14 -0
  26. data/app/models/spree/order_updater_decorator.rb +18 -0
  27. data/app/models/spree/payment_method/tradebyte.rb +7 -0
  28. data/app/models/spree/product_decorator.rb +15 -0
  29. data/app/models/spree/reimbursement/mail_defuser.rb +9 -0
  30. data/app/models/spree/reimbursement_decorator.rb +11 -0
  31. data/app/models/spree/shipment_decorator.rb +9 -0
  32. data/app/models/spree/shipment_handler/mail_defuser.rb +7 -0
  33. data/app/models/spree/shipment_handler_decorator.rb +5 -0
  34. data/app/models/spree/variant_decorator.rb +47 -0
  35. data/app/overrides/order_index.rb +13 -0
  36. data/app/overrides/tradebyte_settings.rb +13 -0
  37. data/app/views/layouts/spree_tradebyte/mailer.html.erb +13 -0
  38. data/app/views/layouts/spree_tradebyte/mailer.text.erb +1 -0
  39. data/app/views/spree/admin/orders/_index_tradebyte_state_override.html.erb +7 -0
  40. data/app/views/spree/admin/orders/_index_tradebyte_state_override_head.html.erb +1 -0
  41. data/app/views/spree/admin/products/_tradebyte_fields.html.erb +15 -0
  42. data/app/views/spree/admin/variants/_tradebyte_fields.html.erb +16 -0
  43. data/app/views/spree_tradebyte/error_notification_mailer/exception_mail.html.erb +12 -0
  44. data/bin/rails +8 -0
  45. data/config/locales/en.yml +5 -0
  46. data/config/routes.rb +3 -0
  47. data/db/migrate/20190301122602_add_tradebyte_exported_to_spree_orders.rb +5 -0
  48. data/db/migrate/20190305123644_add_columns_to_spree_orders.rb +8 -0
  49. data/db/migrate/20190307133555_add_tradebyte_id_to_spree_line_items.rb +5 -0
  50. data/db/migrate/20190315162630_add_tradebyte_sku_to_line_items.rb +5 -0
  51. data/db/migrate/20190529120919_add_tradebyte_fields_to_products.rb +7 -0
  52. data/db/migrate/20190529145337_add_tradebyte_settings_to_spree_variants.rb +5 -0
  53. data/db/migrate/20190611114706_create_shipping_methods_for_tradebyte.rb +17 -0
  54. data/db/migrate/20190611114720_create_payment_method_for_tradebyte.rb +5 -0
  55. data/lib/generators/spree_tradebyte/install/install_generator.rb +28 -0
  56. data/lib/generators/spree_tradebyte/templates/initializer.rb +42 -0
  57. data/lib/helpers/setup_configuration.rb +27 -0
  58. data/lib/spree_tradebyte.rb +26 -0
  59. data/lib/spree_tradebyte/engine.rb +25 -0
  60. data/lib/spree_tradebyte/factories.rb +6 -0
  61. data/lib/spree_tradebyte/tb_logger.rb +14 -0
  62. data/lib/spree_tradebyte/tradebyte_ftp.rb +98 -0
  63. data/lib/spree_tradebyte/version.rb +18 -0
  64. data/lib/tasks/variants.rake +13 -0
  65. data/spree_tradebyte.gemspec +48 -0
  66. metadata +427 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7b934e0dc0244b5c1d79334c326688c6a9b29247ebb6f138a7ee3a9dd46f38e8
4
+ data.tar.gz: 18de0315b7f0c766c161f918caefa951ca6ffaa1150a282d06353ff246a0fd9c
5
+ SHA512:
6
+ metadata.gz: cac6c253529c42ff2c873ec6a85b73042f130ede70d46d3bbfb427305c25dd22d46ede4c5362037f5bee1f9e48b5167c18ff1cab2c261ff4075ea08ed77ab6d1
7
+ data.tar.gz: fcec6d78d405ce73967c5c8c7dd73e1f821806b678fd305d7777385e0b5243a2f9f2d223b8b400aaa6dc0c63534979aef49f732d34eb2e1a91e8427550c301e0
@@ -0,0 +1,39 @@
1
+ ftp.list
2
+ ftp.put('Rakefile')
3
+ ftp.put('test.txt', 'lalal')
4
+ ftp.touch('xx.text')
5
+ ftp.nlst('.')
6
+ ftp.nlst('test')
7
+ ftp.nlst
8
+ ftp.list
9
+ ftp.mkdir('test')
10
+ ftp.list
11
+ ftp.mkdir('test')
12
+ ftp.list
13
+ x
14
+ next
15
+ quit
16
+ ftp.list
17
+ ftp.chdir('IN')
18
+ ftp.chdir('./IN')
19
+ ftp.chdir('IN')
20
+ ftp.chdir('OUT')
21
+ ftp.nlst('**')
22
+ ftp.ls
23
+ ftp.list('*')
24
+ ftp.list
25
+ ftp.mkdir('IN')
26
+ ftp.put('test.txt')
27
+ ftp
28
+ x
29
+ next
30
+ quit
31
+ ftp.nlst('*')
32
+ ftp.nlst(*)
33
+ ftp.nlst
34
+ ftp.nlist
35
+ ftp
36
+ x
37
+ next
38
+ x
39
+ pry x
@@ -0,0 +1,22 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .DS_Store
5
+ .idea
6
+ .localeapp/locales
7
+ .project
8
+ coverage
9
+ default
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.sw?
15
+ spec/dummy
16
+ .rvmrc
17
+ .sass-cache
18
+ public/spree
19
+ .ruby-version
20
+ .ruby-gemset
21
+ gemfiles/*.gemfile.lock
22
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ -r spec_helper
3
+ -f documentation
@@ -0,0 +1,24 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+ TargetRubyVersion: 2.4
4
+ Include:
5
+ - '**/Gemfile'
6
+ - '**/Rakefile'
7
+ - '**/Appraisals'
8
+ Exclude:
9
+ - 'spec/dummy/**/*'
10
+ - 'lib/generators/**/*'
11
+
12
+ Rails:
13
+ Enabled: true
14
+
15
+ Metrics/LineLength:
16
+ Max: 150
17
+
18
+ # DISABLED
19
+
20
+ Style/Documentation:
21
+ Enabled: false
22
+
23
+ Style/FrozenStringLiteralComment:
24
+ Enabled: false
@@ -0,0 +1,31 @@
1
+ sudo: required
2
+ dist: trusty
3
+
4
+ language: ruby
5
+
6
+ env:
7
+ - DB=postgres
8
+ - DB=mysql
9
+
10
+ gemfile:
11
+ - gemfiles/spree_3_1.gemfile
12
+ - gemfiles/spree_3_2.gemfile
13
+ - gemfiles/spree_3_3.gemfile
14
+ - gemfiles/spree_3_4.gemfile
15
+ - gemfiles/spree_master.gemfile
16
+
17
+ script:
18
+ - bundle exec rake test_app
19
+ - bundle exec rake spec
20
+
21
+ rvm:
22
+ - 2.4.2
23
+ - 2.3.1
24
+ - 2.2.7
25
+
26
+ matrix:
27
+ allow_failures:
28
+ - gemfile: gemfiles/spree_master.gemfile
29
+
30
+ before_install:
31
+ - mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
@@ -0,0 +1,29 @@
1
+ appraise 'spree-3-1' do
2
+ gem 'spree', '~> 3.1.0'
3
+ gem 'spree_auth_devise', '~> 3.1.0'
4
+ gem 'rails_test_params_backport', group: :test
5
+ end
6
+
7
+ appraise 'spree-3-2' do
8
+ gem 'spree', '~> 3.2.0'
9
+ gem 'spree_auth_devise', '~> 3.2.0'
10
+ gem 'rails-controller-testing'
11
+ end
12
+
13
+ appraise 'spree-3-3' do
14
+ gem 'spree', '~> 3.3.0'
15
+ gem 'spree_auth_devise', '~> 3.3.0'
16
+ gem 'rails-controller-testing'
17
+ end
18
+
19
+ appraise 'spree-3-4' do
20
+ gem 'spree', '~> 3.4.0'
21
+ gem 'spree_auth_devise', '~> 3.3.0'
22
+ gem 'rails-controller-testing'
23
+ end
24
+
25
+ appraise 'spree-master' do
26
+ gem 'spree', github: 'spree/spree', branch: 'master'
27
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master'
28
+ gem 'rails-controller-testing'
29
+ end
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
8
+ gem 'spree', github: 'spree/spree', branch: 'master'
9
+ # Provides basic authentication functionality for testing parts of your engine
10
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master'
11
+ gem 'rails-controller-testing'
12
+
13
+ gem 'rubocop', require: false
14
+ gem 'rubocop-rspec', require: false
15
+
16
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2019 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,59 @@
1
+ # SpreeTradebyte
2
+
3
+ Introduction goes here.
4
+
5
+ ## Installation
6
+
7
+ 1. Add this extension to your Gemfile with this line:
8
+ ```ruby
9
+ gem 'spree_tradebyte', github: '[your-github-handle]/spree_tradebyte'
10
+ ```
11
+
12
+ 2. Install the gem using Bundler:
13
+ ```ruby
14
+ bundle install
15
+ ```
16
+
17
+ 3. Copy & run migrations
18
+ ```ruby
19
+ bundle exec rails g spree_tradebyte:install
20
+ ```
21
+
22
+ 4. Configure your integration inside `config/initializers/spree_tradebyte.rb`
23
+
24
+ 5. Configure your job runner to execute the following every 10 or so minutes
25
+ ```ruby
26
+ SpreeTradebyte::ImportOrdersJob.perform_async
27
+ SpreeTradebyte::ExportStockJob.perform_async
28
+ ```
29
+
30
+ The jobs will run on the `tradebyte` queue.
31
+
32
+ 6. Restart your server
33
+
34
+ If your server was running, restart it so that it can find the assets properly.
35
+
36
+ ## Testing
37
+
38
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `rake test_app`.
39
+
40
+ ```shell
41
+ bundle
42
+ bundle exec rake
43
+ ```
44
+
45
+ When testing your applications integration with this extension you may use it's factories.
46
+ Simply add this require statement to your spec_helper:
47
+
48
+ ```ruby
49
+ require 'spree_tradebyte/factories'
50
+ ```
51
+
52
+
53
+ ## Contributing
54
+
55
+ If you'd like to contribute, please take a look at the
56
+ [instructions](CONTRIBUTING.md) for installing dependencies and crafting a good
57
+ pull request.
58
+
59
+ Copyright (c) 2019 Fabian Oudhaarlem, released under the New BSD License.
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/extension_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default do
10
+ if Dir['spec/dummy'].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir('../../')
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc 'Generates a dummy app for testing'
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'spree_tradebyte'
20
+ Rake::Task['extension:test_app'].invoke
21
+ end
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -0,0 +1,229 @@
1
+ require 'nokogiri'
2
+ require 'parallel'
3
+
4
+ class SpreeTradebyte::ExportProductsJob < ApplicationJob
5
+ queue_as :tradebyte
6
+
7
+ def perform(*args)
8
+ products = get_products
9
+ products_xml = parse_products(products)
10
+ if Rails.env.development?
11
+ IO.write('TBCAT.xml', products_xml)
12
+ else
13
+ transport_products(products_xml)
14
+ end
15
+ end
16
+
17
+ def base_taxonomy
18
+ @base_taxonomy ||= Spree::Taxonomy.where(name: SpreeTradebyte.base_taxonomy)
19
+ end
20
+
21
+ def get_products
22
+ @products = Spree::Product.active.includes(:translations, properties: :translations, variants: [option_values: [:translations, option_type: :translations]], classifications: [taxon: [:translations]]).select do |product|
23
+ SpreeTradebyte.channels.any? do |channel|
24
+ [true, 1, '1'].include?(product.send("#{channel}_active"))
25
+ end
26
+ end
27
+ end
28
+
29
+ def parse_products(products)
30
+ Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
31
+ xml.TBCATALOG(version: 1.2) do
32
+ xml.PRODUCTDATA do
33
+ products.map do |product|
34
+ parse_product(xml, product)
35
+ end
36
+ end
37
+ end
38
+ end.to_xml
39
+ end
40
+
41
+ def parse_product(xml, product)
42
+ xml.PRODUCT do
43
+ xml.P_NR product.send(SpreeTradebyte.product_id_method)
44
+ xml.P_ACTIVEDATA do
45
+
46
+ SpreeTradebyte.channels.each do |channel|
47
+ xml.P_ACTIVE(channel: channel) do
48
+ xml.text [true, 1, '1'].include?(product.send("#{channel}_active")) ? 1 : 0
49
+ end
50
+ end
51
+ end
52
+
53
+ xml.P_NAME_KEYWORD do
54
+ xml.VALUE('xml:lang' => 'x-default') do
55
+ xml.text product.meta_keywords.presence || product.name
56
+ end
57
+ if product.respond_to? :translations
58
+ product.translations.each do |product_translation|
59
+ xml.VALUE('xml:lang' => product_translation.locale) do
60
+ xml.text product_translation.meta_keywords
61
+ end if product_translation.meta_keywords.present?
62
+ end
63
+ end
64
+ end
65
+
66
+ xml.P_NAME_PROPER do
67
+ xml.VALUE('xml:lang' => 'x-default') do
68
+ xml.text product.name
69
+ end
70
+ product.translations.each do |product_translation|
71
+ xml.VALUE('xml:lang' => product_translation.locale) do
72
+ xml.text product_translation.name
73
+ end if product_translation.name.present?
74
+ end
75
+ end
76
+
77
+ xml.P_TEXT do
78
+ xml.VALUE('xml:lang' => 'x-default') do
79
+ xml.text ActionView::Base.full_sanitizer.sanitize(product.description)
80
+ end
81
+ if product.respond_to? :translations
82
+ product.translations.each do |product_translation|
83
+ description = ActionView::Base.full_sanitizer.sanitize(product_translation.description)
84
+ xml.VALUE('xml:lang' => product_translation.locale) do
85
+ xml.text description
86
+ end if description.present?
87
+ end
88
+ end
89
+ end
90
+
91
+ xml.P_BRAND(identifier: 'key', key: SpreeTradebyte.brand_name)
92
+
93
+ prefix = 'tb_comp_'
94
+ components = if product.respond_to? :translations
95
+ product.product_properties.joins(property: :translations).where("spree_property_translations.name LIKE '#{prefix}%'")
96
+ else
97
+ product.product_properties.joins(:property).where("spree_properties.name LIKE '#{prefix}%'")
98
+ end
99
+
100
+ xml.P_COMPONENTDATA do
101
+ components.each do |component_property|
102
+ component_key = component_property.property_name.gsub(prefix, '')
103
+ next unless component_key.length
104
+
105
+ xml.P_COMPONENT(identifier: 'key', key: component_key) do
106
+ xml.VALUE('xml:lang' => 'x-default') do
107
+ xml.text component_property.value
108
+ end
109
+ if component_property.respond_to? :translations
110
+ component_property.translations.each do |component_property_translation|
111
+ xml.VALUE('xml:lang' => component_property_translation.locale) do
112
+ xml.text component_property_translation.value
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end if components.any?
119
+
120
+
121
+ prefix = 'tb_tag_'
122
+ tags = if product.respond_to? :translations
123
+ product.product_properties.joins(property: :translations).where("spree_property_translations.name LIKE '#{prefix}%'")
124
+ else
125
+ product.product_properties.joins(:property).where("spree_properties.name LIKE '#{prefix}%'")
126
+ end
127
+
128
+ xml.P_TAGS do
129
+ tags.each do |tag_property|
130
+ tag_key = tag_property.property_name.gsub(prefix, '')
131
+ next unless tag_key.length
132
+
133
+ xml.P_TAG(identifier: 'key', key: tag_key) do
134
+ xml.VALUES do
135
+ xml.VALUE(identifier: 'key', key: tag_property.value)
136
+ end
137
+ end
138
+ end
139
+ end if tags.any?
140
+
141
+
142
+ xml.P_MEDIADATA do
143
+ product.images.each_with_index do |image, index|
144
+ xml.P_MEDIA(sort: index, type: 'image') do
145
+ xml.text URI.join(SpreeTradebyte.host, image.attachment.url(:original))
146
+ end
147
+ end
148
+ end if product.images.any?
149
+
150
+
151
+ taxons = if SpreeTradebyte.use_base_taxonomy
152
+ product.taxons.where(taxonomy: base_taxonomy)
153
+ else
154
+ product.taxons
155
+ end
156
+
157
+ xml.P_CATEGORIES do
158
+ taxons.each do |taxon|
159
+ xml.P_CATEGORY(type: 'cluster', identifier: 'key', key: taxon.id) do
160
+ xml.text taxon.self_and_ancestors.collect(&:name).join('|')
161
+ end
162
+ end
163
+ end if taxons.any?
164
+
165
+ xml.ARTICLEDATA do
166
+ product.variants.map do |variant|
167
+ parse_variant(xml, variant)
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ def parse_variant(xml, variant)
174
+ xml.ARTICLE do
175
+ xml.A_NR variant.id
176
+ xml.A_ACTIVE variant.available? ? 1 : 0
177
+ xml.A_EAN variant.sku
178
+ xml.A_NR2 variant.product&.sku
179
+ xml.A_SORT variant.position
180
+
181
+ xml.A_VARIANTDATA do
182
+ variant.option_values.each do |ov|
183
+ xml.A_VARIANT(identifier: 'key', key: ov.option_type.name) do
184
+ xml.VALUE('xml:lang' => 'x-default') do
185
+ xml.text ov.name
186
+ end
187
+
188
+ if ov.respond_to?(:translations)
189
+ ov.translations.each do |ov_translation|
190
+ xml.VALUE('xml:lang' => ov_translation.locale) do
191
+ xml.text ov_translation.name
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ xml.A_PRICEDATA do
200
+ SpreeTradebyte.channels.each do |channel|
201
+ xml.A_PRICE(channel: channel) do
202
+ xml.A_VK variant.send("#{channel}_a_vk").present? ? variant.send("#{channel}_a_vk") : variant.price
203
+ xml.A_VK_OLD variant.send("#{channel}_a_vk_old") unless variant.send("#{channel}_a_vk_old").blank?
204
+ xml.A_UVP variant.send("#{channel}_a_uvp") unless variant.send("#{channel}_a_uvp").blank?
205
+ xml.A_MWST 2
206
+ end
207
+ end
208
+ end
209
+
210
+ xml.A_MEDIADATA do
211
+ variant.all_images.each_with_index do |image, index|
212
+ xml.A_MEDIA(sort: index, type: 'image') do
213
+ xml.text URI.join(SpreeTradebyte.host, image.attachment.url(:original))
214
+ end
215
+ end
216
+ end
217
+
218
+ xml.A_STOCK variant.total_on_hand
219
+
220
+ xml.A_DELIVERY_TIME (SpreeTradebyte.delivery_time / 1.0.days).ceil
221
+ end
222
+ end
223
+
224
+ def transport_products(products_xml)
225
+ ftp = SpreeTradebyte::TradebyteFTP.new(SpreeTradebyte.ftp_user, SpreeTradebyte.ftp_password, SpreeTradebyte.ftp_server, SpreeTradebyte.ftp_port)
226
+ ftp.put_products_file(products_xml)
227
+ ftp.close
228
+ end
229
+ end