kms_catalog 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/assets/javascripts/kms_catalog/application/controllers/{categories_controller.coffee → categories_controller.coffee.erb} +3 -2
  4. data/app/assets/javascripts/kms_catalog/application/controllers/{products_controller.coffee → products_controller.coffee.erb} +40 -19
  5. data/app/assets/javascripts/kms_catalog/application/controllers/variants_controller.coffee.erb +22 -0
  6. data/app/assets/javascripts/templates/help/catalog_variables.html.slim +2 -2
  7. data/app/assets/javascripts/templates/products/edit.html.slim +36 -23
  8. data/app/assets/javascripts/templates/products/form.html.slim +6 -15
  9. data/app/assets/javascripts/templates/products/index.html.slim +3 -2
  10. data/app/assets/javascripts/templates/products/option_types.html.slim +1 -1
  11. data/app/assets/javascripts/templates/products/properties.html.slim +1 -1
  12. data/app/assets/javascripts/templates/products/variants/index.html.slim +18 -20
  13. data/app/assets/javascripts/templates/products/variants/new.html.slim +3 -5
  14. data/app/controllers/kms/catalog/products_controller.rb +6 -6
  15. data/app/models/kms/master_variant.rb +4 -0
  16. data/app/models/kms/product.rb +18 -3
  17. data/app/serializers/kms/product_serializer.rb +12 -0
  18. data/config/locales/en.yml +5 -2
  19. data/config/locales/ru.yml +5 -2
  20. data/db/migrate/20170112133235_add_type_to_variants.rb +5 -0
  21. data/db/migrate/20170112135659_init_master_variants.rb +15 -0
  22. data/db/migrate/20170112140822_drop_redundant_columns_from_products.rb +7 -0
  23. data/lib/{kms/drops → drops/kms}/category_drop.rb +0 -0
  24. data/lib/drops/kms/master_variant_drop.rb +14 -0
  25. data/lib/{kms/drops → drops/kms}/product_drop.rb +3 -7
  26. data/lib/{kms/drops → drops/kms}/property_drop.rb +0 -0
  27. data/lib/{kms/drops → drops/kms}/variant_drop.rb +1 -1
  28. data/lib/kms/catalog/engine.rb +4 -0
  29. data/lib/kms/catalog/version.rb +1 -1
  30. data/spec/factories/variants.rb +5 -0
  31. data/spec/internal/Rakefile +2 -0
  32. data/spec/internal/config/database.yml +3 -0
  33. data/spec/internal/config/routes.rb +3 -0
  34. data/spec/internal/db/schema.rb +3 -0
  35. data/{test/dummy → spec/internal}/public/favicon.ico +0 -0
  36. data/spec/spec_helper.rb +22 -0
  37. metadata +58 -126
  38. data/app/assets/javascripts/kms_catalog/application/controllers/variants_controller.coffee +0 -45
  39. data/test/catalog_test.rb +0 -7
  40. data/test/dummy/README.rdoc +0 -28
  41. data/test/dummy/Rakefile +0 -6
  42. data/test/dummy/app/assets/javascripts/application.js +0 -13
  43. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  44. data/test/dummy/app/controllers/application_controller.rb +0 -5
  45. data/test/dummy/app/helpers/application_helper.rb +0 -2
  46. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  47. data/test/dummy/bin/bundle +0 -3
  48. data/test/dummy/bin/rails +0 -4
  49. data/test/dummy/bin/rake +0 -4
  50. data/test/dummy/bin/setup +0 -29
  51. data/test/dummy/config.ru +0 -4
  52. data/test/dummy/config/application.rb +0 -26
  53. data/test/dummy/config/boot.rb +0 -5
  54. data/test/dummy/config/database.yml +0 -25
  55. data/test/dummy/config/environment.rb +0 -5
  56. data/test/dummy/config/environments/development.rb +0 -41
  57. data/test/dummy/config/environments/production.rb +0 -77
  58. data/test/dummy/config/environments/test.rb +0 -42
  59. data/test/dummy/config/initializers/assets.rb +0 -11
  60. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  61. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  62. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  63. data/test/dummy/config/initializers/inflections.rb +0 -16
  64. data/test/dummy/config/initializers/mime_types.rb +0 -4
  65. data/test/dummy/config/initializers/session_store.rb +0 -3
  66. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  67. data/test/dummy/config/locales/en.yml +0 -23
  68. data/test/dummy/config/routes.rb +0 -56
  69. data/test/dummy/config/secrets.yml +0 -22
  70. data/test/dummy/public/404.html +0 -67
  71. data/test/dummy/public/422.html +0 -67
  72. data/test/dummy/public/500.html +0 -66
  73. data/test/fixtures/categories.yml +0 -7
  74. data/test/fixtures/option_types.yml +0 -9
  75. data/test/fixtures/option_values.yml +0 -9
  76. data/test/fixtures/product_option_types.yml +0 -9
  77. data/test/fixtures/products.yml +0 -11
  78. data/test/fixtures/properties.yml +0 -11
  79. data/test/fixtures/variants.yml +0 -9
  80. data/test/integration/navigation_test.rb +0 -10
  81. data/test/models/category_test.rb +0 -7
  82. data/test/models/option_type_test.rb +0 -7
  83. data/test/models/option_value_test.rb +0 -7
  84. data/test/models/product_option_type_test.rb +0 -7
  85. data/test/models/product_test.rb +0 -7
  86. data/test/models/property_test.rb +0 -7
  87. data/test/models/variant_test.rb +0 -7
  88. data/test/test_helper.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30844053e11e92d563963fdcf876d6b5991e3ebc
4
- data.tar.gz: ed2c7a1f0f173c3a532b5de4196dadd9d51e43cd
3
+ metadata.gz: bbc6c9f51c47706cbd71b70f2b07e07a0e310a01
4
+ data.tar.gz: 15f1d98997ec84183977eb33a7c5868bec10fb71
5
5
  SHA512:
6
- metadata.gz: fc6ca4ea3068bbe3f938b956e44ce6ba2ad16ceccc7d530ee8f2ef8d6179bf055fb8f69cc8cc071c2a2bb0ba2a93db00f45cbe521099ee405ea653ad1a7b8b6a
7
- data.tar.gz: e9bed74cee7b334e6b767a9fdd4e6181407d76406db1bfbb3314733d007887fd8de7e9718e6dd0580b3326be4ac476e2dd1eab4e61749e550e817aec487eb677
6
+ metadata.gz: cbe098bd66fada4ab904a9b9586573bb3b4c164ef8a581d388458c7dd873dd071a153bcd1d9c59b2636d47f81e8942cb4d3e5fcb1ea8ba207c6849b554539b2c
7
+ data.tar.gz: de4d05ceead4bf13859a6c724a959cfe6ef13078dc29a8720d1d0971069472dce06c5c92c12b4a9ca5a1d711fc96c282a6f3c56bbbe71a4addeaea671ba10567
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path("../spec/internal/Rakefile", __FILE__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
 
@@ -54,8 +54,9 @@ CategoriesController = ($scope, $state, $cookieStore, Restangular, $stateParams)
54
54
  console.log('bug')
55
55
 
56
56
  $scope.destroy = (category)->
57
- category.remove().then ->
58
- $scope.categories = _.without($scope.categories, category)
57
+ if(confirm('<%= I18n.t(:are_you_sure) %>'))
58
+ category.remove().then ->
59
+ $scope.categories = _.without($scope.categories, category)
59
60
 
60
61
 
61
62
 
@@ -1,4 +1,4 @@
1
- ProductsController = ($scope, $state, $cookieStore, Restangular, $stateParams) ->
1
+ ProductsController = ($scope, $state, $cookieStore, Restangular, $stateParams, Alertify, ErrorsService) ->
2
2
  $scope.editorOptions =
3
3
  filebrowserUploadUrl: '/assets/ckeditor'
4
4
 
@@ -13,12 +13,16 @@ ProductsController = ($scope, $state, $cookieStore, Restangular, $stateParams) -
13
13
  $scope.store.getList().then (products)->
14
14
  $scope.products = products
15
15
 
16
+
16
17
  if $stateParams.id
18
+ $scope.variantsStore = Restangular.one('products', $stateParams.id).all('variants')
17
19
  $scope.store.get($stateParams.id).then (product)->
18
20
  $scope.product = product
19
21
  else
20
22
  $scope.product = {category_ids: []}
21
23
 
24
+ $scope.variant = {}
25
+
22
26
  $scope.addCat = (item, model) ->
23
27
  index = $scope.product.category_ids.indexOf(item.id)
24
28
  unless index > -1
@@ -32,39 +36,56 @@ ProductsController = ($scope, $state, $cookieStore, Restangular, $stateParams) -
32
36
  fd = new FormData
33
37
  fd.append('product[name]', $scope.product.name || '')
34
38
  fd.append('product[description]', $scope.product.description || '')
35
- fd.append('product[price]', $scope.product.price || '')
39
+ fd.append('product[master_attributes][price]', $scope.product.master.price || '')
36
40
  fd.append('product[category_ids]', $scope.product.category_ids)
37
- fd.append('product[image]', $scope.product.image)
38
- fd.append('product[preview_image]', $scope.product.preview_image)
41
+ fd.append('product[master_attributes][image]', $scope.product.master.image)
39
42
  fd.append('product[seo_title]', $scope.product.seo_title || '')
40
43
  fd.append('product[seo_keywords]', $scope.product.seo_keywords || '')
41
44
  fd.append('product[seo_description]', $scope.product.seo_description || '')
42
- $scope.store.withHttpConfig({ transformRequest: angular.identity }).post(fd, null, {"Content-Type": undefined}).then ->
43
- $state.go('products')
44
- ,->
45
- console.log('bug')
45
+ $scope.store.withHttpConfig({ transformRequest: angular.identity }).post(fd, null, {"Content-Type": undefined}).then (product)->
46
+ $scope.product = product
47
+ $state.go('products.edit', {id: $scope.product.id })
48
+ ,(response)->
49
+ Alertify.error(ErrorsService.prepareErrorsString(response.data.errors))
46
50
 
47
51
  $scope.update = ->
48
52
  fd = new FormData
49
53
  fd.append('product[name]', $scope.product.name || '')
50
54
  fd.append('product[description]', $scope.product.description || '')
51
- fd.append('product[price]', $scope.product.price || '')
55
+ fd.append('product[master_attributes][id]', $scope.product.master.id || '')
56
+ fd.append('product[master_attributes][price]', $scope.product.master.price || '')
52
57
  fd.append('product[category_ids]', $scope.product.category_ids)
53
58
  fd.append('product[seo_title]', $scope.product.seo_title || '')
54
59
  fd.append('product[seo_keywords]', $scope.product.seo_keywords || '')
55
60
  fd.append('product[seo_description]', $scope.product.seo_description || '')
56
- if $scope.product.image.constructor.name == "File"
57
- fd.append('product[image]', $scope.product.image)
58
- if $scope.product.preview_image.constructor.name == "File"
59
- fd.append('product[preview_image]', $scope.product.preview_image)
61
+ if $scope.product.master.image.constructor.name == "File"
62
+ fd.append('product[master_attributes][image]', $scope.product.master.image)
60
63
  $scope.product.withHttpConfig({ transformRequest: angular.identity }).post('', fd, '', {"Content-Type": undefined}).then ->
61
- $state.go('products')
62
- ,->
63
- console.log('bug')
64
+ $state.go('products.edit')
65
+ ,(response)->
66
+ Alertify.error(ErrorsService.prepareErrorsString(response.data.errors))
67
+
68
+ $scope.createVariant = ->
69
+ fd = new FormData
70
+ fd.append('variant[name]', $scope.variant.name || '')
71
+ fd.append('variant[price]', $scope.variant.price || '')
72
+ fd.append('variant[image]', $scope.variant.image)
73
+ $scope.variantsStore.withHttpConfig({ transformRequest: angular.identity }).post(fd, null, {"Content-Type": undefined}).then (variant)->
74
+ $scope.variant = {}
75
+ $scope.product.variants.push(variant)
76
+ ,(response)->
77
+ Alertify.error(ErrorsService.prepareErrorsString(response.data.errors))
78
+
79
+ $scope.destroyVariant = (variant)->
80
+ if(confirm('<%= I18n.t(:are_you_sure) %>'))
81
+ restangular_variant = Restangular.restangularizeElement($scope.product, variant, 'variants')
82
+ restangular_variant.remove().then ->
83
+ $scope.product.variants = _.without($scope.product.variants, variant)
64
84
 
65
85
  $scope.destroy = (product)->
66
- product.remove().then ->
67
- $scope.products = _.without($scope.products, product)
86
+ if(confirm('<%= I18n.t(:are_you_sure) %>'))
87
+ product.remove().then ->
88
+ $scope.products = _.without($scope.products, product)
68
89
 
69
90
  $scope.exceptCurrentCategory = ->
70
91
  new_products = []
@@ -74,4 +95,4 @@ ProductsController = ($scope, $state, $cookieStore, Restangular, $stateParams) -
74
95
 
75
96
 
76
97
  angular.module('KMS')
77
- .controller('ProductsController', ['$scope', '$state', '$cookieStore', 'Restangular', '$stateParams', ProductsController])
98
+ .controller('ProductsController', ['$scope', '$state', '$cookieStore', 'Restangular', '$stateParams', 'Alertify', 'ErrorsService', ProductsController])
@@ -0,0 +1,22 @@
1
+ VariantsController = ($scope, $state, $cookieStore, Restangular, $stateParams, Alertify, ErrorsService) ->
2
+ $scope.store = Restangular.one('products', $stateParams.product_id).all('variants')
3
+ # $scope.store.getList().then (variants) ->
4
+ # $scope.variants = variants#_.groupBy(option_types, 'tag')
5
+
6
+ $scope.store.get($stateParams.id).then (variant)->
7
+ $scope.variant = variant
8
+
9
+ $scope.update = ->
10
+ fd = new FormData
11
+ fd.append('variant[name]', $scope.variant.name || '')
12
+ fd.append('variant[price]', $scope.variant.price || '')
13
+ if $scope.variant.image.constructor.name == "File"
14
+ fd.append('variant[image]', $scope.variant.image)
15
+ $scope.variant.withHttpConfig({ transformRequest: angular.identity }).post('', fd, '', {"Content-Type": undefined}).then ->
16
+ $state.go('products.edit', {id: $scope.variant.product_id})
17
+ ,(response)->
18
+ Alertify.error(ErrorsService.prepareErrorsString(response.data.errors))
19
+
20
+
21
+ angular.module('KMS')
22
+ .controller('VariantsController', ['$scope', '$state', '$cookieStore', 'Restangular', '$stateParams', 'Alertify', 'ErrorsService', VariantsController])
@@ -11,7 +11,7 @@ p
11
11
  p
12
12
  table.table
13
13
  tr
14
- th #{ I18n.t('liquor_help.properties') } Category
14
+ th #{ I18n.t('liquor_help.property') } Category
15
15
  th = I18n.t('liquor_help.description')
16
16
  tr
17
17
  td name
@@ -44,7 +44,7 @@ p
44
44
  p
45
45
  table.table
46
46
  tr
47
- th #{ I18n.t('liquor_help.properties') } Product
47
+ th #{ I18n.t('liquor_help.property') } Product
48
48
  th = I18n.t('liquor_help.description')
49
49
  tr
50
50
  td name
@@ -1,25 +1,38 @@
1
1
  .row
2
2
  .col-lg-12
3
- form role="form" ng-submit="update()"
4
- ng-include src="'products/form.html'"
5
- button.btn.btn-default type="submit" = I18n.t(:update_product)
6
- .row
7
- .col-lg-12
8
- a.btn.btn-default ui-sref="variants({product_id: product.id})"
9
- = Kms::Variant.model_name.human(count: 1.1)
10
- accordion close-others="true"
11
- ng-include src="'products/properties.html'"
12
- ng-include src="'products/option_types.html'"
13
- accordion-group is-open="status.open"
14
- accordion-heading
15
- i.pull-left.glyphicon ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"
16
- | &nbsp;SEO
17
- .form-group
18
- label for="seo_title" = Kms::Product.human_attribute_name(:seo_title)
19
- input#seo_title.form-control type="text" ng-model="product.seo_title"
20
- .form-group
21
- label for="seo_keywords" = Kms::Product.human_attribute_name(:seo_keywords)
22
- input#seo_keywords.form-control type="text" ng-model="product.seo_keywords"
23
- .form-group
24
- label for="seo_description" = Kms::Product.human_attribute_name(:seo_description)
25
- input#seo_description.form-control type="text" ng-model="product.seo_description"
3
+ tabset
4
+ tab
5
+ tab-heading
6
+ i.fa.fa-barcode
7
+ | &nbsp;{{ product.name }}
8
+ .widget style="background-color: #f3f3f3;"
9
+ .widget-body
10
+ .row
11
+ .col-lg-12
12
+ form role="form" ng-submit="update()"
13
+ ng-include src="'products/form.html'"
14
+ button.btn.btn-default type="submit" = I18n.t(:update_product)
15
+ accordion close-others="true"
16
+ ng-include src="'products/properties.html'"
17
+ ng-include src="'products/option_types.html'"
18
+ accordion-group is-open="status.open"
19
+ accordion-heading
20
+ i.pull-left.glyphicon ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"
21
+ | &nbsp;SEO
22
+ .form-group
23
+ label for="seo_title" = Kms::Product.human_attribute_name(:seo_title)
24
+ input#seo_title.form-control type="text" ng-model="product.seo_title"
25
+ .form-group
26
+ label for="seo_keywords" = Kms::Product.human_attribute_name(:seo_keywords)
27
+ input#seo_keywords.form-control type="text" ng-model="product.seo_keywords"
28
+ .form-group
29
+ label for="seo_description" = Kms::Product.human_attribute_name(:seo_description)
30
+ input#seo_description.form-control type="text" ng-model="product.seo_description"
31
+ tab
32
+ tab-heading
33
+ i.fa.fa-plus
34
+ | &nbsp;
35
+ = Kms::Variant.model_name.human(count: 1.1)
36
+ .widget
37
+ .widget-body
38
+ ng-include src="'products/variants/index.html'"
@@ -6,29 +6,20 @@
6
6
  textarea#description.form-control ng-model="product.description" rows="15" ng-if="currentUser.admin" ui-codemirror="{lineNumbers: true, mode:'htmlmixed'}"
7
7
  textarea#description.form-control ng-model="product.description" rows="15" ng-if="!currentUser.admin" ckeditor='editorOptions'
8
8
  .form-group
9
- label for="price" = Kms::Product.human_attribute_name(:price)
10
- input#price.form-control type="text" ng-model="product.price"
9
+ label for="price" = Kms::Variant.human_attribute_name(:price)
10
+ input#price.form-control type="text" ng-model="product.master.price"
11
11
  .form-group
12
12
  label for="category_ids" = Kms::Product.human_attribute_name(:categories)
13
- /select#categories_ids.form-control.ui-select-multiple ng-model="category.categories_ids" ng-options="category.id as category.name for category in categories" required=""
14
13
  ui-select multiple="" ng-model="product.category_ids" theme="bootstrap" on-select="addCat($item, $model)" on-remove='removeCat($item, $model)'
15
14
  ui-select-match placeholder="Выберите категории..."
16
15
  | {{$item.name}}
17
16
  ui-select-choices repeat="category.id as category in categories"
18
17
  div ng-bind-html="category.name | highlight: $select.search"
19
18
  .form-group
20
- label for="image" = Kms::Product.human_attribute_name(:image)
21
- div flow-init="{singleFile: true, headers: setHeaders, fileParameterName: 'product[image]'}" flow-files-submitted="product.image = $flow.files[0].file" flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]" flow-file-success="$file.msg = $message"
22
- input type="file" flow-btn="" ng-model='product.image'
19
+ label for="image" = Kms::Variant.human_attribute_name(:image)
20
+ div flow-init="{singleFile: true, headers: setHeaders, fileParameterName: 'product[master][image]'}" flow-files-submitted="product.master.image = $flow.files[0].file" flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]" flow-file-success="$file.msg = $message"
21
+ input type="file" flow-btn="" ng-model='product.master.image'
23
22
  div class="thumbnail" ng-show="!$flow.files.length"
24
- img ng-src="{{product.image.url}}"
25
- div class="thumbnail" ng-show="$flow.files.length"
26
- img flow-img="$flow.files[0]"
27
- .form-group
28
- label for="preview_image" = Kms::Product.human_attribute_name(:preview_image)
29
- div flow-init="{singleFile: true, headers: setHeaders, fileParameterName: 'product[preview_image]'}" flow-files-submitted="product.preview_image = $flow.files[0].file" flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]" flow-file-success="$file.msg = $message"
30
- input type="file" flow-btn="" ng-model='product.preview_image'
31
- div class="thumbnail" ng-show="!$flow.files.length"
32
- img ng-src="{{product.preview_image.url}}"
23
+ img ng-src="{{product.master.image.url}}"
33
24
  div class="thumbnail" ng-show="$flow.files.length"
34
25
  img flow-img="$flow.files[0]"
@@ -4,7 +4,6 @@
4
4
  .widget-header
5
5
  i.fa.fa-barcode
6
6
  = Kms::Product.model_name.human(count: 1.1)
7
- /a.pull-right href="#" Manage
8
7
  a.btn.btn-sm.btn-primary.pull-right ui-sref="products.new"
9
8
  = I18n.t("add_product")
10
9
  .widget-body.no-padding
@@ -12,8 +11,10 @@
12
11
  table.table
13
12
  tbody
14
13
  tr ng-repeat="product in products"
15
- td style="width: 80%"
14
+ td style="width: 70%"
16
15
  | {{ product.name }}
16
+ td style="width: 20%"
17
+ | {{ product.master.price }}
17
18
  td
18
19
  .btn-group.pull-right
19
20
  a.btn.btn-sm.btn-info ui-sref="products.edit({id: product.id})"
@@ -33,7 +33,7 @@ accordion-group is-open="status.open"
33
33
  .form-group
34
34
  label for="tag" = Kms::OptionType.human_attribute_name(:tag)
35
35
  .row
36
- .col-lg-6
36
+ .col-lg-6 style="padding-left:0"
37
37
  input#tag.form-control type="text" ng-model="option_type.tag" placeholder=I18n.t(:type_group_name_for_options_placeholder)
38
38
  .col-lg-6
39
39
  ui-select ng-model='option_type.tag'
@@ -35,7 +35,7 @@ accordion-group is-open="status.open"
35
35
  .form-group
36
36
  label for="tag" = Kms::Property.human_attribute_name(:tag)
37
37
  .row
38
- .col-lg-6
38
+ .col-lg-6 style="padding-left:0"
39
39
  input#tag.form-control type="text" ng-model="property.tag" placeholder=I18n.t(:type_group_name_for_properties_placeholder)
40
40
  .col-lg-6
41
41
  ui-select ng-model='property.tag'
@@ -1,22 +1,20 @@
1
1
  .row
2
2
  .col-lg-12
3
- .widget
4
- .widget-header
5
- i.fa.fa-barcode
6
- = Kms::Variant.model_name.human(count: 1.1)
7
- /a.pull-right href="#" Manage
8
- a.btn.btn-sm.btn-primary.pull-right ui-sref="variants.new"
9
- = I18n.t("add_variant")
10
- .widget-body.no-padding
11
- .table-responsive
12
- table.table
13
- tbody
14
- tr ng-repeat="variant in variants"
15
- td style="width: 80%"
16
- | {{ variant.name }}
17
- td
18
- .btn-group.pull-right
19
- a.btn.btn-sm.btn-info ui-sref="variants.edit({id: variant.id})"
20
- i.fa.fa-pencil
21
- a.btn.btn-sm.btn-danger ng-click="destroy(variant)"
22
- i.fa.fa-times
3
+ ng-include src="'products/variants/new.html'"
4
+ .col-lg-12
5
+ .table-responsive
6
+ table.table
7
+ tbody
8
+ tr ng-repeat="variant in product.variants"
9
+ td style="width: 10%"
10
+ img.img-responsive ng-src="{{ variant.image.url }}"
11
+ td style="width: 70%"
12
+ | {{ variant.name }}
13
+ td style="width: 10%"
14
+ | {{ variant.price }}
15
+ td
16
+ .btn-group.pull-right
17
+ a.btn.btn-sm.btn-info ui-sref="variants.edit({product_id: product.id, id: variant.id})"
18
+ i.fa.fa-pencil
19
+ a.btn.btn-sm.btn-danger ng-click="destroyVariant(variant)"
20
+ i.fa.fa-times
@@ -1,5 +1,3 @@
1
- .row
2
- .col-lg-12
3
- form role="form" ng-submit="create()"
4
- ng-include src="'products/variants/form.html'"
5
- button.btn.btn-default type="submit" = I18n.t(:add_variant)
1
+ form role="form" ng-submit="createVariant()"
2
+ ng-include src="'products/variants/form.html'"
3
+ button.btn.btn-default type="submit" = I18n.t(:add_variant)
@@ -2,38 +2,38 @@ module Kms
2
2
  module Catalog
3
3
  class ProductsController < ApplicationController
4
4
  def index
5
- render json: Product.order(:name).to_json
5
+ render json: Product.order(:name)
6
6
  end
7
7
 
8
8
  def create
9
9
  product_params[:category_ids] = product_params[:category_ids].split(',') if product_params[:category_ids]
10
10
  @product = Product.new(product_params)
11
11
  @product.save
12
- render json: @product.to_json
12
+ render json: @product
13
13
  end
14
14
 
15
15
  def update
16
16
  product_params[:category_ids] = product_params[:category_ids].split(',') if product_params[:category_ids]
17
17
  @product = Product.find(params[:id])
18
18
  @product.update_attributes(product_params)
19
- render json: @product.to_json
19
+ render json: @product
20
20
  end
21
21
 
22
22
  def show
23
23
  @product = Product.find(params[:id])
24
- render json: @product.to_json(methods: :category_ids, include: :properties)
24
+ render json: @product
25
25
  end
26
26
 
27
27
  def destroy
28
28
  @product = Product.find(params[:id])
29
29
  @product.destroy
30
- render json: @product.to_json
30
+ render json: @product
31
31
  end
32
32
 
33
33
  protected
34
34
 
35
35
  def product_params
36
- params.require(:product).permit!
36
+ params.require(:product).permit(:name, :description, :category_ids, :seo_title, :seo_keywords, :seo_description, master_attributes: [:price, :image, :id])
37
37
  end
38
38
  end
39
39
  end
@@ -0,0 +1,4 @@
1
+ module Kms
2
+ class MasterVariant < Variant
3
+ end
4
+ end
@@ -10,11 +10,26 @@ module Kms
10
10
  has_many :product_option_types, dependent: :destroy
11
11
  has_many :option_types, through: :product_option_types
12
12
 
13
- has_many :variants, dependent: :destroy
13
+ has_many :variants,
14
+ -> { where(type: Kms::Variant.name) },
15
+ class_name: 'Kms::Variant', dependent: :destroy
16
+
17
+ has_one :master, class_name: 'Kms::MasterVariant', dependent: :destroy
14
18
 
15
19
  friendly_id :name, use: :slugged
16
20
 
17
- mount_uploader :image, ProductImageUploader
18
- mount_uploader :preview_image, ProductImageUploader
21
+ # mount_uploader :image, ProductImageUploader
22
+ # mount_uploader :preview_image, ProductImageUploader
23
+
24
+ accepts_nested_attributes_for :master
25
+
26
+ after_initialize :init_master
27
+
28
+ protected
29
+
30
+ def init_master
31
+ return unless new_record?
32
+ self.master ||= build_master
33
+ end
19
34
  end
20
35
  end