spree_tradebyte 0.1.12.alpha

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.
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