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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/app/assets/javascripts/kms_catalog/application/controllers/{categories_controller.coffee → categories_controller.coffee.erb} +3 -2
- data/app/assets/javascripts/kms_catalog/application/controllers/{products_controller.coffee → products_controller.coffee.erb} +40 -19
- data/app/assets/javascripts/kms_catalog/application/controllers/variants_controller.coffee.erb +22 -0
- data/app/assets/javascripts/templates/help/catalog_variables.html.slim +2 -2
- data/app/assets/javascripts/templates/products/edit.html.slim +36 -23
- data/app/assets/javascripts/templates/products/form.html.slim +6 -15
- data/app/assets/javascripts/templates/products/index.html.slim +3 -2
- data/app/assets/javascripts/templates/products/option_types.html.slim +1 -1
- data/app/assets/javascripts/templates/products/properties.html.slim +1 -1
- data/app/assets/javascripts/templates/products/variants/index.html.slim +18 -20
- data/app/assets/javascripts/templates/products/variants/new.html.slim +3 -5
- data/app/controllers/kms/catalog/products_controller.rb +6 -6
- data/app/models/kms/master_variant.rb +4 -0
- data/app/models/kms/product.rb +18 -3
- data/app/serializers/kms/product_serializer.rb +12 -0
- data/config/locales/en.yml +5 -2
- data/config/locales/ru.yml +5 -2
- data/db/migrate/20170112133235_add_type_to_variants.rb +5 -0
- data/db/migrate/20170112135659_init_master_variants.rb +15 -0
- data/db/migrate/20170112140822_drop_redundant_columns_from_products.rb +7 -0
- data/lib/{kms/drops → drops/kms}/category_drop.rb +0 -0
- data/lib/drops/kms/master_variant_drop.rb +14 -0
- data/lib/{kms/drops → drops/kms}/product_drop.rb +3 -7
- data/lib/{kms/drops → drops/kms}/property_drop.rb +0 -0
- data/lib/{kms/drops → drops/kms}/variant_drop.rb +1 -1
- data/lib/kms/catalog/engine.rb +4 -0
- data/lib/kms/catalog/version.rb +1 -1
- data/spec/factories/variants.rb +5 -0
- data/spec/internal/Rakefile +2 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +3 -0
- data/{test/dummy → spec/internal}/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +22 -0
- metadata +58 -126
- data/app/assets/javascripts/kms_catalog/application/controllers/variants_controller.coffee +0 -45
- data/test/catalog_test.rb +0 -7
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/bin/setup +0 -29
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -26
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -41
- data/test/dummy/config/environments/production.rb +0 -77
- data/test/dummy/config/environments/test.rb +0 -42
- data/test/dummy/config/initializers/assets.rb +0 -11
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -56
- data/test/dummy/config/secrets.yml +0 -22
- data/test/dummy/public/404.html +0 -67
- data/test/dummy/public/422.html +0 -67
- data/test/dummy/public/500.html +0 -66
- data/test/fixtures/categories.yml +0 -7
- data/test/fixtures/option_types.yml +0 -9
- data/test/fixtures/option_values.yml +0 -9
- data/test/fixtures/product_option_types.yml +0 -9
- data/test/fixtures/products.yml +0 -11
- data/test/fixtures/properties.yml +0 -11
- data/test/fixtures/variants.yml +0 -9
- data/test/integration/navigation_test.rb +0 -10
- data/test/models/category_test.rb +0 -7
- data/test/models/option_type_test.rb +0 -7
- data/test/models/option_value_test.rb +0 -7
- data/test/models/product_option_type_test.rb +0 -7
- data/test/models/product_test.rb +0 -7
- data/test/models/property_test.rb +0 -7
- data/test/models/variant_test.rb +0 -7
- data/test/test_helper.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbc6c9f51c47706cbd71b70f2b07e07a0e310a01
|
4
|
+
data.tar.gz: 15f1d98997ec84183977eb33a7c5868bec10fb71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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("../
|
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
|
-
|
58
|
-
|
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
|
-
$
|
44
|
-
|
45
|
-
|
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[
|
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
|
-
|
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
|
-
|
67
|
-
|
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])
|
data/app/assets/javascripts/kms_catalog/application/controllers/variants_controller.coffee.erb
ADDED
@@ -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.
|
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.
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
3
|
+
tabset
|
4
|
+
tab
|
5
|
+
tab-heading
|
6
|
+
i.fa.fa-barcode
|
7
|
+
| {{ 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
|
+
| 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
|
+
|
|
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::
|
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::
|
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:
|
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
|
-
.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
.
|
19
|
-
|
20
|
-
|
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
|
-
|
2
|
-
.
|
3
|
-
|
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)
|
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
|
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
|
19
|
+
render json: @product
|
20
20
|
end
|
21
21
|
|
22
22
|
def show
|
23
23
|
@product = Product.find(params[:id])
|
24
|
-
render json: @product
|
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
|
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
|
data/app/models/kms/product.rb
CHANGED
@@ -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,
|
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
|