tienda 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75f31e72ee89918573cb2806723fc533734645a9
4
- data.tar.gz: 76d33082565183722512ea4cbfdac5d63243410e
3
+ metadata.gz: b97ea39013c44c15d7d18bce2149a6a07bb2bc18
4
+ data.tar.gz: 816df89676e8e4d64bf1699a23c101e0ea8268ba
5
5
  SHA512:
6
- metadata.gz: 4e37424a4dbce21b3484ebaf1899d709ff4f14b3c9bd8e4444a2b9a3fb0fb47243a77eb8bbd2eb553936e4d0c9696939fba981eef11ba17190fd8ce65bb4185a
7
- data.tar.gz: 04c0e881b1f0e3a417a0d56433802dd51af397f4b5253de5131579962768816ac5bf0a9a13a9c2606d42191a1d859f4ca622cc6588e070d57dcba564045610c1
6
+ metadata.gz: ed72a17c07f45fc268b18f449c13f0ba9586ded6d3c85210ba431ece3e231ffcdcc9d801e429b58bef666d94aa227b5713165baf715110c67b9f7407a00964f6
7
+ data.tar.gz: beea1c4e4b04efe87f531cfe7c6929605741697a3e0e87c3c07509bdf0205dbad9abaef3a60f008542d73304d333500cb5bdef77ee5126f45695230add127784
@@ -39,6 +39,24 @@ $ ->
39
39
  $('a[rel=searchOrders]').on 'click', ->
40
40
  $('div.search-orders').toggleClass('hide')
41
41
 
42
+ # Add a new image to a table
43
+ $('a[data-behavior=addImageToImagesTable]').on 'click', ->
44
+ table = $('table.productImages')
45
+ nextid = table.find('tbody tr:not(.template)').length
46
+ template = $('tr.template', table).html().replace('[]', "[#{nextid}]")
47
+ table.append("<tr>#{template}</tr>")
48
+ false
49
+
50
+ # Remove an image from a table
51
+ $('table.productImages tbody').on 'click', 'tr td.remove a', ->
52
+ row = $(this).closest('tr')
53
+ if row.find('.destroy').length
54
+ row.find('.destroy').val('true')
55
+ row.fadeOut()
56
+ else
57
+ row.remove()
58
+ false
59
+
42
60
  # Add a new attribute to a table
43
61
  $('a[data-behavior=addAttributeToAttributesTable]').on 'click', ->
44
62
  table = $('table.productAttributes')
@@ -409,11 +409,20 @@ line-height: 1.428571429;
409
409
  PRODUCT STYLES
410
410
  ------------------------------------------------*/
411
411
 
412
+ .productImages.table > tbody > tr > td {
413
+ vertical-align: middle;
414
+ }
415
+
416
+ .productImages td.handle,
412
417
  .productAttributes td.handle {
413
418
  background: image-url('tienda/move.svg') no-repeat center;
414
419
  background-size: 16px
415
420
  }
416
421
 
422
+ .productImages .img_preview {
423
+ max-height: 60px;
424
+ }
425
+
417
426
  /*----------------------------------------------
418
427
  ORDER STATUS STYLES
419
428
  ------------------------------------------------*/
@@ -6,9 +6,9 @@ module Tienda
6
6
 
7
7
  def index
8
8
  if params[:filter].blank?
9
- @products = Tienda::Product.root.includes(:stock_level_adjustments, :default_image, :product_category, :variants).order(:name).group_by(&:product_category).sort_by { |cat, pro| cat.name }
9
+ @products = Tienda::Product.root.includes(:stock_level_adjustments, :product_images, :product_category, :variants).order(:name).group_by(&:product_category).sort_by { |cat, pro| cat.name }
10
10
  else
11
- @products = Tienda::Product.root.send(params[:filter]).includes(:stock_level_adjustments, :default_image, :product_category, :variants).order(:name).group_by(&:product_category).sort_by { |cat, pro| cat.name }
11
+ @products = Tienda::Product.root.send(params[:filter]).includes(:stock_level_adjustments, :product_images, :product_category, :variants).order(:name).group_by(&:product_category).sort_by { |cat, pro| cat.name }
12
12
  end
13
13
  end
14
14
 
@@ -60,7 +60,8 @@ module Tienda
60
60
  :tax_rate_id, :stock_control, :default_image_file, :second_image_file,
61
61
  :third_image_file, :fourth_image_file, :fifth_image_file,
62
62
  :data_sheet_file, :active, :featured, :in_the_box,
63
- :product_attributes_array => [:key, :value, :searchable, :public])
63
+ :product_attributes_array => [:key, :value, :searchable, :public],
64
+ :product_images_attributes => [:image, :_destroy, :id])
64
65
  end
65
66
 
66
67
  end
@@ -18,15 +18,16 @@ module Tienda
18
18
  def attachment_preview(attachment, options = {})
19
19
  if attachment
20
20
  String.new.tap do |s|
21
- if attachment.image?
22
- style = "style='background-image:url(#{attachment.path})'"
21
+ if attachment.mounted_as == :image
22
+ style = "style='background-image:url(#{attachment.url})'"
23
23
  else
24
24
  style = ''
25
25
  end
26
- s << "<div class='attachmentPreview #{attachment.image? ? 'image' : 'doc'}'>"
26
+ s << "<div class='attachmentPreview #{attachment.mounted_as == :image ? 'image' : 'doc'}'>"
27
27
  s << "<div class='imgContainer'><div class='img' #{style}></div></div>"
28
28
  s << "<div class='desc'>"
29
- s << "<span class='filename'><a href='#{attachment_path(attachment)}'>#{attachment.file_name}</a></span>"
29
+ s << "<span class='filename'>#{link_to File.basename(attachment.path), attachment.url}</span>"
30
+ # s << "<span class='filename'><a href='#{attachment_path(attachment)}'>#{attachment.file_name}</a></span>"
30
31
  s << "<span class='delete'>"
31
32
  s << link_to(t('helpers.attachment_preview.delete', :default => 'Delete this file?'), attachment_path(attachment), :method => :delete, :data => {:confirm => t('helpers.attachment_preview.delete_confirm', :default => "Are you sure you wish to remove this attachment?")})
32
33
  s << "</span>"
@@ -7,16 +7,9 @@ module Tienda
7
7
  require_dependency 'tienda/product/product_attributes'
8
8
  require_dependency 'tienda/product/variants'
9
9
 
10
- # Products have 5 images and a data_sheet
11
- attachment :default_image
12
- attachment :second_image
13
- attachment :third_image
14
- attachment :fourth_image
15
- attachment :fifth_image
16
- attachment :data_sheet
17
-
18
10
  # To preserve backwards compatibility
19
11
  alias_attribute :stock, :stock_count
12
+ alias_attribute :images, :product_images
20
13
 
21
14
  # The product's category
22
15
  #
@@ -37,6 +30,10 @@ module Tienda
37
30
  # Stock level adjustments for this product
38
31
  has_many :stock_level_adjustments, dependent: :destroy
39
32
 
33
+ # Product Images
34
+ has_many :product_images, dependent: :destroy
35
+ accepts_nested_attributes_for :product_images, reject_if: proc { |attributes| attributes['image'].blank? }, allow_destroy: true
36
+
40
37
  # Validations
41
38
  with_options if: Proc.new { |p| p.parent.nil? } do |product|
42
39
  product.validates :product_category_id, presence: true
@@ -101,13 +98,6 @@ module Tienda
101
98
  self.default_variant ? self.default_variant.in_stock? : (stock_control? ? stock_count > 0 : true)
102
99
  end
103
100
 
104
- # Return all product images
105
- #
106
- # @return [Array]
107
- def images
108
- nifty_attachments.select { |attachment| attachment.role != "data_sheet" }
109
- end
110
-
111
101
  # Return all product categories
112
102
  #
113
103
  # @return [Array]
@@ -1,11 +1,12 @@
1
1
  module Tienda
2
2
  class ProductCategory < ActiveRecord::Base
3
3
 
4
- # Categories have an image attachment
5
- attachment :image
4
+ # Mount Uploader
5
+ mount_uploader :image, CategoryImageUploader
6
6
 
7
7
  # All products within this category
8
8
  has_many :products, dependent: :restrict_with_exception
9
+ has_many :active_featured_root_products, -> { where(active: true, featured: true, parent_id: nil) }, class_name: 'Tienda::Product'
9
10
  # Sub Categories relationships
10
11
  has_many :children, class_name: 'Tienda::ProductCategory', foreign_key: :parent_id
11
12
  belongs_to :parent, class_name: 'Tienda::ProductCategory'
@@ -0,0 +1,9 @@
1
+ module Tienda
2
+ class ProductImage < ActiveRecord::Base
3
+ # Relationships
4
+ belongs_to :product
5
+
6
+ # Mount Uploaders
7
+ mount_uploader :image, ProductImageUploader
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module Tienda
3
+ class CategoryImageUploader < Tienda::ImageUploader
4
+
5
+ end
6
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module Tienda
3
+ class ImageUploader < CarrierWave::Uploader::Base
4
+
5
+ include CarrierWave::MiniMagick
6
+
7
+ storage :aws
8
+
9
+ # Override the directory where uploaded files will be stored.
10
+ # This is a sensible default for uploaders that are meant to be mounted:
11
+ def store_dir
12
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
13
+ end
14
+
15
+ # Provide a default URL as a default if there hasn't been a file uploaded:
16
+ # def default_url
17
+ # # For Rails 3.1+ asset pipeline compatibility:
18
+ # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
19
+ #
20
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
21
+ # end
22
+
23
+ # Process files as they are uploaded:
24
+ # process :scale => [200, 300]
25
+ #
26
+ # def scale(width, height)
27
+ # # do something
28
+ # end
29
+
30
+ # Create different versions of your uploaded files:
31
+ # version :thumb do
32
+ # process :resize_to_fit => [50, 50]
33
+ # end
34
+
35
+ # Add a white list of extensions which are allowed to be uploaded.
36
+ # For images you might use something like this:
37
+ def extension_white_list
38
+ %w(jpg jpeg gif png)
39
+ end
40
+
41
+ # You can find full list of custom headers in AWS SDK documentation on
42
+ # AWS::S3::S3Object
43
+ def download_url(filename)
44
+ url(response_content_disposition: %Q{attachment; filename="#{filename}"})
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module Tienda
3
+ class ProductImageUploader < Tienda::ImageUploader
4
+
5
+ end
6
+ end
@@ -73,45 +73,29 @@
73
73
  .panel-heading
74
74
  = t('tienda.products.attachments')
75
75
  .panel-body
76
- .row
77
- .col-md-6
78
- .form-group
79
- = f.label :default_image_file, t('tienda.products.default_image')
80
- %p= f.file_field :default_image_file, class: 'form-control'
81
- %div
82
- = attachment_preview @product.default_image
83
- .col-md-6
84
- .form-group
85
- = f.label :second_image_file, t('tienda.products.second_image')
86
- %p= f.file_field :second_image_file, class: 'form-control'
87
- %div
88
- = attachment_preview @product.second_image
89
- .row
90
- .col-md-6
91
- .form-group
92
- = f.label :third_image_file, t('tienda.products.third_image')
93
- %p= f.file_field :third_image_file, class: 'form-control'
94
- %div
95
- = attachment_preview @product.third_image
96
- .col-md-6
97
- .form-group
98
- = f.label :fourth_image_file, t('tienda.products.fourth_image')
99
- %p= f.file_field :fourth_image_file, class: 'form-control'
100
- %div
101
- = attachment_preview @product.fourth_image
102
- .row
103
- .col-md-6
104
- .form-group
105
- = f.label :fifth_image_file, t('tienda.products.fifth_image')
106
- %p= f.file_field :fifth_image_file, class: 'form-control'
107
- %div
108
- = attachment_preview @product.fifth_image
109
- .col-md-6
110
- .form-group
111
- = f.label :data_sheet_file, t('tienda.products.datasheet')
112
- %p= f.file_field :data_sheet_file, class: 'form-control'
113
- %div
114
- = attachment_preview @product.data_sheet
76
+ %table.productImages.table.table-hover
77
+ %thead
78
+ %tr
79
+ %th= t('tienda.products.preview')
80
+ %th= t('tienda.products.file_name')
81
+ %th.remove= t('tienda.products.remove')
82
+ %th
83
+ %tbody
84
+ %tr.template{style: 'display:none;'}
85
+ %td= file_field_tag 'product[product_images_attributes][][image]', class: 'form-control'
86
+ %td= t('tienda.products.file_name')
87
+ %td.remove= link_to t('tienda.remove') , '#', class: 'btn btn-sm btn-danger'
88
+ %td
89
+ - @product.product_images.each_with_index do |image, i|
90
+ %tr
91
+ %td= image_tag image.image.url, class: :img_preview
92
+ %td= File.basename(image.image.path)
93
+ %td.remove
94
+ = link_to t("tienda.remove"), '#', class: 'btn btn-sm btn-danger'
95
+ = hidden_field_tag "product[product_images_attributes][#{i}][id]", image.id
96
+ = hidden_field_tag "product[product_images_attributes][#{i}][_destroy]", '', class: 'destroy'
97
+ %td
98
+ %p.addImage= link_to t('tienda.products.add_image') , '#', data: {behavior: 'addImageToImagesTable'}, class: 'btn btn-success btn-sm'
115
99
 
116
100
  .panel.panel-default
117
101
  .panel-heading
@@ -0,0 +1,15 @@
1
+ CarrierWave.configure do |config|
2
+ AWS_CONFIG = Rails.application.secrets.aws_config
3
+
4
+ config.storage = :aws
5
+ config.aws_bucket = AWS_CONFIG['s3_bucket_name']
6
+ config.aws_acl = :'public-read'
7
+ config.asset_host = 'https://cdn.masinfinitocasa.com'
8
+ config.aws_authenticated_url_expiration = 60 * 60 * 24 * 365
9
+
10
+ config.aws_credentials = {
11
+ access_key_id: AWS_CONFIG['s3_key'],
12
+ secret_access_key: AWS_CONFIG['s3_secret'],
13
+ region: AWS_CONFIG['s3_region']
14
+ }
15
+ end
data/config/routes.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  Tienda::Engine.routes.draw do
2
2
 
3
- get 'attachment/:id/:filename.:extension' => 'attachments#show'
4
3
  resources :product_categories
5
4
  resources :products do
6
5
  resources :variants
@@ -0,0 +1,12 @@
1
+ class CreateTiendaProductImages < ActiveRecord::Migration
2
+ def change
3
+ create_table :tienda_product_images do |t|
4
+ t.references :product, index: true
5
+ t.string :image
6
+
7
+ t.timestamps null: false
8
+ end
9
+ add_column :tienda_product_categories, :image, :string
10
+ # add_foreign_key :tienda_product_images, :products
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ class ConvertProductImagesToCarrierwave < ActiveRecord::Migration
2
+ PRODUCT_IMAGE_TYPES = [:default_image, :second_image, :third_image, :fourth_image, :fifth_image]
3
+ def up
4
+ # Product Images
5
+ PRODUCT_IMAGE_TYPES.each do |image_type|
6
+ puts "Converting Product's #{image_type}s"
7
+ sql = "SELECT parent_id, file_name, data FROM nifty_attachments WHERE parent_type = 'Tienda::Product' AND role = '#{image_type}'"
8
+ ActiveRecord::Base.connection.execute(sql).each do |attachment|
9
+ File.open(attachment[1], 'wb') { |f| f.write(attachment[2]) }
10
+ image = Tienda::ProductImage.new
11
+ image.product_id = attachment[0]
12
+ File.open(attachment[1], 'r') { |f| image.image = f }
13
+ image.save
14
+ File.delete(attachment[1])
15
+ end
16
+ end
17
+
18
+ #Product Categories Images
19
+ puts "Converting Product Categoeies' images"
20
+ sql = "SELECT parent_id, file_name, data FROM nifty_attachments WHERE parent_type = 'Tienda::ProductCategory'"
21
+ ActiveRecord::Base.connection.execute(sql).each do |attachment|
22
+ File.open(attachment[1], 'wb') { |f| f.write(attachment[2]) }
23
+ category = Tienda::ProductCategory.find attachment[0]
24
+ File.open(attachment[1], 'r') { |f| category.image = f }
25
+ category.save
26
+ File.delete(attachment[1])
27
+ end
28
+
29
+ drop_table :nifty_attachments
30
+ end
31
+ end
data/lib/tienda.rb CHANGED
@@ -4,10 +4,12 @@ require 'dynamic_form'
4
4
  require 'kaminari'
5
5
  require 'ransack'
6
6
  require 'counter_culture'
7
+ require 'carrierwave'
8
+ require 'carrierwave-aws'
9
+ require 'mini_magick'
7
10
 
8
11
  require 'nifty/utils'
9
12
  require 'nifty/key_value_store'
10
- require 'nifty/attachments'
11
13
 
12
14
  module Tienda
13
15
  class << self
@@ -1,3 +1,3 @@
1
1
  module Tienda
2
- VERSION = '2.0.2'
2
+ VERSION = '2.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tienda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Robaina
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-24 00:00:00.000000000 Z
11
+ date: 2015-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -199,46 +199,54 @@ dependencies:
199
199
  - !ruby/object:Gem::Version
200
200
  version: 0.1.23
201
201
  - !ruby/object:Gem::Dependency
202
- name: nifty-key-value-store
202
+ name: carrierwave
203
203
  requirement: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - ">="
206
206
  - !ruby/object:Gem::Version
207
- version: 1.0.1
208
- - - "<"
209
- - !ruby/object:Gem::Version
210
- version: 2.0.0
207
+ version: 0.10.0
211
208
  type: :runtime
212
209
  prerelease: false
213
210
  version_requirements: !ruby/object:Gem::Requirement
214
211
  requirements:
215
212
  - - ">="
216
213
  - !ruby/object:Gem::Version
217
- version: 1.0.1
218
- - - "<"
214
+ version: 0.10.0
215
+ - !ruby/object:Gem::Dependency
216
+ name: carrierwave-aws
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
219
220
  - !ruby/object:Gem::Version
220
- version: 2.0.0
221
+ version: 0.5.0
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: 0.5.0
221
229
  - !ruby/object:Gem::Dependency
222
- name: nifty-utils
230
+ name: mini_magick
223
231
  requirement: !ruby/object:Gem::Requirement
224
232
  requirements:
225
- - - "~>"
233
+ - - ">="
226
234
  - !ruby/object:Gem::Version
227
- version: '1.0'
235
+ version: 4.2.7
228
236
  type: :runtime
229
237
  prerelease: false
230
238
  version_requirements: !ruby/object:Gem::Requirement
231
239
  requirements:
232
- - - "~>"
240
+ - - ">="
233
241
  - !ruby/object:Gem::Version
234
- version: '1.0'
242
+ version: 4.2.7
235
243
  - !ruby/object:Gem::Dependency
236
- name: nifty-attachments
244
+ name: nifty-key-value-store
237
245
  requirement: !ruby/object:Gem::Requirement
238
246
  requirements:
239
247
  - - ">="
240
248
  - !ruby/object:Gem::Version
241
- version: 1.0.3
249
+ version: 1.0.1
242
250
  - - "<"
243
251
  - !ruby/object:Gem::Version
244
252
  version: 2.0.0
@@ -248,10 +256,24 @@ dependencies:
248
256
  requirements:
249
257
  - - ">="
250
258
  - !ruby/object:Gem::Version
251
- version: 1.0.3
259
+ version: 1.0.1
252
260
  - - "<"
253
261
  - !ruby/object:Gem::Version
254
262
  version: 2.0.0
263
+ - !ruby/object:Gem::Dependency
264
+ name: nifty-utils
265
+ requirement: !ruby/object:Gem::Requirement
266
+ requirements:
267
+ - - "~>"
268
+ - !ruby/object:Gem::Version
269
+ version: '1.0'
270
+ type: :runtime
271
+ prerelease: false
272
+ version_requirements: !ruby/object:Gem::Requirement
273
+ requirements:
274
+ - - "~>"
275
+ - !ruby/object:Gem::Version
276
+ version: '1.0'
255
277
  - !ruby/object:Gem::Dependency
256
278
  name: sqlite3
257
279
  requirement: !ruby/object:Gem::Requirement
@@ -447,10 +469,14 @@ files:
447
469
  - app/models/tienda/product/variants.rb
448
470
  - app/models/tienda/product_attribute.rb
449
471
  - app/models/tienda/product_category.rb
472
+ - app/models/tienda/product_image.rb
450
473
  - app/models/tienda/setting.rb
451
474
  - app/models/tienda/stock_level_adjustment.rb
452
475
  - app/models/tienda/tax_rate.rb
453
476
  - app/models/tienda/user.rb
477
+ - app/uploaders/tienda/category_image_uploader.rb
478
+ - app/uploaders/tienda/image_uploader.rb
479
+ - app/uploaders/tienda/product_image_uploader.rb
454
480
  - app/validators/permalink_validator.rb
455
481
  - app/views/layouts/tienda/application.html.haml
456
482
  - app/views/layouts/tienda/printable.html.haml
@@ -514,6 +540,7 @@ files:
514
540
  - app/views/tienda/variants/form.html.haml
515
541
  - app/views/tienda/variants/index.html.haml
516
542
  - config/initializers/assets.rb
543
+ - config/initializers/carrierwave.rb
517
544
  - config/locales/en.yml
518
545
  - config/locales/pl.yml
519
546
  - config/locales/pt-BR.yml
@@ -525,6 +552,8 @@ files:
525
552
  - db/migrate/20150517212100_update_stock_counter_cache.rb
526
553
  - db/migrate/20150603235417_add_document_to_orders.rb
527
554
  - db/migrate/20150605232554_add_parent_id_to_categories.rb
555
+ - db/migrate/20150626045455_create_tienda_product_images.rb
556
+ - db/migrate/20150628230608_convert_product_images_to_carrierwave.rb
528
557
  - db/seeds.rb
529
558
  - db/seeds_data/poe400.jpg
530
559
  - db/seeds_data/snom-870-blk.jpg