From 924128098bb7ccfc9eb829b74c72e1abdcfc056e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 16:27:49 +1000 Subject: [PATCH 001/139] Restricting shipping methods --- app/views/checkout/_order.rabl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/checkout/_order.rabl b/app/views/checkout/_order.rabl index 9903795493..36e5a98eed 100644 --- a/app/views/checkout/_order.rabl +++ b/app/views/checkout/_order.rabl @@ -18,8 +18,8 @@ child current_order.ship_address => :ship_address do end node :shipping_methods do - Hash[current_order.distributor.shipping_methods.collect { - |method| [method.id, { + Hash[current_order.available_shipping_methods("front_end").collect { |method| + [method.id, { require_ship_address: method.require_ship_address, price: method.compute_amount(current_order).to_f, name: method.name From 3ce196e042687af719d948a23696702089f5832e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 13 May 2014 12:16:43 +1000 Subject: [PATCH 002/139] Starting on the new shop --- app/views/shop/_products.html.haml | 129 ++++++++++++++++------------- 1 file changed, 72 insertions(+), 57 deletions(-) diff --git a/app/views/shop/_products.html.haml b/app/views/shop/_products.html.haml index 7ed6606717..7fa562acdf 100644 --- a/app/views/shop/_products.html.haml +++ b/app/views/shop/_products.html.haml @@ -6,73 +6,88 @@ %input#search.text{"ng-model" => "query", placeholder: "Search", "ng-debounce" => "150", - "ng-keypress" => "searchKeypress($event)"} + "ofn-disable-enter" => true} %input.button.right{type: :submit, value: "Add to Cart"} - %table - %thead - %th.name Item - %th.notes Notes - %th.variant Unit - %th.quantity QTY - %th.bulk Bulk - %th.price.text-right Price - %tbody{"ng-show" => "data.loading"} - %tr - %td{colspan: 6} - %h3.text-center Loading Products - %tbody{"ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} - %tr{"class" => "product product-{{ product.id }}"} + .row + .small-12.columns + .product_table + %product.row{"ng-controller" => "ProductNodeCtrl", + "ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} - %td.name{bindonce: "product"} - %img{"bo-src" => "product.master.images[0].small_url"} - %div - %h5 - {{ product.name }} - %a{"data-reveal-id" => "producer_details_{{product.supplier.id}}", "data-reveal" => ""} - {{ product.supplier.name }} + = render partial: "shop/product_summary" + + .row{bindonce: true, "ng-if" => "hasVariants()"} + = render partial: "shop/product_variants" - %td.notes{bindonce: ""} {{ product.notes | truncate:80 }} + .row{bindonce: true, "ng-if" => "!hasVariants()"} + = render partial: "shop/product_master" - %td{bindonce: ""} - %span{"ng-hide" => "product.variants.length > 0"} {{ product.master.options_text }} - %span{"ng-show" => "product.variants.length > 0"} - %img.collapse{src: "/assets/collapse.png", - "ng-show" => "product.show_variants", - "ng-click" => "product.show_variants = !product.show_variants"} - %img.expand{src: "/assets/expand.png", - "ng-show" => "!product.show_variants", - "ng-click" => "product.show_variants = !product.show_variants"} - %td - %span{"ng-show" => "(product.variants.length == 0)"} - %input{type: :number, - value: nil, - min: 0, - "ofn-disable-scroll" => true, - max: "{{product.on_demand && 9999 || product.count_on_hand }}", - name: "variants[{{product.master.id}}]", - id: "variants_{{product.master.id}}", - "ng-model" => "product.quantity"} + -#%table + -#%thead + -#%th.name Item + -#%th.notes Notes + -#%th.variant Unit + -#%th.quantity QTY + -#%th.bulk Bulk + -#%th.price.text-right Price + -#%tbody{"ng-show" => "data.loading"} + -#%tr + -#%td{colspan: 6} + -#%h3.text-center Loading Products + -#%tbody{"ng-repeat" => ""} + -#%tr{"class" => "product product-{{ product.id }}"} - %td.group_buy - %span{"ng-show" => "product.group_buy && (product.variants.length == 0)"} - %input{type: :number, - min: 0, - "ofn-disable-scroll" => true, - max: "{{product.on_demand && 9999 || product.count_on_hand }}", - name: "variant_attributes[{{product.master.id}}][max_quantity]", - "ng-model" => "product.max_quantity"} + -#%td.name{bindonce: "product"} + -#%img{"bo-src" => "product.master.images[0].small_url"} + -#%div + -#%h5 + -#{{ product.name }} + -#%a{"data-reveal-id" => "producer_details_{{product.supplier.id}}", "data-reveal" => ""} + -#{{ product.supplier.name }} - %td.price.text-right{bindonce: ""} - %small{"ng-show" => "(product.variants.length > 0)"} from - {{ productPrice(product) | currency }} + -#%td.notes{bindonce: ""} {{ product.notes | truncate:80 }} - %tr.product-description{bindonce: ""} - %td{colspan: 2}{{ product.notes | truncate:80 }} + -#%td{bindonce: ""} + -#%span{"ng-hide" => "product.variants.length > 0"} {{ product.master.options_text }} + -#%span{"ng-show" => "product.variants.length > 0"} + -#%img.collapse{src: "/assets/collapse.png", + -#"ng-show" => "product.show_variants", + -#"ng-click" => "product.show_variants = !product.show_variants"} - %tr.variant{"ng-repeat" => "variant in product.variants", "ng-if" => "product.show_variants"} - = render partial: "shop/variant" + -#%img.expand{src: "/assets/expand.png", + -#"ng-show" => "!product.show_variants", + -#"ng-click" => "product.show_variants = !product.show_variants"} + -#%td + -#%span{"ng-show" => "(product.variants.length == 0)"} + -#%input{type: :number, + -#value: nil, + -#min: 0, + -#"ofn-disable-scroll" => true, + -#max: "{{product.on_demand && 9999 || product.count_on_hand }}", + -#name: "variants[{{product.master.id}}]", + -#id: "variants_{{product.master.id}}", + -#"ng-model" => "product.quantity"} + + -#%td.group_buy + -#%span{"ng-show" => "product.group_buy && (product.variants.length == 0)"} + -#%input{type: :number, + -#min: 0, + -#"ofn-disable-scroll" => true, + -#max: "{{product.on_demand && 9999 || product.count_on_hand }}", + -#name: "variant_attributes[{{product.master.id}}][max_quantity]", + -#"ng-model" => "product.max_quantity"} + + -#%td.price.text-right{bindonce: ""} + -#%small{"ng-show" => "(product.variants.length > 0)"} from + -#{{ productPrice(product) | currency }} + + -#%tr.product-description{bindonce: ""} + -#%td{colspan: 2}{{ product.notes | truncate:80 }} + + -#%tr.variant{"ng-repeat" => "variant in product.variants", "ng-if" => "product.show_variants"} + -#= render partial: "shop/variant" %input.button.right{type: :submit, value: "Add to Cart"} From 12ddbb6a3224e7791e0c85567b3d9f81f8b09e17 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 13 May 2014 15:54:14 +1000 Subject: [PATCH 003/139] Reworking the shop page --- .../product_node_controller.js.coffee | 9 +++ .../controllers/products_controller.js.coffee | 6 -- .../darkswarm/services/product.js.coffee | 8 +-- .../darkswarm/product_table.css.sass | 4 ++ .../stylesheets/darkswarm/shop.css.sass | 60 ------------------- app/views/shop/_product_master.html.haml | 43 +++++++++++++ app/views/shop/_product_summary.html.haml | 12 ++++ app/views/shop/_product_variants.html.haml | 44 ++++++++++++++ app/views/shop/_products.html.haml | 7 +-- app/views/shop/_variants.html.haml | 0 app/views/shop/products.rabl | 4 -- 11 files changed, 119 insertions(+), 78 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee create mode 100644 app/assets/stylesheets/darkswarm/product_table.css.sass create mode 100644 app/views/shop/_product_master.html.haml create mode 100644 app/views/shop/_product_summary.html.haml create mode 100644 app/views/shop/_product_variants.html.haml create mode 100644 app/views/shop/_variants.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee new file mode 100644 index 0000000000..4ec316e65f --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -0,0 +1,9 @@ +Darkswarm.controller "ProductNodeCtrl", ($scope) -> + $scope.price = -> + if $scope.product.variants.length > 0 + prices = (v.price for v in $scope.product.variants) + Math.min.apply(null, prices) + else + $scope.product.price + + $scope.hasVariants = $scope.product.variants.length > 0 diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 9ba11baa5b..735a80257b 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -2,7 +2,6 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) - $scope.data = Product.data $scope.limit = 3 $scope.order_cycle = OrderCycle.order_cycle - Product.update() $scope.incrementLimit = -> if $scope.limit < $scope.data.products.length @@ -14,8 +13,3 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) - e.preventDefault() $scope.productPrice = (product) -> - if product.variants.length > 0 - prices = (v.price for v in product.variants) - Math.min.apply(null, prices) - else - product.price diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index 89778b659c..ca31d5e9c0 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -1,12 +1,12 @@ Darkswarm.factory 'Product', ($resource) -> new class Product - data: { + constructor: -> + @update() + data: products: null loading: true - } + update: -> @data.products = $resource("/shop/products").query => @data.loading = false @data - all: -> - @data.products || @update() diff --git a/app/assets/stylesheets/darkswarm/product_table.css.sass b/app/assets/stylesheets/darkswarm/product_table.css.sass new file mode 100644 index 0000000000..9b0a7b4598 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/product_table.css.sass @@ -0,0 +1,4 @@ +.product_table + .row + border: 1px solid black + padding: 8px inherit diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index 2107542594..03ba40eba1 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -82,63 +82,3 @@ product padding-top: 1em input.button.right float: left - table - table-layout: fixed - width: 100% - border-collapse: collapse - border: none - th - line-height: 50px - &.name - width: 330px - //&.notes - //width: 140px - &.variant - width: 180px - &.quantity, &.bulk, &.price - width: 90px - .notes - max-width: 300px - td, th - background: #fff - > span - min-width: 50px - display: block - tbody - border: 1px solid #cccccc - border-left: 0px - border-right: 0px - td - padding: 20px 0px - &.name - img - float: left - margin-right: 30px - @media all and (max-width: 768px) - margin-right: 1em - div - min-width: 150px - tr.product-description - display: none - - - // Responsive - @media all and (max-width: 768px) - td.notes, th.notes - display: none - img - width: 20px - height: auto - tr.product-description - display: table-row - td:empty - display: none - - - input[type=number] - width: 60px - margin: 0px - display: block - float: right - padding-top: 14px - diff --git a/app/views/shop/_product_master.html.haml b/app/views/shop/_product_master.html.haml new file mode 100644 index 0000000000..c335103d4e --- /dev/null +++ b/app/views/shop/_product_master.html.haml @@ -0,0 +1,43 @@ +.small-1.column + %span.bulk{"bo-if" => "product.group_buy"} bulk +   + +.small-5.columns + {{ product.name }} + ({{ product.master.options_text }}) + + +-# WITHOUT GROUP BUY +.small-5.columns{"bo-if" => "!product.group_buy"} + %input{type: :number, + min: 0, + "ofn-disable-scroll" => true, + max: "{{product.on_demand && 9999 || product.count_on_hand }}", + name: "variants[{{product.master.id}}]", + id: "variants_{{product.master.id}}", + "ng-model" => "product.quantity"} + {{ product.master.options_text }} + +-# WITH GROUP BUY +.small-2.columns{"bo-if" => "product.group_buy"} + %input{type: :number, + min: 0, + "ofn-disable-scroll" => true, + max: "{{product.on_demand && 9999 || product.count_on_hand }}", + name: "variants[{{product.master.id}}]", + id: "variants_{{product.master.id}}", + "ng-model" => "product.quantity"} + {{ product.master.options_text }} + (min) + +.small-3.columns{"bo-if" => "product.group_buy"} + %input{type: :number, + min: 0, + "ofn-disable-scroll" => true, + max: "{{product.on_demand && 9999 || product.count_on_hand }}", + name: "variant_attributes[{{product.master.id}}][max_quantity]", + "ng-model" => "product.max_quantity"} + (max) + +.small-1.column + {{ product.price | currency }} diff --git a/app/views/shop/_product_summary.html.haml b/app/views/shop/_product_summary.html.haml new file mode 100644 index 0000000000..8edb2e2536 --- /dev/null +++ b/app/views/shop/_product_summary.html.haml @@ -0,0 +1,12 @@ +.row{bindonce: true} + .small-1.column + %img{"bo-src" => "product.master.images[0].small_url"} + %img{name: "taxon icon here"} + .small-5.columns + %strong {{ product.name }} + .small-4.columns + {{ product.supplier.name }} + .small-1.columns + %span{"ng-if" => "hasVariants"} from + {{ price() | currency }} + diff --git a/app/views/shop/_product_variants.html.haml b/app/views/shop/_product_variants.html.haml new file mode 100644 index 0000000000..c915a55361 --- /dev/null +++ b/app/views/shop/_product_variants.html.haml @@ -0,0 +1,44 @@ +.row{bindonce: true, + "ng-repeat" => "variant in product.variants"} + .small-1.column + %span.bulk{"bo-if" => "product.group_buy"} bulk +   + + .small-5.columns + {{ variant.options_text }} + {{ variant.id }} + + -# WITHOUT GROUP BUY + .small-5.columns{"bo-if" => "!product.group_buy"} + %input{type: :number, + value: nil, + min: 0, + "ofn-disable-scroll" => true, + max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", + name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}", + "bo-model" => "variant.quantity"} + {{ variant.options_text }} + + -# WITH GROUP BUY + .small-2.columns{"bo-if" => "product.group_buy"} + %input{type: :number, + value: nil, + min: 0, + "ofn-disable-scroll" => true, + max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", + name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}", + "bo-model" => "variant.quantity"} + {{ variant.options_text }} + (min) + + .small-3.columns{"bo-if" => "product.group_buy"} + %input{type: :number, + min: 0, + "ofn-disable-scroll" => true, + max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", + name: "variant_attributes[{{variant.id}}][max_quantity]", + "ng-model" => "variant.max_quantity"} + (max) + + .small-1.columns + {{ variant.price | currency }} diff --git a/app/views/shop/_products.html.haml b/app/views/shop/_products.html.haml index 7fa562acdf..0944fcae9d 100644 --- a/app/views/shop/_products.html.haml +++ b/app/views/shop/_products.html.haml @@ -11,19 +11,18 @@ .row .small-12.columns - .product_table + .product_table{bindonce: true} %product.row{"ng-controller" => "ProductNodeCtrl", "ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} = render partial: "shop/product_summary" - .row{bindonce: true, "ng-if" => "hasVariants()"} + %div{"bo-if" => "hasVariants"} = render partial: "shop/product_variants" - .row{bindonce: true, "ng-if" => "!hasVariants()"} + .row{"bo-if" => "!hasVariants"} = render partial: "shop/product_master" - -#%table -#%thead -#%th.name Item diff --git a/app/views/shop/_variants.html.haml b/app/views/shop/_variants.html.haml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index c92a1afaa0..a7430fc08c 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -1,10 +1,6 @@ collection @products attributes :id, :name, :permalink, :count_on_hand, :on_demand, :group_buy -node :show_variants do - true -end - node do |product| { notes: strip_tags(product.notes), From 8c6e884563744de4180ec62ad85c2bf364d57ca9 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 13 May 2014 16:29:43 +1000 Subject: [PATCH 004/139] Further improvements, fixing my directive, re-arranging partial --- .../darkswarm/directives/modal.js.coffee | 6 +- app/views/shop/_products.html.haml | 93 ------------------- app/views/shop/_variant.html.haml | 22 ----- app/views/shop/_variants.html.haml | 0 app/views/shop/products/_form.html.haml | 27 ++++++ .../_master.html.haml} | 0 app/views/shop/products/_modal.html.haml | 2 + .../_summary.html.haml} | 3 +- .../_variants.html.haml} | 0 app/views/shop/show.html.haml | 2 +- 10 files changed, 37 insertions(+), 118 deletions(-) delete mode 100644 app/views/shop/_products.html.haml delete mode 100644 app/views/shop/_variant.html.haml delete mode 100644 app/views/shop/_variants.html.haml create mode 100644 app/views/shop/products/_form.html.haml rename app/views/shop/{_product_master.html.haml => products/_master.html.haml} (100%) create mode 100644 app/views/shop/products/_modal.html.haml rename app/views/shop/{_product_summary.html.haml => products/_summary.html.haml} (86%) rename app/views/shop/{_product_variants.html.haml => products/_variants.html.haml} (100%) diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index 8c34ec18a8..0eed6e93c5 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -7,8 +7,12 @@ Darkswarm.directive "ofnModal", ($modal)-> link: (scope, elem, attrs, ctrl, transclude)-> scope.title = attrs.title + contents = null + transclude scope, (clone)-> + contents = clone + scope.cancel = -> scope.modalInstance.dismiss("cancel") elem.on "click", -> - scope.modalInstance = $modal.open(controller: ctrl, template: transclude()) + scope.modalInstance = $modal.open(controller: ctrl, template: contents) diff --git a/app/views/shop/_products.html.haml b/app/views/shop/_products.html.haml deleted file mode 100644 index 0944fcae9d..0000000000 --- a/app/views/shop/_products.html.haml +++ /dev/null @@ -1,93 +0,0 @@ -%products{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null", -"infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"} - - = form_for :order, :url => populate_orders_path, html: {:class => "custom"} do - - %input#search.text{"ng-model" => "query", - placeholder: "Search", - "ng-debounce" => "150", - "ofn-disable-enter" => true} - %input.button.right{type: :submit, value: "Add to Cart"} - - .row - .small-12.columns - .product_table{bindonce: true} - %product.row{"ng-controller" => "ProductNodeCtrl", - "ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} - - = render partial: "shop/product_summary" - - %div{"bo-if" => "hasVariants"} - = render partial: "shop/product_variants" - - .row{"bo-if" => "!hasVariants"} - = render partial: "shop/product_master" - - -#%table - -#%thead - -#%th.name Item - -#%th.notes Notes - -#%th.variant Unit - -#%th.quantity QTY - -#%th.bulk Bulk - -#%th.price.text-right Price - -#%tbody{"ng-show" => "data.loading"} - -#%tr - -#%td{colspan: 6} - -#%h3.text-center Loading Products - -#%tbody{"ng-repeat" => ""} - -#%tr{"class" => "product product-{{ product.id }}"} - - -#%td.name{bindonce: "product"} - -#%img{"bo-src" => "product.master.images[0].small_url"} - -#%div - -#%h5 - -#{{ product.name }} - -#%a{"data-reveal-id" => "producer_details_{{product.supplier.id}}", "data-reveal" => ""} - -#{{ product.supplier.name }} - - -#%td.notes{bindonce: ""} {{ product.notes | truncate:80 }} - - -#%td{bindonce: ""} - -#%span{"ng-hide" => "product.variants.length > 0"} {{ product.master.options_text }} - -#%span{"ng-show" => "product.variants.length > 0"} - -#%img.collapse{src: "/assets/collapse.png", - -#"ng-show" => "product.show_variants", - -#"ng-click" => "product.show_variants = !product.show_variants"} - - -#%img.expand{src: "/assets/expand.png", - -#"ng-show" => "!product.show_variants", - -#"ng-click" => "product.show_variants = !product.show_variants"} - -#%td - -#%span{"ng-show" => "(product.variants.length == 0)"} - -#%input{type: :number, - -#value: nil, - -#min: 0, - -#"ofn-disable-scroll" => true, - -#max: "{{product.on_demand && 9999 || product.count_on_hand }}", - -#name: "variants[{{product.master.id}}]", - -#id: "variants_{{product.master.id}}", - -#"ng-model" => "product.quantity"} - - -#%td.group_buy - -#%span{"ng-show" => "product.group_buy && (product.variants.length == 0)"} - -#%input{type: :number, - -#min: 0, - -#"ofn-disable-scroll" => true, - -#max: "{{product.on_demand && 9999 || product.count_on_hand }}", - -#name: "variant_attributes[{{product.master.id}}][max_quantity]", - -#"ng-model" => "product.max_quantity"} - - -#%td.price.text-right{bindonce: ""} - -#%small{"ng-show" => "(product.variants.length > 0)"} from - -#{{ productPrice(product) | currency }} - - -#%tr.product-description{bindonce: ""} - -#%td{colspan: 2}{{ product.notes | truncate:80 }} - - -#%tr.variant{"ng-repeat" => "variant in product.variants", "ng-if" => "product.show_variants"} - -#= render partial: "shop/variant" - - %input.button.right{type: :submit, value: "Add to Cart"} - - diff --git a/app/views/shop/_variant.html.haml b/app/views/shop/_variant.html.haml deleted file mode 100644 index 15d5485090..0000000000 --- a/app/views/shop/_variant.html.haml +++ /dev/null @@ -1,22 +0,0 @@ - -%td -%td.notes -%td{bindonce: ""} {{variant.options_text}} -%td - %input{type: :number, - value: nil, - min: 0, - "ofn-disable-scroll" => true, - max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", - name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}", - "ng-model" => "variant.quantity"} -%td.group_buy - %span{"ng-show" => "product.group_buy"} - %input{type: :number, - min: 0, - "ofn-disable-scroll" => true, - max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", - name: "variant_attributes[{{variant.id}}][max_quantity]", - "ng-model" => "variant.max_quantity"} -%td.price.text-right{bindonce: ""} - {{ variant.price | currency }} diff --git a/app/views/shop/_variants.html.haml b/app/views/shop/_variants.html.haml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml new file mode 100644 index 0000000000..15e7ff6bd7 --- /dev/null +++ b/app/views/shop/products/_form.html.haml @@ -0,0 +1,27 @@ +%products{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null", +"infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"} + + = form_for :order, :url => populate_orders_path, html: {:class => "custom"} do + + %input#search.text{"ng-model" => "query", + placeholder: "Search", + "ng-debounce" => "150", + "ofn-disable-enter" => true} + %input.button.right{type: :submit, value: "Add to Cart"} + + .row + .small-12.columns + .product_table{bindonce: true} + %product.row{"ng-controller" => "ProductNodeCtrl", + "ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} + = render partial: "shop/products/summary" + + %div{"bo-if" => "hasVariants"} + = render partial: "shop/products/variants" + + .row{"bo-if" => "!hasVariants"} + = render partial: "shop/products/master" + + %input.button.right{type: :submit, value: "Add to Cart"} + + diff --git a/app/views/shop/_product_master.html.haml b/app/views/shop/products/_master.html.haml similarity index 100% rename from app/views/shop/_product_master.html.haml rename to app/views/shop/products/_master.html.haml diff --git a/app/views/shop/products/_modal.html.haml b/app/views/shop/products/_modal.html.haml new file mode 100644 index 0000000000..29a023704f --- /dev/null +++ b/app/views/shop/products/_modal.html.haml @@ -0,0 +1,2 @@ +%ofn-modal{title: "{{product.name}}"} + {{ product.description }} diff --git a/app/views/shop/_product_summary.html.haml b/app/views/shop/products/_summary.html.haml similarity index 86% rename from app/views/shop/_product_summary.html.haml rename to app/views/shop/products/_summary.html.haml index 8edb2e2536..a5fac46a7e 100644 --- a/app/views/shop/_product_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -3,7 +3,8 @@ %img{"bo-src" => "product.master.images[0].small_url"} %img{name: "taxon icon here"} .small-5.columns - %strong {{ product.name }} + = render partial: "shop/products/modal" + .small-4.columns {{ product.supplier.name }} .small-1.columns diff --git a/app/views/shop/_product_variants.html.haml b/app/views/shop/products/_variants.html.haml similarity index 100% rename from app/views/shop/_product_variants.html.haml rename to app/views/shop/products/_variants.html.haml diff --git a/app/views/shop/show.html.haml b/app/views/shop/show.html.haml index ecfcc8e4e3..b833f76916 100644 --- a/app/views/shop/show.html.haml +++ b/app/views/shop/show.html.haml @@ -14,4 +14,4 @@ = render partial: "shopping_shared/details" %products.row - = render partial: "shop/products" + = render partial: "shop/products/form" From 9f169e6ef8ade8545827eb44be0fdc78e25156f6 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 14 May 2014 16:15:18 +1000 Subject: [PATCH 005/139] Adding a basic stub of the primary taxon --- app/models/spree/product_decorator.rb | 4 ++ app/views/shop/products.rabl | 4 ++ spec/controllers/shop_controller_spec.rb | 92 +++--------------------- spec/models/spree/product_spec.rb | 10 +++ 4 files changed, 26 insertions(+), 84 deletions(-) diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 282a93cfb5..ba7cbc253d 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -118,6 +118,10 @@ Spree::Product.class_eval do order_cycle.variants_distributed_by(distributor).where(product_id: self) end + def primary_taxon + self.taxons.order.first + end + # Build a product distribution for each distributor def build_product_distributions_for_user user Enterprise.is_distributor.managed_by(user).each do |distributor| diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index a7430fc08c..4f0eb0ce90 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -13,6 +13,10 @@ child :supplier => :supplier do attributes :id, :name, :description end +child :primary_taxon => :primary_taxon do + attributes :id, :permalink, :name +end + child :master => :master do attributes :id, :is_master, :count_on_hand, :options_text, :count_on_hand, :on_demand child :images => :images do diff --git a/spec/controllers/shop_controller_spec.rb b/spec/controllers/shop_controller_spec.rb index 88cde0e6d9..3683137b79 100644 --- a/spec/controllers/shop_controller_spec.rb +++ b/spec/controllers/shop_controller_spec.rb @@ -111,90 +111,6 @@ describe ShopController do response.body.should be_empty end - # TODO: this should be a controller test baby - pending "filtering products" do - let(:distributor) { create(:distributor_enterprise) } - let(:supplier) { create(:supplier_enterprise) } - let(:oc1) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), orders_close_at: 2.days.from_now) } - let(:p1) { create(:simple_product, on_demand: false) } - let(:p2) { create(:simple_product, on_demand: true) } - let(:p3) { create(:simple_product, on_demand: false) } - let(:p4) { create(:simple_product, on_demand: false) } - let(:p5) { create(:simple_product, on_demand: false) } - let(:p6) { create(:simple_product, on_demand: false) } - let(:p7) { create(:simple_product, on_demand: false) } - let(:v1) { create(:variant, product: p4, unit_value: 2) } - let(:v2) { create(:variant, product: p4, unit_value: 3, on_demand: false) } - let(:v3) { create(:variant, product: p4, unit_value: 4, on_demand: true) } - let(:v4) { create(:variant, product: p5) } - let(:v5) { create(:variant, product: p5) } - let(:v6) { create(:variant, product: p7) } - let(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) } - - before do - p1.master.count_on_hand = 1 - p2.master.count_on_hand = 0 - p1.master.update_attribute(:count_on_hand, 1) - p2.master.update_attribute(:count_on_hand, 0) - p3.master.update_attribute(:count_on_hand, 0) - p6.master.update_attribute(:count_on_hand, 1) - p6.delete - p7.master.update_attribute(:count_on_hand, 1) - v1.update_attribute(:count_on_hand, 1) - v2.update_attribute(:count_on_hand, 0) - v3.update_attribute(:count_on_hand, 0) - v4.update_attribute(:count_on_hand, 1) - v5.update_attribute(:count_on_hand, 0) - v6.update_attribute(:count_on_hand, 1) - v6.update_attribute(:deleted_at, Time.now) - exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id) - exchange.update_attribute :pickup_time, "frogs" - exchange.variants << p1.master - exchange.variants << p2.master - exchange.variants << p3.master - exchange.variants << p6.master - exchange.variants << v1 - exchange.variants << v2 - exchange.variants << v3 - # v4 is in stock but not in distribution - # v5 is out of stock and in the distribution - # Neither should display, nor should their product, p5 - exchange.variants << v5 - exchange.variants << v6 - - controller.stub(:current_order).and_return order - visit shop_path - end - - it "filters products based on availability" do - # It shows on hand products - page.should have_content p1.name - page.should have_content p4.name - - # It shows on demand products - page.should have_content p2.name - - # It does not show products that are neither on hand or on demand - page.should_not have_content p3.name - - # It shows on demand variants - page.should have_content v3.options_text - - # It does not show variants that are neither on hand or on demand - page.should_not have_content v2.options_text - - # It does not show products that have no available variants in this distribution - page.should_not have_content p5.name - - # It does not show deleted products - page.should_not have_content p6.name - - # It does not show deleted variants - page.should_not have_content v6.name - page.should_not have_content p7.name - end - end - context "RABL tests" do render_views before do @@ -211,6 +127,7 @@ describe ShopController do xhr :get, :products response.body.should_not have_content product.name end + it "strips html from description" do product.update_attribute(:description, "turtles frogs") xhr :get, :products @@ -223,6 +140,13 @@ describe ShopController do xhr :get, :products response.body.should have_content "998.0" end + + it "includes the primary taxon" do + taxon = mock_model(Spree::Taxon, name: "fruitbat") + Spree::Product.any_instance.stub(:primary_taxon).and_return taxon + xhr :get, :products + response.body.should have_content "fruitbat" + end end end end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6743e404e9..6d90b70761 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -547,5 +547,15 @@ module Spree end end end + + describe "Taxons" do + let(:taxon1) { create(:taxon) } + let(:taxon2) { create(:taxon) } + let(:product) { create(:simple_product, taxons: [taxon1, taxon2]) } + + it "returns the first taxon as the primary taxon" do + product.primary_taxon.should == taxon1 + end + end end end From c9fea79d19741a4a34ec8c3f9934baeb0033efe7 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 14 May 2014 16:22:25 +1000 Subject: [PATCH 006/139] Printing the primary taxon name --- app/views/shop/products/_summary.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index a5fac46a7e..500a0577a0 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -1,7 +1,7 @@ .row{bindonce: true} .small-1.column %img{"bo-src" => "product.master.images[0].small_url"} - %img{name: "taxon icon here"} + {{ product.primary_taxon.name }} .small-5.columns = render partial: "shop/products/modal" From adb134743fa81c8e023fc4990e4838ab6c1da2d0 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 12:20:42 +1000 Subject: [PATCH 007/139] Adding producer modals to home --- app/views/home/_fat.html.haml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/home/_fat.html.haml b/app/views/home/_fat.html.haml index 7d5dfb3b80..823e96a37e 100644 --- a/app/views/home/_fat.html.haml +++ b/app/views/home/_fat.html.haml @@ -10,8 +10,10 @@ %li.delivery{"bo-if" => "hub.delivery"} Delivery .columns.small-4 %strong Our producers - %p - Go to our shop to see our current producers + %ul + %li{"ng-repeat" => "producer in hub.producers"} + %ofn-modal{title: "{{ producer.name }}"} + {{ producer || json }} .row.active_table_row.link{"ng-show" => "open()", "ng-if" => "hub.active"} .columns.small-11 From 3ac9c3e00d1932e35e6fe3bf45137a2a3df2a543 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 14:01:31 +1000 Subject: [PATCH 008/139] Basics of producer modal in place --- app/views/home/_fat.html.haml | 3 +-- app/views/json/_hubs.rabl | 6 +++++- app/views/modals/_producer.html.haml | 13 +++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 app/views/modals/_producer.html.haml diff --git a/app/views/home/_fat.html.haml b/app/views/home/_fat.html.haml index 823e96a37e..67c83b73cb 100644 --- a/app/views/home/_fat.html.haml +++ b/app/views/home/_fat.html.haml @@ -12,8 +12,7 @@ %strong Our producers %ul %li{"ng-repeat" => "producer in hub.producers"} - %ofn-modal{title: "{{ producer.name }}"} - {{ producer || json }} + = render partial: "modals/producer" .row.active_table_row.link{"ng-show" => "open()", "ng-if" => "hub.active"} .columns.small-11 diff --git a/app/views/json/_hubs.rabl b/app/views/json/_hubs.rabl index a6958840bc..60cad8fbbf 100644 --- a/app/views/json/_hubs.rabl +++ b/app/views/json/_hubs.rabl @@ -6,7 +6,11 @@ child distributed_taxons: :taxons do end child suppliers: :producers do - attributes :name, :id + attributes :name, :id, :description, :long_description + + node :promo_image do |producer| + producer.promo_image.url + end end node :pickup do |hub| diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml new file mode 100644 index 0000000000..691e9378d3 --- /dev/null +++ b/app/views/modals/_producer.html.haml @@ -0,0 +1,13 @@ +%ofn-modal{title: "{{ producer.name }}"} + #producer_modal{bindonce: true} + .row + .small-12.columns + %img{"bo-src" => "producer.promo_image"} + %h3 {{ producer.name }} + + .row + .small-6.columns + %p + {{ producer.description }} + .small-6.columns + Stay in touch with {{ producer.name }} From 91fe8e18d30332f88b742630fcca263682284f21 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 15:38:10 +1000 Subject: [PATCH 009/139] Taxon sorting --- .../darkswarm/controllers/products_controller.js.coffee | 1 + app/views/json/_producers.rabl | 2 +- app/views/json/_taxon.rabl | 5 +++++ app/views/shop/products.rabl | 2 +- app/views/shop/products/_form.html.haml | 3 ++- app/views/shop/products/_summary.html.haml | 7 +++---- 6 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 app/views/json/_taxon.rabl diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 735a80257b..09df18ca38 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -1,6 +1,7 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) -> $scope.data = Product.data $scope.limit = 3 + $scope.ordering = {order: "name"} $scope.order_cycle = OrderCycle.order_cycle $scope.incrementLimit = -> diff --git a/app/views/json/_producers.rabl b/app/views/json/_producers.rabl index 717347e5de..95a133a182 100644 --- a/app/views/json/_producers.rabl +++ b/app/views/json/_producers.rabl @@ -2,7 +2,7 @@ collection @producers extends 'json/enterprises' child supplied_taxons: :taxons do - attributes :name, :id + extends 'json/taxon' end child distributors: :distributors do diff --git a/app/views/json/_taxon.rabl b/app/views/json/_taxon.rabl new file mode 100644 index 0000000000..916abeff78 --- /dev/null +++ b/app/views/json/_taxon.rabl @@ -0,0 +1,5 @@ +attributes :name, :id, :permalink + +node :icon do |taxon| + taxon.icon.url +end diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index 4f0eb0ce90..c79157dae5 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -14,7 +14,7 @@ child :supplier => :supplier do end child :primary_taxon => :primary_taxon do - attributes :id, :permalink, :name + extends 'json/taxon' end child :master => :master do diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 15e7ff6bd7..b13c4cb0a9 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -13,7 +13,8 @@ .small-12.columns .product_table{bindonce: true} %product.row{"ng-controller" => "ProductNodeCtrl", - "ng-repeat" => "product in data.products | filter:query | limitTo: limit track by product.id"} + "ng-repeat" => "product in data.products | filter:query | orderBy:order | limitTo: limit track by product.id"} + = render partial: "shop/products/summary" %div{"bo-if" => "hasVariants"} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index 500a0577a0..a6e4e26497 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -1,13 +1,12 @@ -.row{bindonce: true} +.row .small-1.column %img{"bo-src" => "product.master.images[0].small_url"} - {{ product.primary_taxon.name }} + %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon'"} + .small-5.columns = render partial: "shop/products/modal" - .small-4.columns {{ product.supplier.name }} .small-1.columns %span{"ng-if" => "hasVariants"} from {{ price() | currency }} - From 7c213a061b96929c78667b667a5bd26f3526cb52 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 16:10:54 +1000 Subject: [PATCH 010/139] Getting working taxon sorting and icon rendering in --- app/views/shop/products/_form.html.haml | 4 +--- app/views/shop/products/_summary.html.haml | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index b13c4cb0a9..3a7cea9e63 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -13,7 +13,7 @@ .small-12.columns .product_table{bindonce: true} %product.row{"ng-controller" => "ProductNodeCtrl", - "ng-repeat" => "product in data.products | filter:query | orderBy:order | limitTo: limit track by product.id"} + "ng-repeat" => "product in data.products | filter:query | orderBy:ordering.order | limitTo: limit track by product.id"} = render partial: "shop/products/summary" @@ -24,5 +24,3 @@ = render partial: "shop/products/master" %input.button.right{type: :submit, value: "Add to Cart"} - - diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index a6e4e26497..50f81093d1 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -1,7 +1,9 @@ .row .small-1.column %img{"bo-src" => "product.master.images[0].small_url"} - %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon'"} + %img{"bo-src" => "product.primary_taxon.icon", + "ng-click" => "ordering.order = 'primary_taxon.name'", + name: "{{product.primary_taxon.name}}"} .small-5.columns = render partial: "shop/products/modal" From 3e22e55b61d7025274b7c5c6925bd8c08888530d Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 15 May 2014 16:17:12 +1000 Subject: [PATCH 011/139] Printing taxon icons on home --- app/views/home/_fat.html.haml | 3 ++- app/views/json/_hubs.rabl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/home/_fat.html.haml b/app/views/home/_fat.html.haml index 67c83b73cb..9382844265 100644 --- a/app/views/home/_fat.html.haml +++ b/app/views/home/_fat.html.haml @@ -2,7 +2,8 @@ .columns.small-4 %strong Shop for %p.trans-sentence - {{ hub.taxons | printArrayOfObjects }} + %img{"ng-repeat" => "taxon in hub.taxons", "bo-src" => "taxon.icon", + name: "{{taxon.name}}", alt: "{{taxon.name}}"} .columns.small-4 %strong Delivery options %ol diff --git a/app/views/json/_hubs.rabl b/app/views/json/_hubs.rabl index 60cad8fbbf..ca57a73aea 100644 --- a/app/views/json/_hubs.rabl +++ b/app/views/json/_hubs.rabl @@ -2,7 +2,7 @@ collection Enterprise.visible.is_distributor extends 'json/enterprises' child distributed_taxons: :taxons do - attributes :name, :id + extends "json/taxon" end child suppliers: :producers do From eab9c28d2e462c45e3db36740f09164acd027448 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 16 May 2014 14:00:33 +1000 Subject: [PATCH 012/139] Adding groups to this branch, also tidying up the shop stuff for Laura --- app/assets/javascripts/groups.js.coffee | 3 +++ app/assets/stylesheets/groups.css.scss | 3 +++ app/controllers/groups_controller.rb | 5 +++++ app/helpers/groups_helper.rb | 2 ++ app/views/groups/index.html.haml | 0 app/views/shop/products/_form.html.haml | 4 ++-- app/views/shop/products/_master.html.haml | 8 ++------ app/views/shop/products/_summary.html.haml | 11 +++++++---- app/views/shop/products/_variants.html.haml | 8 +++----- spec/controllers/groups_controller_spec.rb | 9 +++++++++ spec/helpers/groups_helper_spec.rb | 15 +++++++++++++++ 11 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 app/assets/javascripts/groups.js.coffee create mode 100644 app/assets/stylesheets/groups.css.scss create mode 100644 app/controllers/groups_controller.rb create mode 100644 app/helpers/groups_helper.rb create mode 100644 app/views/groups/index.html.haml create mode 100644 spec/controllers/groups_controller_spec.rb create mode 100644 spec/helpers/groups_helper_spec.rb diff --git a/app/assets/javascripts/groups.js.coffee b/app/assets/javascripts/groups.js.coffee new file mode 100644 index 0000000000..761567942f --- /dev/null +++ b/app/assets/javascripts/groups.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/groups.css.scss b/app/assets/stylesheets/groups.css.scss new file mode 100644 index 0000000000..c2a5f9013b --- /dev/null +++ b/app/assets/stylesheets/groups.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the groups controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb new file mode 100644 index 0000000000..1d6932b0d5 --- /dev/null +++ b/app/controllers/groups_controller.rb @@ -0,0 +1,5 @@ +class GroupsController < ApplicationController + def index + @groups = EnterpriseGroup.on_front_page.by_position + end +end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb new file mode 100644 index 0000000000..c091b2fc82 --- /dev/null +++ b/app/helpers/groups_helper.rb @@ -0,0 +1,2 @@ +module GroupsHelper +end diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 3a7cea9e63..076857fa89 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -12,7 +12,7 @@ .row .small-12.columns .product_table{bindonce: true} - %product.row{"ng-controller" => "ProductNodeCtrl", + %product{"ng-controller" => "ProductNodeCtrl", "ng-repeat" => "product in data.products | filter:query | orderBy:ordering.order | limitTo: limit track by product.id"} = render partial: "shop/products/summary" @@ -20,7 +20,7 @@ %div{"bo-if" => "hasVariants"} = render partial: "shop/products/variants" - .row{"bo-if" => "!hasVariants"} + .row.variant{"bo-if" => "!hasVariants"} = render partial: "shop/products/master" %input.button.right{type: :submit, value: "Add to Cart"} diff --git a/app/views/shop/products/_master.html.haml b/app/views/shop/products/_master.html.haml index c335103d4e..7398912bda 100644 --- a/app/views/shop/products/_master.html.haml +++ b/app/views/shop/products/_master.html.haml @@ -2,11 +2,9 @@ %span.bulk{"bo-if" => "product.group_buy"} bulk   -.small-5.columns - {{ product.name }} +.small-4.columns ({{ product.master.options_text }}) - -# WITHOUT GROUP BUY .small-5.columns{"bo-if" => "!product.group_buy"} %input{type: :number, @@ -16,7 +14,6 @@ name: "variants[{{product.master.id}}]", id: "variants_{{product.master.id}}", "ng-model" => "product.quantity"} - {{ product.master.options_text }} -# WITH GROUP BUY .small-2.columns{"bo-if" => "product.group_buy"} @@ -27,7 +24,6 @@ name: "variants[{{product.master.id}}]", id: "variants_{{product.master.id}}", "ng-model" => "product.quantity"} - {{ product.master.options_text }} (min) .small-3.columns{"bo-if" => "product.group_buy"} @@ -39,5 +35,5 @@ "ng-model" => "product.max_quantity"} (max) -.small-1.column +.small-2.columns.text-right {{ product.price | currency }} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index 50f81093d1..ae0e759df6 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -1,14 +1,17 @@ -.row +.row.summary .small-1.column %img{"bo-src" => "product.master.images[0].small_url"} + + .small-4.columns %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon.name'", name: "{{product.primary_taxon.name}}"} + {{ product.name}} + -#= render partial: "shop/products/modal" .small-5.columns - = render partial: "shop/products/modal" - .small-4.columns {{ product.supplier.name }} - .small-1.columns + + .small-2.columns.text-right %span{"ng-if" => "hasVariants"} from {{ price() | currency }} diff --git a/app/views/shop/products/_variants.html.haml b/app/views/shop/products/_variants.html.haml index c915a55361..01041bd1ca 100644 --- a/app/views/shop/products/_variants.html.haml +++ b/app/views/shop/products/_variants.html.haml @@ -1,12 +1,12 @@ .row{bindonce: true, "ng-repeat" => "variant in product.variants"} + .small-1.column %span.bulk{"bo-if" => "product.group_buy"} bulk   - .small-5.columns + .small-4.columns {{ variant.options_text }} - {{ variant.id }} -# WITHOUT GROUP BUY .small-5.columns{"bo-if" => "!product.group_buy"} @@ -17,7 +17,6 @@ max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}", "bo-model" => "variant.quantity"} - {{ variant.options_text }} -# WITH GROUP BUY .small-2.columns{"bo-if" => "product.group_buy"} @@ -28,7 +27,6 @@ max: "{{variant.on_demand && 9999 || variant.count_on_hand }}", name: "variants[{{variant.id}}]", id: "variants_{{variant.id}}", "bo-model" => "variant.quantity"} - {{ variant.options_text }} (min) .small-3.columns{"bo-if" => "product.group_buy"} @@ -40,5 +38,5 @@ "ng-model" => "variant.max_quantity"} (max) - .small-1.columns + .small-2.columns.text-right {{ variant.price | currency }} diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb new file mode 100644 index 0000000000..4005d82a2a --- /dev/null +++ b/spec/controllers/groups_controller_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe GroupsController do + it "gets all visible groups" do + EnterpriseGroup.stub_chain :on_front_page, :by_position + EnterpriseGroup.should_receive :on_front_page + get :index + end +end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb new file mode 100644 index 0000000000..08a4335bae --- /dev/null +++ b/spec/helpers/groups_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the GroupsHelper. For example: +# +# describe GroupsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe GroupsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end From 1dd9f6326b5b9904198cf21673a1770b774ae166 Mon Sep 17 00:00:00 2001 From: summerscope Date: Fri, 16 May 2014 15:59:53 +1000 Subject: [PATCH 013/139] Tweaking the markup and styling for shop page. --- .../stylesheets/darkswarm/shop.css.sass | 33 +++++++++++++-- app/views/shop/products/_form.html.haml | 41 ++++++++++--------- app/views/shop/products/_summary.html.haml | 11 ++--- app/views/shop/products/_variants.html.haml | 2 +- app/views/shop/show.html.haml | 2 +- 5 files changed, 60 insertions(+), 29 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index 03ba40eba1..f9f2f37818 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -1,8 +1,7 @@ @import mixins @import variables +@import branding -product - display: block .darkswarm #search @@ -77,8 +76,36 @@ product products display: block - padding-top: 2.3em + padding-top: 2.3em @media all and (max-width: 768px) padding-top: 1em input.button.right float: left + + product + border: 1px solid #ff0000 + display: block + margin-bottom: 1em !important + + .row.summary, .row.variants + margin-left: 0 + margin-right: 0 + + .row.summary + background: #ccc + + .summary-header + &, & * + @include avenir + color: $clr-brick + + .summary-price + &, & * + @include avenir + + + + + + + diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 076857fa89..07dd7c8e1a 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -1,26 +1,29 @@ -%products{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null", +%products.small-12.columns{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null", "infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"} = form_for :order, :url => populate_orders_path, html: {:class => "custom"} do - %input#search.text{"ng-model" => "query", - placeholder: "Search", - "ng-debounce" => "150", - "ofn-disable-enter" => true} - %input.button.right{type: :submit, value: "Add to Cart"} + .row + .small-6.columns + %input#search.text{"ng-model" => "query", + placeholder: "Search", + "ng-debounce" => "150", + "ofn-disable-enter" => true} + .small-6.columns + %input.button.right{type: :submit, value: "Add to Cart"} + + %div{bindonce: true} + %product{"ng-controller" => "ProductNodeCtrl", + "ng-repeat" => "product in data.products | filter:query | orderBy:ordering.order | limitTo: limit track by product.id"} + %div + = render partial: "shop/products/summary" + + %div{"bo-if" => "hasVariants"} + = render partial: "shop/products/variants" + .variant.row{"bo-if" => "!hasVariants"} + = render partial: "shop/products/master" + .row .small-12.columns - .product_table{bindonce: true} - %product{"ng-controller" => "ProductNodeCtrl", - "ng-repeat" => "product in data.products | filter:query | orderBy:ordering.order | limitTo: limit track by product.id"} - - = render partial: "shop/products/summary" - - %div{"bo-if" => "hasVariants"} - = render partial: "shop/products/variants" - - .row.variant{"bo-if" => "!hasVariants"} - = render partial: "shop/products/master" - - %input.button.right{type: :submit, value: "Add to Cart"} + %input.button.right{type: :submit, value: "Add to Cart"} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index ae0e759df6..ebf2a8104c 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -2,16 +2,17 @@ .small-1.column %img{"bo-src" => "product.master.images[0].small_url"} - .small-4.columns + .small-4.columns.summary-header %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon.name'", name: "{{product.primary_taxon.name}}"} {{ product.name}} -#= render partial: "shop/products/modal" - .small-5.columns + .small-5.columns.summary-header {{ product.supplier.name }} - .small-2.columns.text-right - %span{"ng-if" => "hasVariants"} from - {{ price() | currency }} + .small-2.columns.summary-price.text-right + %span{"ng-if" => "hasVariants"} + %em from + {{ price() | currency }} diff --git a/app/views/shop/products/_variants.html.haml b/app/views/shop/products/_variants.html.haml index 01041bd1ca..40a4371337 100644 --- a/app/views/shop/products/_variants.html.haml +++ b/app/views/shop/products/_variants.html.haml @@ -1,4 +1,4 @@ -.row{bindonce: true, +.row.variants{bindonce: true, "ng-repeat" => "variant in product.variants"} .small-1.column diff --git a/app/views/shop/show.html.haml b/app/views/shop/show.html.haml index b833f76916..ba9493e46b 100644 --- a/app/views/shop/show.html.haml +++ b/app/views/shop/show.html.haml @@ -13,5 +13,5 @@ = render partial: "shopping_shared/details" - %products.row + .row = render partial: "shop/products/form" From 4e4667c33df5bfdb3fccb68fef7072168533184a Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 16 May 2014 11:26:40 +1000 Subject: [PATCH 014/139] Adding groups --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index e4868d777c..69a3c99d56 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,6 +7,7 @@ Openfoodnetwork::Application.routes.draw do get :order_cycle end + resources :groups resources :producers get '/checkout', :to => 'checkout#edit' , :as => :checkout From 09586024180b18ff62f43b03754176bcc69a928b Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 16 May 2014 15:43:26 +1000 Subject: [PATCH 015/139] Starting on migrations and admin forms --- .../controllers/groups_controller.js.coffee | 3 +++ .../darkswarm/services/groups.js.coffee | 4 ++++ app/assets/javascripts/groups.js.coffee | 3 --- app/controllers/groups_controller.rb | 4 +++- app/models/enterprise_group.rb | 9 +++++++++ app/views/groups/index.html.haml | 19 +++++++++++++++++++ app/views/json/_groups.rabl | 2 ++ ...achment_promo_image_to_enterprise_group.rb | 15 +++++++++++++++ .../20140516044750_add_fields_to_groups.rb | 6 ++++++ ...add_attachment_logo_to_enterprise_group.rb | 15 +++++++++++++++ db/schema.rb | 18 ++++++++++++++---- spec/factories.rb | 1 + spec/features/admin/enterprise_groups_spec.rb | 5 ++++- spec/models/enterprise_group_spec.rb | 7 +++++++ 14 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee create mode 100644 app/assets/javascripts/darkswarm/services/groups.js.coffee delete mode 100644 app/assets/javascripts/groups.js.coffee create mode 100644 app/views/json/_groups.rabl create mode 100644 db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb create mode 100644 db/migrate/20140516044750_add_fields_to_groups.rb create mode 100644 db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb diff --git a/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee new file mode 100644 index 0000000000..8fd47c49f8 --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee @@ -0,0 +1,3 @@ +Darkswarm.controller "GroupsCtrl", ($scope, Groups) -> + $scope.Groups = Groups + $scope.order = 'position' diff --git a/app/assets/javascripts/darkswarm/services/groups.js.coffee b/app/assets/javascripts/darkswarm/services/groups.js.coffee new file mode 100644 index 0000000000..e5e50615e8 --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/groups.js.coffee @@ -0,0 +1,4 @@ +Darkswarm.factory 'Groups', (groups) -> + new class Groups + constructor: -> + @groups = groups diff --git a/app/assets/javascripts/groups.js.coffee b/app/assets/javascripts/groups.js.coffee deleted file mode 100644 index 761567942f..0000000000 --- a/app/assets/javascripts/groups.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 1d6932b0d5..84290f20a3 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,4 +1,6 @@ -class GroupsController < ApplicationController +class GroupsController < BaseController + layout 'darkswarm' + def index @groups = EnterpriseGroup.on_front_page.by_position end diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index 41d2a997cc..0638577850 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -4,6 +4,15 @@ class EnterpriseGroup < ActiveRecord::Base has_and_belongs_to_many :enterprises validates :name, presence: true + #validates :description, presence: true + + attr_accessible :promo_image + has_attached_file :promo_image, styles: {medium: "1200x1200>"} + validates_attachment_content_type :promo_image, :content_type => /\Aimage\/.*\Z/ + + attr_accessible :logo + has_attached_file :logo, styles: {medium: "100x100"} + validates_attachment_content_type :logo, :content_type => /\Aimage\/.*\Z/ scope :by_position, order('position ASC') scope :on_front_page, where(on_front_page: true) diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index e69de29bb2..c08bff367c 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -0,0 +1,19 @@ +#groups{"ng-controller" => "GroupsCtrl"} + :javascript + angular.module('Darkswarm').value('groups', #{render partial: "json/groups", object: @groups}) + .row + .small-12.columns.text-center + %h1 Groups / Regions + %h3 Check out our food groups below + + %input{type: :text, + "ng-model" => "query", + placeholder: "Search group name", + "ng-debounce" => "150", + "ofn-disable-enter" => true} + + .row{bindonce: true} + .small.12.columns + .group_table + .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} + {{ group.name }} diff --git a/app/views/json/_groups.rabl b/app/views/json/_groups.rabl new file mode 100644 index 0000000000..3029006c76 --- /dev/null +++ b/app/views/json/_groups.rabl @@ -0,0 +1,2 @@ +collection @groups +attributes :id, :name, :position diff --git a/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb b/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb new file mode 100644 index 0000000000..bd67cb92f0 --- /dev/null +++ b/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb @@ -0,0 +1,15 @@ +class AddAttachmentPromoImageToEnterpriseGroup < ActiveRecord::Migration + def self.up + add_column :enterprise_groups, :promo_image_file_name, :string + add_column :enterprise_groups, :promo_image_content_type, :string + add_column :enterprise_groups, :promo_image_file_size, :integer + add_column :enterprise_groups, :promo_image_updated_at, :datetime + end + + def self.down + remove_column :enterprise_groups, :promo_image_file_name + remove_column :enterprise_groups, :promo_image_content_type + remove_column :enterprise_groups, :promo_image_file_size + remove_column :enterprise_groups, :promo_image_updated_at + end +end diff --git a/db/migrate/20140516044750_add_fields_to_groups.rb b/db/migrate/20140516044750_add_fields_to_groups.rb new file mode 100644 index 0000000000..a50ef1db14 --- /dev/null +++ b/db/migrate/20140516044750_add_fields_to_groups.rb @@ -0,0 +1,6 @@ +class AddFieldsToGroups < ActiveRecord::Migration + def change + add_column :enterprise_groups, :description, :text + add_column :enterprise_groups, :long_description, :text + end +end diff --git a/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb b/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb new file mode 100644 index 0000000000..525bccb63e --- /dev/null +++ b/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb @@ -0,0 +1,15 @@ +class AddAttachmentLogoToEnterpriseGroup < ActiveRecord::Migration + def self.up + add_column :enterprise_groups, :logo_file_name, :string + add_column :enterprise_groups, :logo_content_type, :string + add_column :enterprise_groups, :logo_file_size, :integer + add_column :enterprise_groups, :logo_updated_at, :datetime + end + + def self.down + remove_column :enterprise_groups, :logo_file_name + remove_column :enterprise_groups, :logo_content_type + remove_column :enterprise_groups, :logo_file_size + remove_column :enterprise_groups, :logo_updated_at + end +end diff --git a/db/schema.rb b/db/schema.rb index cacc8fc793..5394fcbd61 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140514044959) do +ActiveRecord::Schema.define(:version => 20140516045323) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -182,9 +182,19 @@ ActiveRecord::Schema.define(:version => 20140514044959) do add_index "enterprise_fees", ["enterprise_id"], :name => "index_enterprise_fees_on_enterprise_id" create_table "enterprise_groups", :force => true do |t| - t.string "name" - t.boolean "on_front_page" - t.integer "position" + t.string "name" + t.boolean "on_front_page" + t.integer "position" + t.string "promo_image_file_name" + t.string "promo_image_content_type" + t.integer "promo_image_file_size" + t.datetime "promo_image_updated_at" + t.text "description" + t.text "long_description" + t.string "logo_file_name" + t.string "logo_content_type" + t.integer "logo_file_size" + t.datetime "logo_updated_at" end create_table "enterprise_groups_enterprises", :id => false, :force => true do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 710ba1c8ba..13c0bd0e8e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -98,6 +98,7 @@ FactoryGirl.define do factory :enterprise_group, :class => EnterpriseGroup do name 'Enterprise group' + description 'this is a group' on_front_page false end diff --git a/spec/features/admin/enterprise_groups_spec.rb b/spec/features/admin/enterprise_groups_spec.rb index 012179e75a..f0ab8564b1 100644 --- a/spec/features/admin/enterprise_groups_spec.rb +++ b/spec/features/admin/enterprise_groups_spec.rb @@ -33,6 +33,7 @@ feature %q{ click_link 'New Enterprise Group' fill_in 'enterprise_group_name', with: 'EGEGEG' + fill_in 'enterprise_group_description', with: 'This is a description' check 'enterprise_group_on_front_page' select e1.name, from: 'enterprise_group_enterprise_ids' select e2.name, from: 'enterprise_group_enterprise_ids' @@ -42,6 +43,7 @@ feature %q{ eg = EnterpriseGroup.last eg.name.should == 'EGEGEG' + eg.description.should == 'This is a description' eg.on_front_page.should be_true eg.enterprises.sort.should == [e1, e2].sort end @@ -60,6 +62,7 @@ feature %q{ page.should have_select 'enterprise_group_enterprise_ids', selected: [e1.name, e2.name] fill_in 'enterprise_group_name', with: 'xyzzy' + fill_in 'enterprise_group_description', with: 'This is a description' uncheck 'enterprise_group_on_front_page' unselect e1.name, from: 'enterprise_group_enterprise_ids' select e2.name, from: 'enterprise_group_enterprise_ids' @@ -69,6 +72,7 @@ feature %q{ eg = EnterpriseGroup.last eg.name.should == 'xyzzy' + eg.description.should == 'This is a description' eg.on_front_page.should be_false eg.enterprises.should == [e2] end @@ -99,7 +103,6 @@ feature %q{ EnterpriseGroup.all.should_not include eg end - context "as an enterprise user" do xit "should show me only enterprises I manage when creating a new enterprise group" end diff --git a/spec/models/enterprise_group_spec.rb b/spec/models/enterprise_group_spec.rb index 167a8c2f7b..3e38882064 100644 --- a/spec/models/enterprise_group_spec.rb +++ b/spec/models/enterprise_group_spec.rb @@ -11,6 +11,13 @@ describe EnterpriseGroup do e = build(:enterprise_group, name: '') e.should_not be_valid end + + it "requires a description" do + e = build(:enterprise_group, description: '') + end + + it { should have_attached_file :promo_image } + it { should have_attached_file :logo } end describe "relations" do From 61cf35a5b93ab42b9995cf0b4fe53eec33d474b2 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 16 May 2014 16:30:37 +1000 Subject: [PATCH 016/139] Adding attr_accessors and paperclip file uploads --- .../admin/enterprise_groups_controller.rb | 2 -- app/models/enterprise_group.rb | 6 ++-- .../admin/enterprise_groups/_form.html.haml | 29 +++++++++++++++++++ spec/features/admin/enterprise_groups_spec.rb | 3 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index 466bde2cd5..cc2f3ed1db 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -15,12 +15,10 @@ module Admin redirect_to main_app.admin_enterprise_groups_path end - private def collection EnterpriseGroup.by_position end - end end diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index 0638577850..6c163b087a 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -4,10 +4,12 @@ class EnterpriseGroup < ActiveRecord::Base has_and_belongs_to_many :enterprises validates :name, presence: true - #validates :description, presence: true + validates :description, presence: true + + attr_accessible :name, :description, :long_description, :on_front_page, :enterprise_ids attr_accessible :promo_image - has_attached_file :promo_image, styles: {medium: "1200x1200>"} + has_attached_file :promo_image, styles: {medium: "800>400"} validates_attachment_content_type :promo_image, :content_type => /\Aimage\/.*\Z/ attr_accessible :logo diff --git a/app/views/admin/enterprise_groups/_form.html.haml b/app/views/admin/enterprise_groups/_form.html.haml index b41a68d4a5..ec4934bf19 100644 --- a/app/views/admin/enterprise_groups/_form.html.haml +++ b/app/views/admin/enterprise_groups/_form.html.haml @@ -3,6 +3,16 @@ %br/ = f.text_field :name += f.field_container :description do + = f.label :description + %br/ + = f.text_field :description + += f.field_container :long_description do + = f.label :long_description + %br/ + = f.text_area :long_description + = f.field_container :on_front_page do = f.label :on_front_page, 'On front page?' %br/ @@ -12,3 +22,22 @@ = f.label :enterprise_ids, 'Enterprises' %br/ = f.collection_select :enterprise_ids, Enterprise.all, :id, :name, {}, {class: "select2 fullwidth", multiple: true} + + +.row + .alpha.three.columns + = f.label :logo, class: 'with-tip', 'data-powertip' => 'This is the logo' + .with-tip{'data-powertip' => 'This is the logo'} + %a What's this? + .omega.eight.columns + = image_tag @object.logo.url if @object.logo.present? + = f.file_field :logo + +.row + .alpha.three.columns + = f.label :promo_image, class: 'with-tip', 'data-powertip' => 'This image is displayed at the top of the Group profile' + .with-tip{'data-powertip' => 'This image is displayed at the top of the Group profile'} + %a What's this? + .omega.eight.columns + = image_tag @object.promo_image.url if @object.promo_image.present? + = f.file_field :promo_image diff --git a/spec/features/admin/enterprise_groups_spec.rb b/spec/features/admin/enterprise_groups_spec.rb index f0ab8564b1..24e89e9be7 100644 --- a/spec/features/admin/enterprise_groups_spec.rb +++ b/spec/features/admin/enterprise_groups_spec.rb @@ -62,9 +62,9 @@ feature %q{ page.should have_select 'enterprise_group_enterprise_ids', selected: [e1.name, e2.name] fill_in 'enterprise_group_name', with: 'xyzzy' - fill_in 'enterprise_group_description', with: 'This is a description' uncheck 'enterprise_group_on_front_page' unselect e1.name, from: 'enterprise_group_enterprise_ids' + select e2.name, from: 'enterprise_group_enterprise_ids' click_button 'Update' @@ -72,7 +72,6 @@ feature %q{ eg = EnterpriseGroup.last eg.name.should == 'xyzzy' - eg.description.should == 'This is a description' eg.on_front_page.should be_false eg.enterprises.should == [e2] end From e7f6a9badfd0bb7cc09541cd7724807a060da15a Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 10:47:09 +1000 Subject: [PATCH 017/139] Adding data to groups page --- app/views/groups/index.html.haml | 14 ++++++++++---- app/views/json/_enterprises.rabl | 8 ++++++++ app/views/json/_groups.rabl | 10 +++++++++- app/views/json/_hubs.rabl | 8 -------- app/views/shared/menu/_large_menu.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 5 +---- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index c08bff367c..552e45fd48 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -12,8 +12,14 @@ "ng-debounce" => "150", "ofn-disable-enter" => true} - .row{bindonce: true} + .row.group_table{bindonce: true} .small.12.columns - .group_table - .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} - {{ group.name }} + .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} + %h2 {{ group.name }} + %p {{ group.description }} + %p {{ group.long_description }} + %img{"bo-src" => "group.logo"} + + %ul + %li{"ng-repeat" => "enterprise in group.enterprises"} + %a{"bo-href" => "enterprise.path"} {{ enterprise.name }} diff --git a/app/views/json/_enterprises.rabl b/app/views/json/_enterprises.rabl index 97e040eca9..2f2f82c944 100644 --- a/app/views/json/_enterprises.rabl +++ b/app/views/json/_enterprises.rabl @@ -4,3 +4,11 @@ attributes :name, :id, :description child :address do extends "json/partials/address" end + +node :path do |enterprise| + shop_enterprise_path(enterprise) +end + +node :hash do |enterprise| + enterprise.to_param +end diff --git a/app/views/json/_groups.rabl b/app/views/json/_groups.rabl index 3029006c76..9475b425c4 100644 --- a/app/views/json/_groups.rabl +++ b/app/views/json/_groups.rabl @@ -1,2 +1,10 @@ collection @groups -attributes :id, :name, :position +attributes :id, :name, :position, :description, :long_description + +child enterprises: :enterprises do + extends 'json/enterprises' +end + +node :logo do |group| + group.logo(:original) +end diff --git a/app/views/json/_hubs.rabl b/app/views/json/_hubs.rabl index ca57a73aea..dc589b878b 100644 --- a/app/views/json/_hubs.rabl +++ b/app/views/json/_hubs.rabl @@ -21,14 +21,6 @@ node :delivery do |hub| not hub.shipping_methods.where(:require_ship_address => true).empty? end -node :path do |hub| - shop_enterprise_path(hub) -end - -node :hash do |hub| - hub.to_param -end - node :active do |hub| @active_distributors.include?(hub) end diff --git a/app/views/shared/menu/_large_menu.html.haml b/app/views/shared/menu/_large_menu.html.haml index 328d46ca85..a5c6180150 100644 --- a/app/views/shared/menu/_large_menu.html.haml +++ b/app/views/shared/menu/_large_menu.html.haml @@ -21,7 +21,7 @@ %span.nav-primary Producers %li.divider %li - %a{href: ""} + %a{href: groups_path} %span.nav-primary Groups %li.divider - if spree_current_user.andand.has_spree_role? 'admin' diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index a33cb85c11..43096c34b6 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -36,17 +36,14 @@ %li %a{href: root_path + "#/#hubs"} %span.nav-primary Hubs - %li %a{href: ""} %span.nav-primary Map - %li %a{href: main_app.producers_path} %span.nav-primary Producers - %li - %a{href: ""} + %a{href: groups_path} %span.nav-primary Groups From 685ba3f63ac0fffecb23042bbc71844ebd43cf0b Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:17:56 +1000 Subject: [PATCH 018/139] Fixing my modal and the tests --- .../darkswarm/directives/modal.js.coffee | 7 ++---- app/views/modals/_food_hub.html.haml | 2 +- app/views/modals/_learn_more.html.haml | 2 +- app/views/shared/menu/_large_menu.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 2 +- app/views/shop/products/_form.html.haml | 2 +- app/views/shop/products/_summary.html.haml | 2 +- app/views/shop/products/_variants.html.haml | 2 +- spec/controllers/shop_controller_spec.rb | 1 + .../consumer/shopping/shopping_spec.rb | 23 ++++++++----------- spec/support/request/shop_workflow.rb | 8 +++++++ 11 files changed, 28 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index 0eed6e93c5..73217b3812 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -2,17 +2,14 @@ Darkswarm.directive "ofnModal", ($modal)-> restrict: 'E' replace: true transclude: true + scope: {} template: "{{title}}" link: (scope, elem, attrs, ctrl, transclude)-> scope.title = attrs.title - contents = null transclude scope, (clone)-> contents = clone - scope.cancel = -> - scope.modalInstance.dismiss("cancel") - - elem.on "click", -> + elem.on "click", => scope.modalInstance = $modal.open(controller: ctrl, template: contents) diff --git a/app/views/modals/_food_hub.html.haml b/app/views/modals/_food_hub.html.haml index e80ffe3745..9b559d26cc 100644 --- a/app/views/modals/_food_hub.html.haml +++ b/app/views/modals/_food_hub.html.haml @@ -2,4 +2,4 @@ %h5 Our food hubs are the point of contact between you and the people who make your food! %p You can search for a convenient hub by location or name. Some hubs have multiple points where you can pick-up your purchases, and some will also provide delivery options. Each food hub is a sales point with independent business operations and logisitics - so variations between hubs are to be expected. %p You can only shop one food hub at a time. -%a.close-reveal-modal{"ng-click" => "cancel()"} × \ No newline at end of file +%a.close-reveal-modal{"ng-click" => "$close()"} × diff --git a/app/views/modals/_learn_more.html.haml b/app/views/modals/_learn_more.html.haml index 870d5fe0bc..4cb0534c6e 100644 --- a/app/views/modals/_learn_more.html.haml +++ b/app/views/modals/_learn_more.html.haml @@ -6,4 +6,4 @@ %h5 Learn more %p If you want to learn more about the Open Food Network, how it works, and get involved, check out: %a.button.neutral-btn.dark{:href => "http://www.openfoodnetwork.org" , :target => "_blank" } Open Food Network -%a.close-reveal-modal{"ng-click" => "cancel()"} × +%a.close-reveal-modal{"ng-click" => "$close()"} × diff --git a/app/views/shared/menu/_large_menu.html.haml b/app/views/shared/menu/_large_menu.html.haml index a5c6180150..6f9bae4488 100644 --- a/app/views/shared/menu/_large_menu.html.haml +++ b/app/views/shared/menu/_large_menu.html.haml @@ -21,7 +21,7 @@ %span.nav-primary Producers %li.divider %li - %a{href: groups_path} + %a{href: main_app.groups_path} %span.nav-primary Groups %li.divider - if spree_current_user.andand.has_spree_role? 'admin' diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index 43096c34b6..5478436eb8 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -43,7 +43,7 @@ %a{href: main_app.producers_path} %span.nav-primary Producers %li - %a{href: groups_path} + %a{href: main_app.groups_path} %span.nav-primary Groups diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 07dd7c8e1a..8c70f76188 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -26,4 +26,4 @@ .row .small-12.columns - %input.button.right{type: :submit, value: "Add to Cart"} + %input.button.right.add_to_cart{type: :submit, value: "Add to Cart"} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index ebf2a8104c..5e777a5dbb 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -12,7 +12,7 @@ .small-5.columns.summary-header {{ product.supplier.name }} - .small-2.columns.summary-price.text-right + .small-2.columns.summary-price.text-right.price %span{"ng-if" => "hasVariants"} %em from {{ price() | currency }} diff --git a/app/views/shop/products/_variants.html.haml b/app/views/shop/products/_variants.html.haml index 40a4371337..14ff8eff24 100644 --- a/app/views/shop/products/_variants.html.haml +++ b/app/views/shop/products/_variants.html.haml @@ -38,5 +38,5 @@ "ng-model" => "variant.max_quantity"} (max) - .small-2.columns.text-right + .small-2.columns.text-right.price {{ variant.price | currency }} diff --git a/spec/controllers/shop_controller_spec.rb b/spec/controllers/shop_controller_spec.rb index 3683137b79..f0857f54bc 100644 --- a/spec/controllers/shop_controller_spec.rb +++ b/spec/controllers/shop_controller_spec.rb @@ -144,6 +144,7 @@ describe ShopController do it "includes the primary taxon" do taxon = mock_model(Spree::Taxon, name: "fruitbat") Spree::Product.any_instance.stub(:primary_taxon).and_return taxon + taxon.stub_chain(:icon, :url).and_return "" xhr :get, :products response.body.should have_content "fruitbat" end diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 19fcb5a44b..9946be2f5b 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -90,10 +90,6 @@ feature "As a consumer I want to shop with a distributor", js: true do it "should not show quantity field for product with variants" do visit shop_path page.should_not have_selector("#variants_#{product.master.id}", visible: true) - - #it "expands variants" do - find(".collapse").trigger "click" - page.should_not have_text variant1.options_text end it "uses the adjusted price" do @@ -104,15 +100,16 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path # Page should not have product.price (with or without fee) - page.should_not have_selector 'tr.product > td', text: "from $10.00" - page.should_not have_selector 'tr.product > td', text: "from $33.00" + page.should_not have_price "from $10.00" + page.should_not have_price "from $33.00" # Page should have variant prices (with fee) - page.should have_selector 'tr.variant > td.price', text: "$43.00" - page.should have_selector 'tr.variant > td.price', text: "$53.00" + page.should have_price "$43.00" + page.should have_price "$53.00" # Product price should be listed as the lesser of these - page.should have_selector 'tr.product > td', text: "from $43.00" + #page.should have_selector 'tr.product > td', text: "from $43.00" + page.should have_price "from $43.00" end end @@ -131,7 +128,7 @@ feature "As a consumer I want to shop with a distributor", js: true do it "should save group buy data to ze cart" do fill_in "variants[#{product.master.id}]", with: 5 fill_in "variant_attributes[#{product.master.id}][max_quantity]", with: 9 - first("form.custom > input.button.right").click + add_to_cart page.should have_content product.name li = Spree::Order.order(:created_at).last.line_items.order(:created_at).last li.max_quantity.should == 9 @@ -142,7 +139,7 @@ feature "As a consumer I want to shop with a distributor", js: true do pending "adding a product with a max quantity less than quantity results in max_quantity==quantity" do fill_in "variants[#{product.master.id}]", with: 5 fill_in "variant_attributes[#{product.master.id}][max_quantity]", with: 1 - first("form.custom > input.button.right").click + add_to_cart page.should have_content product.name li = Spree::Order.order(:created_at).last.line_items.order(:created_at).last li.max_quantity.should == 5 @@ -161,7 +158,7 @@ feature "As a consumer I want to shop with a distributor", js: true do it "should save group buy data to ze cart" do fill_in "variants[#{variant.id}]", with: 6 fill_in "variant_attributes[#{variant.id}][max_quantity]", with: 7 - first("form.custom > input.button.right").click + add_to_cart page.should have_content product.name li = Spree::Order.order(:created_at).last.line_items.order(:created_at).last li.max_quantity.should == 7 @@ -181,7 +178,7 @@ feature "As a consumer I want to shop with a distributor", js: true do end it "should let us add products to our cart" do fill_in "variants[#{variant.id}]", with: "1" - first("form.custom > input.button.right").click + add_to_cart current_path.should == "/cart" page.should have_content product.name end diff --git a/spec/support/request/shop_workflow.rb b/spec/support/request/shop_workflow.rb index bdad9e5d49..c87d33149a 100644 --- a/spec/support/request/shop_workflow.rb +++ b/spec/support/request/shop_workflow.rb @@ -1,4 +1,12 @@ module ShopWorkflow + def add_to_cart + first("input.add_to_cart").click + end + + def have_price(price) + have_selector ".price", text: price + end + def set_order(order) ApplicationController.any_instance.stub(:session).and_return({order_id: order.id, access_token: order.token}) end From 9557d69f711e659aa1c1b023dc1f711ddc3f0796 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:30:28 +1000 Subject: [PATCH 019/139] Showing admin for enterprise or admin user --- app/helpers/shared_helper.rb | 6 +++++- app/views/shared/menu/_large_menu.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index f255999009..be1e0ba0f4 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -20,6 +20,10 @@ module SharedHelper end def enterprise_user? - spree_current_user.andand.enterprises.count > 0 + spree_current_user.andand.enterprises.andand.count.to_i > 0 + end + + def admin_user? + spree_current_user.andand.has_spree_role? 'admin' end end diff --git a/app/views/shared/menu/_large_menu.html.haml b/app/views/shared/menu/_large_menu.html.haml index 328d46ca85..9443dfa979 100644 --- a/app/views/shared/menu/_large_menu.html.haml +++ b/app/views/shared/menu/_large_menu.html.haml @@ -24,7 +24,7 @@ %a{href: ""} %span.nav-primary Groups %li.divider - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index a33cb85c11..7d37d9b2cb 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -15,7 +15,7 @@ %ul.off-canvas-list %li= link_to image_tag("ofn_logo_small.png"), root_path - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin From 3eb6f98c70b7dfa988f66bacf861a1114daccfab Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:39:22 +1000 Subject: [PATCH 020/139] Putting error messages on checkout into error flash for easier debugging --- app/controllers/checkout_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 5cf940c223..2bedcf5b6b 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -26,7 +26,7 @@ class CheckoutController < Spree::CheckoutController if @order.next state_callback(:after) else - flash[:error] = t(:payment_processing_failed) + flash[:error] = @order.errors.full_messages.to_sentence update_failed return end From 52345d9bb347a2402ce7fb57474e2dd4e0fa3fc6 Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 20 May 2014 14:11:41 +1000 Subject: [PATCH 021/139] Improvements to shoptfront page styling --- app/assets/stylesheets/darkswarm/mixins.sass | 2 +- .../stylesheets/darkswarm/shop.css.sass | 42 ++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/mixins.sass b/app/assets/stylesheets/darkswarm/mixins.sass index 1f8086d9f2..fde601f2d9 100644 --- a/app/assets/stylesheets/darkswarm/mixins.sass +++ b/app/assets/stylesheets/darkswarm/mixins.sass @@ -12,7 +12,7 @@ border: 1px solid #999 font-size: 18px @extend .avenir - padding: 22px 18px + padding: 0.75em 1em height: auto margin-bottom: 1em diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index f9f2f37818..0c2972367a 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -82,27 +82,49 @@ input.button.right float: left + + product:hover, product:focus, product:active + border-color: $clr-brick + @include box-shadow(0 0 3px 0 $clr-brick-bright) + + .row.variants + border-top: 1px solid $clr-brick-light + background: $clr-brick-ultra-light + product - border: 1px solid #ff0000 + @include csstrans + border: 1px solid #989898 display: block margin-bottom: 1em !important + input + margin: 0 + width: 8em + + .columns + padding-top: 1em + padding-bottom: 1em + .row.summary, .row.variants + @include csstrans margin-left: 0 margin-right: 0 + background: #f7f7f7 + border-top: 1px solid #dfdfdf .row.summary - background: #ccc + @include csstrans + background: #fff - .summary-header - &, & * - @include avenir - color: $clr-brick + .summary-header + &, & * + @include avenir + color: $clr-brick - .summary-price - &, & * - @include avenir - + .summary-price + &, & * + @include avenir + From 4e463e70874ae8244e491392bba0c4491ef447aa Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:30:28 +1000 Subject: [PATCH 022/139] Showing admin for enterprise or admin user --- app/helpers/shared_helper.rb | 6 +++++- app/views/shared/menu/_large_menu.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index f255999009..be1e0ba0f4 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -20,6 +20,10 @@ module SharedHelper end def enterprise_user? - spree_current_user.andand.enterprises.count > 0 + spree_current_user.andand.enterprises.andand.count.to_i > 0 + end + + def admin_user? + spree_current_user.andand.has_spree_role? 'admin' end end diff --git a/app/views/shared/menu/_large_menu.html.haml b/app/views/shared/menu/_large_menu.html.haml index 6f9bae4488..7a72b80f60 100644 --- a/app/views/shared/menu/_large_menu.html.haml +++ b/app/views/shared/menu/_large_menu.html.haml @@ -24,7 +24,7 @@ %a{href: main_app.groups_path} %span.nav-primary Groups %li.divider - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index 5478436eb8..5e9f22c597 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -15,7 +15,7 @@ %ul.off-canvas-list %li= link_to image_tag("ofn_logo_small.png"), root_path - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin From 2fc45d635d4e9d0a616fd27f7c5954c365d69844 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:39:22 +1000 Subject: [PATCH 023/139] Putting error messages on checkout into error flash for easier debugging --- app/controllers/checkout_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 5cf940c223..2bedcf5b6b 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -26,7 +26,7 @@ class CheckoutController < Spree::CheckoutController if @order.next state_callback(:after) else - flash[:error] = t(:payment_processing_failed) + flash[:error] = @order.errors.full_messages.to_sentence update_failed return end From df82627bd1058289dffc7b331e075f0f0e558b2d Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 15:47:00 +1000 Subject: [PATCH 024/139] Starting to rework login behaviour when hitting /admin --- app/controllers/checkout_controller.rb | 6 +++++- .../spree/admin/base_controller_decorator.rb | 2 +- .../spree/admin/overview_controller_decorator.rb | 15 ++++++++++++++- config/routes.rb | 2 ++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 2bedcf5b6b..3879f16741 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -26,7 +26,11 @@ class CheckoutController < Spree::CheckoutController if @order.next state_callback(:after) else - flash[:error] = @order.errors.full_messages.to_sentence + unless @order.errors.empty? + flash[:error] = @order.errors.full_messages.to_sentence + else + flash[:error] = t(:payment_processing_failed) + end update_failed return end diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb index 8e876513fa..df7076345f 100644 --- a/app/controllers/spree/admin/base_controller_decorator.rb +++ b/app/controllers/spree/admin/base_controller_decorator.rb @@ -11,4 +11,4 @@ Spree::Admin::BaseController.class_eval do authorize! :admin, record authorize! action, record end -end \ No newline at end of file +end diff --git a/app/controllers/spree/admin/overview_controller_decorator.rb b/app/controllers/spree/admin/overview_controller_decorator.rb index dd53294f6f..5c96901c1d 100644 --- a/app/controllers/spree/admin/overview_controller_decorator.rb +++ b/app/controllers/spree/admin/overview_controller_decorator.rb @@ -4,4 +4,17 @@ Spree::Admin::OverviewController.class_eval do @product_count = Spree::Product.active.managed_by(spree_current_user).count @order_cycle_count = OrderCycle.active.managed_by(spree_current_user).count end -end \ No newline at end of file + + # This is in Spree::Core::ControllerHelpers::Auth + # But you can't easily reopen modules in Ruby + def unauthorized + if try_spree_current_user + flash[:error] = t(:authorization_failure) + redirect_to '/unauthorized' + else + store_location + url = respond_to?(:spree_login_path) ? spree_login_path : root_path + redirect_to url + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 69a3c99d56..310d1d9e4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,8 @@ Openfoodnetwork::Application.routes.draw do root :to => 'home#index' + get "/#/login", to: "home#index", as: :spree_login + resource :shop, controller: "shop" do get :products post :order_cycle From 0957edee5d67d24a5f73ef74527de64495a4248d Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 20 May 2014 15:50:03 +1000 Subject: [PATCH 025/139] Styling for shopping cart page --- app/assets/stylesheets/darkswarm/all.scss | 3 +- .../stylesheets/darkswarm/forms.css.sass | 5 +++ .../darkswarm/shopping-cart.css.sass | 6 +++ app/views/shop/show.html.haml | 2 + app/views/spree/orders/_form.html.haml | 23 ++++++++++++ app/views/spree/orders/_line_item.html.haml | 2 +- app/views/spree/orders/edit.html.haml | 37 +++++-------------- 7 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/forms.css.sass create mode 100644 app/assets/stylesheets/darkswarm/shopping-cart.css.sass diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index a3ee62ec56..80e43cdc8b 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -11,5 +11,4 @@ ofn-modal { display: block; -} - +} \ No newline at end of file diff --git a/app/assets/stylesheets/darkswarm/forms.css.sass b/app/assets/stylesheets/darkswarm/forms.css.sass new file mode 100644 index 0000000000..7047159601 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/forms.css.sass @@ -0,0 +1,5 @@ +@import mixins +@import branding + +fieldset + border: 0 \ No newline at end of file diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass new file mode 100644 index 0000000000..a5314c3ef2 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass @@ -0,0 +1,6 @@ +@import mixins +@import branding + +#edit-cart + button, .button + margin: 0 diff --git a/app/views/shop/show.html.haml b/app/views/shop/show.html.haml index ba9493e46b..b94bd59bf9 100644 --- a/app/views/shop/show.html.haml +++ b/app/views/shop/show.html.haml @@ -15,3 +15,5 @@ .row = render partial: "shop/products/form" + += render partial: "shared/footer" \ No newline at end of file diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 9366e0025d..09b3b72c22 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -19,4 +19,27 @@ = order_form.fields_for :line_items do |item_form| = render :partial => 'line_item', :locals => { :variant => item_form.object.variant, :line_item => item_form.object, :item_form => item_form } + %tfoot#edit-cart + %tr + %td + Product + \: + %span.order-total.item-total= number_to_currency @order.item_total + %td + Distribution + \: + %span.order-total.distribution-total= order_distribution_subtotal(@order) + %td + %td + = button_tag :class => 'neutral-btn dark expand small', :id => 'update-button' do + %i.fi-refresh + = t(:update) + %td + %h5.order-total.grand-total= @order.display_total + %td#empty-cart + / This needs help from Will - would like a link not button + %span#clear_cart_link{"data-hook" => ""} + = form_tag empty_cart_path, :method => :put do + = submit_tag t(:empty_cart), :class => 'button alert expand small' + = render "spree/orders/adjustments" unless @order.adjustments.eligible.blank? diff --git a/app/views/spree/orders/_line_item.html.haml b/app/views/spree/orders/_line_item.html.haml index bb7054655f..6986caf100 100644 --- a/app/views/spree/orders/_line_item.html.haml +++ b/app/views/spree/orders/_line_item.html.haml @@ -21,7 +21,7 @@ %td.cart-item-total{"data-hook" => "cart_item_total"} = line_item.display_amount.to_html unless line_item.quantity.nil? - %td.cart-item-delete{"data-hook" => "cart_item_delete"} + %td.cart-item-delete.text-center{"data-hook" => "cart_item_delete"} {{ quantity }} = link_to image_tag('icons/delete.png'), '#', :class => 'delete', :id => "delete_#{dom_id(line_item)}" diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 06b82d5169..f0c6b95a78 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -24,35 +24,18 @@ .row = render :partial => 'form', :locals => { :order_form => order_form } - #subtotal.row{'data-hook' => ""} - .columns.large-5 - %h5 - Product - \: - %span.order-total.item-total= number_to_currency @order.item_total - .columns.large-4 - %h5 - Distribution - \: - %span.order-total.distribution-total= order_distribution_subtotal(@order) - .columns.large-3 - %h4 - Cart Total - \: - %span.order-total.grand-total= @order.display_total .links{'data-hook' => "cart_buttons"} .row - #empty-cart.columns.large-8{"data-hook" => ""} - = form_tag empty_cart_path, :method => :put do - #clear_cart_link{"data-hook" => ""} - = link_to "Continue Shopping", main_app.shop_path, class: "button secondary" - = t(:or) - = submit_tag t(:empty_cart), :class => 'button secondary' - + .columns.large-8{"data-hook" => ""} + + %a.button.large.secondary{href: main_app.shop_path} + %i.fi-arrow-left + Continue shopping .columns.large-4.text-right - = button_tag :class => 'secondary', :id => 'update-button' do - = t(:update) - = t(:or) - = link_to "Checkout", main_app.checkout_path, class: "button checkout primary", id: "checkout-link" + %a#checkout-link.button.large.primary{href: main_app.checkout_path} + Checkout + %i.fi-arrow-right + += render partial: "shared/footer" From 601281ced777d2fde2f753695715e0acdd45c518 Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 20 May 2014 16:04:26 +1000 Subject: [PATCH 026/139] Add button style to shop page --- app/views/shop/products/_form.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml index 8c70f76188..5a3af9684e 100644 --- a/app/views/shop/products/_form.html.haml +++ b/app/views/shop/products/_form.html.haml @@ -10,7 +10,7 @@ "ng-debounce" => "150", "ofn-disable-enter" => true} .small-6.columns - %input.button.right{type: :submit, value: "Add to Cart"} + %input.button.primary.right{type: :submit, value: "Add to Cart"} %div{bindonce: true} %product{"ng-controller" => "ProductNodeCtrl", @@ -26,4 +26,4 @@ .row .small-12.columns - %input.button.right.add_to_cart{type: :submit, value: "Add to Cart"} + %input.button.primary.right.add_to_cart{type: :submit, value: "Add to Cart"} From 0b595e21d2f8e87a517c0f64f4bf9881ae17bcba Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:30:28 +1000 Subject: [PATCH 027/139] Showing admin for enterprise or admin user --- app/helpers/shared_helper.rb | 6 +++++- app/views/shared/menu/_large_menu.html.haml | 2 +- app/views/shared/menu/_mobile_menu.html.haml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index f255999009..be1e0ba0f4 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -20,6 +20,10 @@ module SharedHelper end def enterprise_user? - spree_current_user.andand.enterprises.count > 0 + spree_current_user.andand.enterprises.andand.count.to_i > 0 + end + + def admin_user? + spree_current_user.andand.has_spree_role? 'admin' end end diff --git a/app/views/shared/menu/_large_menu.html.haml b/app/views/shared/menu/_large_menu.html.haml index 6f9bae4488..7a72b80f60 100644 --- a/app/views/shared/menu/_large_menu.html.haml +++ b/app/views/shared/menu/_large_menu.html.haml @@ -24,7 +24,7 @@ %a{href: main_app.groups_path} %span.nav-primary Groups %li.divider - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin diff --git a/app/views/shared/menu/_mobile_menu.html.haml b/app/views/shared/menu/_mobile_menu.html.haml index 5478436eb8..5e9f22c597 100644 --- a/app/views/shared/menu/_mobile_menu.html.haml +++ b/app/views/shared/menu/_mobile_menu.html.haml @@ -15,7 +15,7 @@ %ul.off-canvas-list %li= link_to image_tag("ofn_logo_small.png"), root_path - - if spree_current_user.andand.has_spree_role? 'admin' + - if admin_user? or enterprise_user? %li %a{href: spree.admin_path} %span.nav-primary Admin From da69167b4ce3649060e69f57ad4968b66e8db30e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 12:39:22 +1000 Subject: [PATCH 028/139] Putting error messages on checkout into error flash for easier debugging --- app/controllers/checkout_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 5cf940c223..2bedcf5b6b 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -26,7 +26,7 @@ class CheckoutController < Spree::CheckoutController if @order.next state_callback(:after) else - flash[:error] = t(:payment_processing_failed) + flash[:error] = @order.errors.full_messages.to_sentence update_failed return end From 36aba8049fbede064d5f1e5e00607c243b16a0e2 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 15:47:00 +1000 Subject: [PATCH 029/139] Starting to rework login behaviour when hitting /admin --- app/controllers/checkout_controller.rb | 6 +++++- .../spree/admin/base_controller_decorator.rb | 2 +- .../spree/admin/overview_controller_decorator.rb | 15 ++++++++++++++- config/routes.rb | 2 ++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 2bedcf5b6b..3879f16741 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -26,7 +26,11 @@ class CheckoutController < Spree::CheckoutController if @order.next state_callback(:after) else - flash[:error] = @order.errors.full_messages.to_sentence + unless @order.errors.empty? + flash[:error] = @order.errors.full_messages.to_sentence + else + flash[:error] = t(:payment_processing_failed) + end update_failed return end diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb index 8e876513fa..df7076345f 100644 --- a/app/controllers/spree/admin/base_controller_decorator.rb +++ b/app/controllers/spree/admin/base_controller_decorator.rb @@ -11,4 +11,4 @@ Spree::Admin::BaseController.class_eval do authorize! :admin, record authorize! action, record end -end \ No newline at end of file +end diff --git a/app/controllers/spree/admin/overview_controller_decorator.rb b/app/controllers/spree/admin/overview_controller_decorator.rb index dd53294f6f..5c96901c1d 100644 --- a/app/controllers/spree/admin/overview_controller_decorator.rb +++ b/app/controllers/spree/admin/overview_controller_decorator.rb @@ -4,4 +4,17 @@ Spree::Admin::OverviewController.class_eval do @product_count = Spree::Product.active.managed_by(spree_current_user).count @order_cycle_count = OrderCycle.active.managed_by(spree_current_user).count end -end \ No newline at end of file + + # This is in Spree::Core::ControllerHelpers::Auth + # But you can't easily reopen modules in Ruby + def unauthorized + if try_spree_current_user + flash[:error] = t(:authorization_failure) + redirect_to '/unauthorized' + else + store_location + url = respond_to?(:spree_login_path) ? spree_login_path : root_path + redirect_to url + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 69a3c99d56..310d1d9e4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,8 @@ Openfoodnetwork::Application.routes.draw do root :to => 'home#index' + get "/#/login", to: "home#index", as: :spree_login + resource :shop, controller: "shop" do get :products post :order_cycle From ef91f8d17ffe14fde9aaea4ce0273b91a5f2bcf8 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Tue, 20 May 2014 16:04:53 +1000 Subject: [PATCH 030/139] Redirecting if cart is empty and activating the empty cart link --- app/controllers/spree/orders_controller_decorator.rb | 10 ++++++++++ app/views/spree/orders/_form.html.haml | 5 +++-- spec/controllers/spree/orders_controller_spec.rb | 11 +++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index af1d5621c5..ce20dfd58d 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -11,6 +11,16 @@ Spree::OrdersController.class_eval do include OrderCyclesHelper layout 'darkswarm' + # Patching to redirect to shop if order is empty + def edit + @order = current_order(true) + if @order.line_items.empty? + redirect_to main_app.shop_path + else + associate_user + end + end + # Patch Orders#populate to populate multi_cart (if enabled) def populate if OpenFoodNetwork::FeatureToggle.enabled? :multi_cart diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 09b3b72c22..3723299f84 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -39,7 +39,8 @@ %td#empty-cart / This needs help from Will - would like a link not button %span#clear_cart_link{"data-hook" => ""} - = form_tag empty_cart_path, :method => :put do - = submit_tag t(:empty_cart), :class => 'button alert expand small' + = link_to "Empty cart", empty_cart_path, method: :put + -#= form_tag empty_cart_path, :method => :put do + -#= submit_tag t(:empty_cart), :class => 'button alert expand small' = render "spree/orders/adjustments" unless @order.adjustments.eligible.blank? diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index a9118355d6..53c7be68f0 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -2,12 +2,23 @@ require 'spec_helper' describe Spree::OrdersController do let(:distributor) { double(:distributor) } + let(:order) { create(:order) } + let(:order_cycle) { create(:simple_order_cycle) } it "redirects home when no distributor is selected" do spree_get :edit response.should redirect_to root_path end + it "redirects to shop when order is empty" do + controller.stub(:current_distributor).and_return(distributor) + controller.stub(:current_order_cycle).and_return(order_cycle) + controller.stub(:current_order).and_return order + order.stub_chain(:line_items, :empty?).and_return true + spree_get :edit + response.should redirect_to shop_path + end + it "redirects to the shop when no order cycle is selected" do controller.stub(:current_distributor).and_return(distributor) spree_get :edit From d874855aa14ce3696a73530107ceac60cc1c6227 Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 20 May 2014 16:40:23 +1000 Subject: [PATCH 031/139] Update styling on empty cart --- app/assets/stylesheets/darkswarm/typography.css.sass | 5 ++++- app/views/spree/orders/_form.html.haml | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/typography.css.sass b/app/assets/stylesheets/darkswarm/typography.css.sass index 68d990240d..63d4efe13f 100644 --- a/app/assets/stylesheets/darkswarm/typography.css.sass +++ b/app/assets/stylesheets/darkswarm/typography.css.sass @@ -26,7 +26,7 @@ a text-decoration: none color: $clr-brick-bright -small +small, .small font-size: 0.75rem @mixin avenir @@ -56,6 +56,9 @@ ul.ofn-list .pad-top padding-top: 1em +.not-bold + font-weight: normal + strong.avenir font-weight: normal // Avenir is basically bold anyway diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 3723299f84..bec495a458 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -36,10 +36,9 @@ = t(:update) %td %h5.order-total.grand-total= @order.display_total - %td#empty-cart - / This needs help from Will - would like a link not button + %td#empty-cart.text-center %span#clear_cart_link{"data-hook" => ""} - = link_to "Empty cart", empty_cart_path, method: :put + = link_to "Empty cart", empty_cart_path, method: :put, :class => 'not-bold small' -#= form_tag empty_cart_path, :method => :put do -#= submit_tag t(:empty_cart), :class => 'button alert expand small' From 391b1da04c09aca950196c6bed0c166411eb35aa Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 10:46:03 +1000 Subject: [PATCH 032/139] adding session token to order test --- app/controllers/spree/orders_controller_decorator.rb | 1 + spec/controllers/spree/orders_controller_spec.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb index ce20dfd58d..959e51204f 100644 --- a/app/controllers/spree/orders_controller_decorator.rb +++ b/app/controllers/spree/orders_controller_decorator.rb @@ -28,6 +28,7 @@ Spree::OrdersController.class_eval do end populator = Spree::OrderPopulator.new(current_order(true), current_currency) if populator.populate(params.slice(:products, :variants, :quantity)) + fire_event('spree.cart.add') fire_event('spree.order.contents_changed') respond_with(@order) do |format| diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb index 53c7be68f0..e6c9b91894 100644 --- a/spec/controllers/spree/orders_controller_spec.rb +++ b/spec/controllers/spree/orders_controller_spec.rb @@ -15,6 +15,7 @@ describe Spree::OrdersController do controller.stub(:current_order_cycle).and_return(order_cycle) controller.stub(:current_order).and_return order order.stub_chain(:line_items, :empty?).and_return true + session[:access_token] = order.token spree_get :edit response.should redirect_to shop_path end From 4f1b8d06e71e1bcb654f5436a948750884a9efcd Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 12:19:07 +1000 Subject: [PATCH 033/139] Construct enterprise relationships with a factory --- spec/factories.rb | 3 +++ spec/models/enterprise_spec.rb | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index 13c0bd0e8e..b2ed52b7a7 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -96,6 +96,9 @@ FactoryGirl.define do is_distributor true end + factory :enterprise_relationship do + end + factory :enterprise_group, :class => EnterpriseGroup do name 'Enterprise group' description 'this is a group' diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index 06c4c0850e..f375b8890a 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -31,10 +31,10 @@ describe Enterprise do let(:e) { create(:distributor_enterprise) } let(:p) { create(:supplier_enterprise) } let(:c) { create(:distributor_enterprise) } - before do - EnterpriseRelationship.create! parent_id: p.id, child_id: e.id - EnterpriseRelationship.create! parent_id: e.id, child_id: c.id - end + + let!(:er1) { create(:enterprise_relationship, parent_id: p.id, child_id: e.id) } + let!(:er2) { create(:enterprise_relationship, parent_id: e.id, child_id: c.id) } + it "finds relatives" do e.relatives.sort.should == [p, c].sort end From aa53d8238655d544c6557fe12d28d23c05781d36 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 12:19:48 +1000 Subject: [PATCH 034/139] Add stub page for managing enterprise relationships --- .../admin/enterprise_relationships_controller.rb | 7 +++++++ app/views/admin/enterprise_relationships/index.html.haml | 8 ++++++++ app/views/admin/enterprises/index.html.erb | 2 ++ app/views/admin/shared/_enterprises_sub_menu.html.haml | 4 ++++ config/routes.rb | 2 ++ 5 files changed, 23 insertions(+) create mode 100644 app/controllers/admin/enterprise_relationships_controller.rb create mode 100644 app/views/admin/enterprise_relationships/index.html.haml create mode 100644 app/views/admin/shared/_enterprises_sub_menu.html.haml diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb new file mode 100644 index 0000000000..7959b9d9b5 --- /dev/null +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -0,0 +1,7 @@ +module Admin + class EnterpriseRelationshipsController < ResourceController + def index + + end + end +end diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml new file mode 100644 index 0000000000..7f2c236d82 --- /dev/null +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -0,0 +1,8 @@ +- content_for :page_title do + Enterprise Relationships + += render 'admin/shared/enterprises_sub_menu' + +%table#enterprise-relationships + %tr + %td Hello, world. diff --git a/app/views/admin/enterprises/index.html.erb b/app/views/admin/enterprises/index.html.erb index d2917bcc45..1795b17950 100644 --- a/app/views/admin/enterprises/index.html.erb +++ b/app/views/admin/enterprises/index.html.erb @@ -8,6 +8,8 @@ <% end %> +<%= render 'admin/shared/enterprises_sub_menu' %> + <%= form_for @enterprise_set, :url => main_app.bulk_update_admin_enterprises_path do |f| %> diff --git a/app/views/admin/shared/_enterprises_sub_menu.html.haml b/app/views/admin/shared/_enterprises_sub_menu.html.haml new file mode 100644 index 0000000000..57ce5e9194 --- /dev/null +++ b/app/views/admin/shared/_enterprises_sub_menu.html.haml @@ -0,0 +1,4 @@ += content_for :sub_menu do + %ul#sub_nav.inline-menu{"data-hook" => "admin_order_sub_tabs"} + = tab :enterprises, url: main_app.admin_enterprises_path + = tab :relationships, url: main_app.admin_enterprise_relationships_path diff --git a/config/routes.rb b/config/routes.rb index 310d1d9e4d..973cb288cc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -41,6 +41,8 @@ Openfoodnetwork::Application.routes.draw do post :bulk_update, :on => :collection, :as => :bulk_update end + resources :enterprise_relationships + resources :enterprise_fees do post :bulk_update, :on => :collection, :as => :bulk_update end From f7de504d89bb461fe45d6b259070e728c93d4367 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 12:27:58 +1000 Subject: [PATCH 035/139] Add stub angular controller for managing enterprise relationships --- .../enterprise_relationships_controller.js.coffee | 2 ++ .../admin/enterprise_relationships/index.html.haml | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee new file mode 100644 index 0000000000..39a4ad38c4 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -0,0 +1,2 @@ +Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope) -> + $scope.hello = "Hello, angular." diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index 7f2c236d82..aff1fa2e6f 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -3,6 +3,13 @@ = render 'admin/shared/enterprises_sub_menu' -%table#enterprise-relationships - %tr - %td Hello, world. +%div{"ng-app" => "ofn.admin", "ng-controller" => "AdminEnterpriseRelationshipsCtrl"} + %table#enterprise-relationships + %thead + %tr + %th Parent + %th Child + %tbody + %tr + %td {{ hello }} + %td {{ hello }} From 1a854b89eca8b0dda3f6fc5632af68c99e77c4e3 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 14:24:35 +1000 Subject: [PATCH 036/139] Sort enterprise relationships by enterprise name --- app/models/enterprise_relationship.rb | 5 +++++ spec/models/enterprise_relationship_spec.rb | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 spec/models/enterprise_relationship_spec.rb diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index 2cbda1511a..2afd8c8a3e 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -4,4 +4,9 @@ class EnterpriseRelationship < ActiveRecord::Base validates_presence_of :parent_id, :child_id validates_uniqueness_of :child_id, scope: :parent_id + + scope :with_enterprises, + joins('LEFT JOIN enterprises AS parent_enterprises ON parent_enterprises.id = enterprise_relationships.parent_id'). + joins('LEFT JOIN enterprises AS child_enterprises ON child_enterprises.id = enterprise_relationships.child_id') + scope :by_name, with_enterprises.order('parent_enterprises.name, child_enterprises.name') end diff --git a/spec/models/enterprise_relationship_spec.rb b/spec/models/enterprise_relationship_spec.rb new file mode 100644 index 0000000000..7cca07472e --- /dev/null +++ b/spec/models/enterprise_relationship_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe EnterpriseRelationship do + describe "scopes" do + it "sorts by parent, child enterprise name" do + e1 = create(:enterprise, name: 'A') + e2 = create(:enterprise, name: 'B') + e3 = create(:enterprise, name: 'C') + er1 = create(:enterprise_relationship, parent: e1, child: e3) + er2 = create(:enterprise_relationship, parent: e2, child: e1) + er3 = create(:enterprise_relationship, parent: e1, child: e2) + + EnterpriseRelationship.by_name.should == [er3, er1, er2] + end + end +end From 6414ae2972454cffd4171a00cdbd2d8b4a7f21d4 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 14:47:53 +1000 Subject: [PATCH 037/139] Output enterprise relationships as JSON --- .../admin/json/_enterprise_relationships.rabl | 11 +++++++++ .../enterprise_relationships_rabl_spec.rb | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 app/views/admin/json/_enterprise_relationships.rabl create mode 100644 spec/views/admin/json/enterprise_relationships_rabl_spec.rb diff --git a/app/views/admin/json/_enterprise_relationships.rabl b/app/views/admin/json/_enterprise_relationships.rabl new file mode 100644 index 0000000000..1867dd9c56 --- /dev/null +++ b/app/views/admin/json/_enterprise_relationships.rabl @@ -0,0 +1,11 @@ +collection @enterprise_relationships + +attributes :parent_id, :child_id + +node :parent_name do |enterprise_relationship| + enterprise_relationship.parent.name +end + +node :child_name do |enterprise_relationship| + enterprise_relationship.child.name +end diff --git a/spec/views/admin/json/enterprise_relationships_rabl_spec.rb b/spec/views/admin/json/enterprise_relationships_rabl_spec.rb new file mode 100644 index 0000000000..9b72a0d45b --- /dev/null +++ b/spec/views/admin/json/enterprise_relationships_rabl_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe "admin/json/_enterprise_relationships.json.rabl" do + let(:parent) { create(:enterprise) } + let(:child) { create(:enterprise) } + let(:enterprise_relationship) { create(:enterprise_relationship, parent: parent, child: child) } + let(:render) { Rabl.render([enterprise_relationship], 'admin/json/enterprise_relationships', view_path: 'app/views', scope: RablHelper::FakeContext.instance) } + + it "renders a list of enterprise relationships" do + render.should have_json_type(Array).at_path '' + render.should have_json_type(Object).at_path '0' + end + + it "renders enterprise ids" do + render.should be_json_eql(parent.id).at_path '0/parent_id' + render.should be_json_eql(child.id).at_path '0/child_id' + end + + it "renders enterprise names" do + render.should be_json_eql(parent.name.to_json).at_path '0/parent_name' + render.should be_json_eql(child.name.to_json).at_path '0/child_name' + end +end From 61af8204d9f078d69989aae3611683f2920cab87 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 14:49:25 +1000 Subject: [PATCH 038/139] Add spec matcher have_table_row --- spec/support/matchers/table_matchers.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 spec/support/matchers/table_matchers.rb diff --git a/spec/support/matchers/table_matchers.rb b/spec/support/matchers/table_matchers.rb new file mode 100644 index 0000000000..7a06965c67 --- /dev/null +++ b/spec/support/matchers/table_matchers.rb @@ -0,0 +1,16 @@ +RSpec::Matchers.define :have_table_row do |row| + + match do |node| + @row = row + node.all('tr').map { |tr| tr.all('th, td').map(&:text) }.include? row + end + + failure_message_for_should do |text| + "expected to find table row #{@row}" + end + + failure_message_for_should_not do |text| + "expected not to find table row #{@row}" + end + +end From 5f4e4ebeb025e26b2e48e17452c4eb71b3784d2b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 14:49:39 +1000 Subject: [PATCH 039/139] Admin can list enterprise relationships --- ...erprise_relationships_controller.js.coffee | 4 +-- .../enterprise_relationships.js.coffee | 4 +++ .../enterprise_relationships_controller.rb | 2 +- .../enterprise_relationships/index.html.haml | 10 ++++-- .../admin/enterprise_relationships_spec.rb | 32 +++++++++++++++++++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/admin/services/enterprise_relationships.js.coffee create mode 100644 spec/features/admin/enterprise_relationships_spec.rb diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index 39a4ad38c4..cd86cf20d6 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -1,2 +1,2 @@ -Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope) -> - $scope.hello = "Hello, angular." +Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, EnterpriseRelationships) -> + $scope.EnterpriseRelationships = EnterpriseRelationships diff --git a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee new file mode 100644 index 0000000000..0201a9793e --- /dev/null +++ b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee @@ -0,0 +1,4 @@ +Admin.factory 'EnterpriseRelationships', (enterprise_relationships) -> + new class EnterpriseRelationships + constructor: -> + @enterprise_relationships = enterprise_relationships diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 7959b9d9b5..d8dcfdde9d 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -1,7 +1,7 @@ module Admin class EnterpriseRelationshipsController < ResourceController def index - + @enterprise_relationships = EnterpriseRelationship.by_name end end end diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index aff1fa2e6f..897593b22d 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -4,12 +4,16 @@ = render 'admin/shared/enterprises_sub_menu' %div{"ng-app" => "ofn.admin", "ng-controller" => "AdminEnterpriseRelationshipsCtrl"} + :javascript + angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}) + -#%pre {{ EnterpriseRelationships.enterprise_relationships | json }} + %table#enterprise-relationships %thead %tr %th Parent %th Child %tbody - %tr - %td {{ hello }} - %td {{ hello }} + %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} + %td {{ enterprise_relationship.parent_name }} + %td {{ enterprise_relationship.child_name }} diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb new file mode 100644 index 0000000000..ca0a065e5f --- /dev/null +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +feature %q{ + As an Administrator + I want to manage relationships between enterprises +}, js: true do + include AuthenticationWorkflow + include WebHelper + + before { login_to_admin_section } + + scenario "listing relationships" do + # Given some enterprises with relationships + e1, e2, e3, e4 = create(:enterprise), create(:enterprise), create(:enterprise), create(:enterprise) + create(:enterprise_relationship, parent: e1, child: e2) + create(:enterprise_relationship, parent: e3, child: e4) + + # When I go to the relationships page + click_link 'Enterprises' + click_link 'Relationships' + + # Then I should see the relationships + within('table#enterprise-relationships') do + page.should have_table_row [e1.name, e2.name] + page.should have_table_row [e3.name, e4.name] + end + end + + + scenario "creating a relationship" + scenario "deleting a relationship" +end From ba7e29074f825f54150628dbf64be97b02942b71 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 16:20:02 +1000 Subject: [PATCH 040/139] have_table_row waits --- spec/support/matchers/table_matchers.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/support/matchers/table_matchers.rb b/spec/support/matchers/table_matchers.rb index 7a06965c67..71fb297e33 100644 --- a/spec/support/matchers/table_matchers.rb +++ b/spec/support/matchers/table_matchers.rb @@ -2,7 +2,14 @@ RSpec::Matchers.define :have_table_row do |row| match do |node| @row = row - node.all('tr').map { |tr| tr.all('th, td').map(&:text) }.include? row + + begin + wait_until { node.all('tr').map { |tr| tr.all('th, td').map(&:text) }.include? row } + rescue TimeoutError + false + else + true + end end failure_message_for_should do |text| From 3cb55062ccca817215a17bbe65358cd49eab7be2 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 16:20:25 +1000 Subject: [PATCH 041/139] Split enterprise_relationships rabl into show and index --- app/views/admin/json/_enterprise_relationship.rabl | 11 +++++++++++ app/views/admin/json/_enterprise_relationships.rabl | 11 +---------- 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 app/views/admin/json/_enterprise_relationship.rabl diff --git a/app/views/admin/json/_enterprise_relationship.rabl b/app/views/admin/json/_enterprise_relationship.rabl new file mode 100644 index 0000000000..23d08d4c87 --- /dev/null +++ b/app/views/admin/json/_enterprise_relationship.rabl @@ -0,0 +1,11 @@ +object @enterprise_relationship + +attributes :parent_id, :child_id + +node :parent_name do |enterprise_relationship| + enterprise_relationship.parent.name +end + +node :child_name do |enterprise_relationship| + enterprise_relationship.child.name +end diff --git a/app/views/admin/json/_enterprise_relationships.rabl b/app/views/admin/json/_enterprise_relationships.rabl index 1867dd9c56..aad55b9770 100644 --- a/app/views/admin/json/_enterprise_relationships.rabl +++ b/app/views/admin/json/_enterprise_relationships.rabl @@ -1,11 +1,2 @@ collection @enterprise_relationships - -attributes :parent_id, :child_id - -node :parent_name do |enterprise_relationship| - enterprise_relationship.parent.name -end - -node :child_name do |enterprise_relationship| - enterprise_relationship.child.name -end +extends "admin/json/enterprise_relationship" From 9b2a80c6b5320336dfe934071c9e1ba5da369037 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 15 May 2014 16:23:04 +1000 Subject: [PATCH 042/139] Admin can create enterprise relationships --- ...nterprise_relationships_controller.js.coffee | 12 +++++++++++- .../admin/services/enterprises.js.coffee | 4 ++++ .../enterprise_relationships_controller.rb | 11 +++++++++++ .../enterprise_relationships/index.html.haml | 13 +++++++++++-- app/views/admin/json/_enterprises.rabl | 3 +++ .../admin/enterprise_relationships_spec.rb | 17 ++++++++++++++++- 6 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 app/assets/javascripts/admin/services/enterprises.js.coffee create mode 100644 app/views/admin/json/_enterprises.rabl diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index cd86cf20d6..e7934f86fc 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -1,2 +1,12 @@ -Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, EnterpriseRelationships) -> +Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, $http, EnterpriseRelationships, Enterprises) -> $scope.EnterpriseRelationships = EnterpriseRelationships + $scope.Enterprises = Enterprises + + $scope.create = -> + $http.post('/admin/enterprise_relationships', {enterprise_relationship: {parent_id: $scope.parent_id, child_id: $scope.child_id}}).success (data, status) => + $scope.EnterpriseRelationships.enterprise_relationships.unshift({parent_name: data.parent_name, child_name: data.child_name}) + + .error (response, status) => + #@errors = response.errors + #flash.error = response.flash?.error + #flash.success = response.flash?.notice diff --git a/app/assets/javascripts/admin/services/enterprises.js.coffee b/app/assets/javascripts/admin/services/enterprises.js.coffee new file mode 100644 index 0000000000..199b6294c3 --- /dev/null +++ b/app/assets/javascripts/admin/services/enterprises.js.coffee @@ -0,0 +1,4 @@ +Admin.factory 'Enterprises', (enterprises) -> + new class Enterprises + constructor: -> + @enterprises = enterprises diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index d8dcfdde9d..aecc788cc0 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -1,7 +1,18 @@ module Admin class EnterpriseRelationshipsController < ResourceController def index + @enterprises = Enterprise.managed_by(spree_current_user).by_name @enterprise_relationships = EnterpriseRelationship.by_name end + + def create + @enterprise_relationship = EnterpriseRelationship.new params[:enterprise_relationship] + + if @enterprise_relationship.save + render partial: "admin/json/enterprise_relationship", locals: {enterprise_relationship: @enterprise_relationship} + else + render status: 413, json: @enterprise_relationship.errors + end + end end end diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index 897593b22d..abe74c1738 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -5,15 +5,24 @@ %div{"ng-app" => "ofn.admin", "ng-controller" => "AdminEnterpriseRelationshipsCtrl"} :javascript - angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}) - -#%pre {{ EnterpriseRelationships.enterprise_relationships | json }} + angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}); + angular.module('ofn.admin').value('enterprises', #{render partial: "admin/json/enterprises", object: @enterprises}); %table#enterprise-relationships %thead %tr %th Parent %th Child + %th.actions %tbody + %tr + %td + %select{name: "enterprise_relationship_parent_name", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %td + %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %td.actions + %input{type: "button", value: "Create", "ng-click" => "create()"} + %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} %td {{ enterprise_relationship.parent_name }} %td {{ enterprise_relationship.child_name }} diff --git a/app/views/admin/json/_enterprises.rabl b/app/views/admin/json/_enterprises.rabl new file mode 100644 index 0000000000..29e1dc7bf6 --- /dev/null +++ b/app/views/admin/json/_enterprises.rabl @@ -0,0 +1,3 @@ +collection @enterprises + +attributes :id, :name diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index ca0a065e5f..f2421320a6 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -27,6 +27,21 @@ feature %q{ end - scenario "creating a relationship" + scenario "creating a relationship" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + + visit admin_enterprise_relationships_path + select 'One', from: 'enterprise_relationship_parent_name' + select 'Two', from: 'enterprise_relationship_child_name' + click_button 'Create' + + page.should have_table_row [e1.name, e2.name] + EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present + end + + + scenario "error when creating relationship" + scenario "deleting a relationship" end From e40843bccb64ef8d04d8f478e894385f70413b2e Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 11:25:51 +1000 Subject: [PATCH 043/139] Allow error messages without attribute name. Improve enterprise relationship error message. --- Gemfile | 1 + Gemfile.lock | 7 +++++++ app/models/enterprise_relationship.rb | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index af4108c9eb..87566eebfa 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,7 @@ gem 'geocoder' gem 'gmaps4rails' gem 'spinjs-rails' gem 'rack-ssl', :require => 'rack/ssl' +gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg' gem 'foreigner' gem 'immigrant' diff --git a/Gemfile.lock b/Gemfile.lock index 87a0acf967..733ef43572 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,6 +6,12 @@ GIT actionpack (~> 3.0) activemodel (~> 3.0) +GIT + remote: git://github.com/jeremydurham/custom-err-msg.git + revision: 3a8ec9dddc7a5b0aab7c69a6060596de300c68f4 + specs: + custom_error_message (1.1.1) + GIT remote: git://github.com/openfoodfoundation/spree.git revision: da651b40f5c6cdd32e00b060729eb9aefd4f615f @@ -492,6 +498,7 @@ DEPENDENCIES coffee-rails (~> 3.2.1) comfortable_mexican_sofa compass-rails + custom_error_message! database_cleaner (= 0.7.1) db2fog debugger-linecache diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index 2afd8c8a3e..09fff8ba03 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -3,7 +3,7 @@ class EnterpriseRelationship < ActiveRecord::Base belongs_to :child, class_name: 'Enterprise' validates_presence_of :parent_id, :child_id - validates_uniqueness_of :child_id, scope: :parent_id + validates_uniqueness_of :child_id, scope: :parent_id, message: "^That relationship is already established." scope :with_enterprises, joins('LEFT JOIN enterprises AS parent_enterprises ON parent_enterprises.id = enterprise_relationships.parent_id'). From b9a9937541f21bb6347003a9b3a6ac914b510a46 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 11:27:59 +1000 Subject: [PATCH 044/139] Attempting to create a relationship with invalid data shows an error message --- ...erprise_relationships_controller.js.coffee | 5 ++--- .../enterprise_relationships_controller.rb | 2 +- .../enterprise_relationships/index.html.haml | 1 + .../admin/enterprise_relationships_spec.rb | 19 ++++++++++++++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index e7934f86fc..02001bc48f 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -5,8 +5,7 @@ Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, $http, EnterpriseR $scope.create = -> $http.post('/admin/enterprise_relationships', {enterprise_relationship: {parent_id: $scope.parent_id, child_id: $scope.child_id}}).success (data, status) => $scope.EnterpriseRelationships.enterprise_relationships.unshift({parent_name: data.parent_name, child_name: data.child_name}) + $scope.errors = "" .error (response, status) => - #@errors = response.errors - #flash.error = response.flash?.error - #flash.success = response.flash?.notice + $scope.errors = response.errors diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index aecc788cc0..9661470574 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -11,7 +11,7 @@ module Admin if @enterprise_relationship.save render partial: "admin/json/enterprise_relationship", locals: {enterprise_relationship: @enterprise_relationship} else - render status: 413, json: @enterprise_relationship.errors + render status: 400, json: {errors: @enterprise_relationship.errors.full_messages.join(', ')} end end end diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index abe74c1738..050c57cc96 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -22,6 +22,7 @@ %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} %td.actions %input{type: "button", value: "Create", "ng-click" => "create()"} + .errors {{ errors }} %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} %td {{ enterprise_relationship.parent_name }} diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index f2421320a6..ae54f1112c 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -9,6 +9,7 @@ feature %q{ before { login_to_admin_section } + scenario "listing relationships" do # Given some enterprises with relationships e1, e2, e3, e4 = create(:enterprise), create(:enterprise), create(:enterprise), create(:enterprise) @@ -41,7 +42,23 @@ feature %q{ end - scenario "error when creating relationship" + scenario "attempting to create a relationship with invalid data" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + create(:enterprise_relationship, parent: e1, child: e2) + + expect do + # When I attempt to create a duplicate relationship + visit admin_enterprise_relationships_path + select 'One', from: 'enterprise_relationship_parent_name' + select 'Two', from: 'enterprise_relationship_child_name' + click_button 'Create' + + # Then I should see an error message + page.should have_content "That relationship is already established." + end.to change(EnterpriseRelationship, :count).by(0) + end + scenario "deleting a relationship" end From f1df0210915933a2aa82c6c9ed9b899e93ca732d Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 11:28:13 +1000 Subject: [PATCH 045/139] Show enterprise relationships tab as selected --- app/views/admin/shared/_enterprises_sub_menu.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/shared/_enterprises_sub_menu.html.haml b/app/views/admin/shared/_enterprises_sub_menu.html.haml index 57ce5e9194..4a793689b7 100644 --- a/app/views/admin/shared/_enterprises_sub_menu.html.haml +++ b/app/views/admin/shared/_enterprises_sub_menu.html.haml @@ -1,4 +1,4 @@ = content_for :sub_menu do %ul#sub_nav.inline-menu{"data-hook" => "admin_order_sub_tabs"} = tab :enterprises, url: main_app.admin_enterprises_path - = tab :relationships, url: main_app.admin_enterprise_relationships_path + = tab :relationships, url: main_app.admin_enterprise_relationships_path, match_path: '/enterprise_relationships' From aa965e3752d7256686bbbe716b5926de32c94f87 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 11:34:10 +1000 Subject: [PATCH 046/139] Show a CSS3 animation when a row is added --- app/assets/javascripts/admin/admin.js.coffee | 2 +- app/assets/javascripts/admin/all.js | 1 + .../admin/enterprise_relationships.css.sass | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/admin/enterprise_relationships.css.sass diff --git a/app/assets/javascripts/admin/admin.js.coffee b/app/assets/javascripts/admin/admin.js.coffee index ba07bb7933..76154e9e20 100644 --- a/app/assets/javascripts/admin/admin.js.coffee +++ b/app/assets/javascripts/admin/admin.js.coffee @@ -1,3 +1,3 @@ -window.Admin = angular.module("ofn.admin", ["ngResource","ofn.dropdown"]).config ($httpProvider) -> +window.Admin = angular.module("ofn.admin", ["ngResource", "ngAnimate", "ofn.dropdown"]).config ($httpProvider) -> $httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content") $httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*" \ No newline at end of file diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 3cf4fe97e7..99c936c4d7 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -11,6 +11,7 @@ //= require shared/jquery-ui-timepicker-addon //= require angular //= require angular-resource +//= require angular-animate //= require admin/spree_core //= require admin/spree_auth //= require admin/spree_promo diff --git a/app/assets/stylesheets/admin/enterprise_relationships.css.sass b/app/assets/stylesheets/admin/enterprise_relationships.css.sass new file mode 100644 index 0000000000..cffc0b0623 --- /dev/null +++ b/app/assets/stylesheets/admin/enterprise_relationships.css.sass @@ -0,0 +1,20 @@ +// TODO: Provide -moz- and -o- directives +@-webkit-keyframes alert-flash + 0% + background-color: #f9f1ae + + 100% + background-color: #fff + + +table#enterprise-relationships + th.actions, td.actions + width: 16% + .errors + color: #f00 + + tr.ng-enter + -webkit-animation-name: alert-flash + -webkit-animation-duration: 1200ms + -webkit-animation-iteration-count: 1 + -webkit-animation-timing-function: ease-in-out From 5d0680234d5ba003bc47bc0381ea846828cd7780 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 14:44:01 +1000 Subject: [PATCH 047/139] Admin can delete enterprise relationships --- ...erprise_relationships_controller.js.coffee | 6 +++++- .../enterprise_relationships.js.coffee | 7 ++++++- .../enterprise_relationships_controller.rb | 6 ++++++ .../enterprise_relationships/index.html.haml | 2 ++ .../admin/json/_enterprise_relationship.rabl | 2 +- .../admin/enterprise_relationships_spec.rb | 20 +++++++++++++++---- 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index 02001bc48f..51e2dd9ee0 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -4,8 +4,12 @@ Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, $http, EnterpriseR $scope.create = -> $http.post('/admin/enterprise_relationships', {enterprise_relationship: {parent_id: $scope.parent_id, child_id: $scope.child_id}}).success (data, status) => - $scope.EnterpriseRelationships.enterprise_relationships.unshift({parent_name: data.parent_name, child_name: data.child_name}) + $scope.EnterpriseRelationships.enterprise_relationships.unshift(data) $scope.errors = "" .error (response, status) => $scope.errors = response.errors + + $scope.delete = (enterprise_relationship) -> + if confirm("Are you sure?") + $scope.EnterpriseRelationships.delete enterprise_relationship diff --git a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee index 0201a9793e..8af5fef666 100644 --- a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee +++ b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee @@ -1,4 +1,9 @@ -Admin.factory 'EnterpriseRelationships', (enterprise_relationships) -> +Admin.factory 'EnterpriseRelationships', ($http, enterprise_relationships) -> new class EnterpriseRelationships constructor: -> @enterprise_relationships = enterprise_relationships + + delete: (er) -> + ers = @enterprise_relationships + $http.delete('/admin/enterprise_relationships/' + er.id).success (data) -> + ers.splice ers.indexOf(er), 1 diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 9661470574..46ac45a3e5 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -14,5 +14,11 @@ module Admin render status: 400, json: {errors: @enterprise_relationship.errors.full_messages.join(', ')} end end + + def destroy + @enterprise_relationship = EnterpriseRelationship.find params[:id] + @enterprise_relationship.destroy + render nothing: true + end end end diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index 050c57cc96..1992f883d4 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -27,3 +27,5 @@ %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} %td {{ enterprise_relationship.parent_name }} %td {{ enterprise_relationship.child_name }} + %td.actions + %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} diff --git a/app/views/admin/json/_enterprise_relationship.rabl b/app/views/admin/json/_enterprise_relationship.rabl index 23d08d4c87..9be152ec5c 100644 --- a/app/views/admin/json/_enterprise_relationship.rabl +++ b/app/views/admin/json/_enterprise_relationship.rabl @@ -1,6 +1,6 @@ object @enterprise_relationship -attributes :parent_id, :child_id +attributes :id, :parent_id, :child_id node :parent_name do |enterprise_relationship| enterprise_relationship.parent.name diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index ae54f1112c..0161677afe 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -22,8 +22,8 @@ feature %q{ # Then I should see the relationships within('table#enterprise-relationships') do - page.should have_table_row [e1.name, e2.name] - page.should have_table_row [e3.name, e4.name] + page.should have_table_row [e1.name, e2.name, ''] + page.should have_table_row [e3.name, e4.name, ''] end end @@ -37,7 +37,7 @@ feature %q{ select 'Two', from: 'enterprise_relationship_child_name' click_button 'Create' - page.should have_table_row [e1.name, e2.name] + page.should have_table_row [e1.name, e2.name, ''] EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present end @@ -60,5 +60,17 @@ feature %q{ end - scenario "deleting a relationship" + scenario "deleting a relationship" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + er = create(:enterprise_relationship, parent: e1, child: e2) + + visit admin_enterprise_relationships_path + page.should have_table_row [e1.name, e2.name, ''] + + first("a.delete-enterprise-relationship").click + + page.should_not have_table_row [e1.name, e2.name, ''] + EnterpriseRelationship.where(id: er.id).should be_empty + end end From 18886c931f643267109eb4ca8f1e440b4251256b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 16 May 2014 15:04:14 +1000 Subject: [PATCH 048/139] Extract create EnterpriseRelationship to service --- .../enterprise_relationships_controller.js.coffee | 9 ++------- .../services/enterprise_relationships.js.coffee | 15 ++++++++++++--- .../enterprise_relationships/index.html.haml | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index 51e2dd9ee0..c66e79c046 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -1,14 +1,9 @@ -Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, $http, EnterpriseRelationships, Enterprises) -> +Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, EnterpriseRelationships, Enterprises) -> $scope.EnterpriseRelationships = EnterpriseRelationships $scope.Enterprises = Enterprises $scope.create = -> - $http.post('/admin/enterprise_relationships', {enterprise_relationship: {parent_id: $scope.parent_id, child_id: $scope.child_id}}).success (data, status) => - $scope.EnterpriseRelationships.enterprise_relationships.unshift(data) - $scope.errors = "" - - .error (response, status) => - $scope.errors = response.errors + $scope.EnterpriseRelationships.create($scope.parent_id, $scope.child_id) $scope.delete = (enterprise_relationship) -> if confirm("Are you sure?") diff --git a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee index 8af5fef666..0469aa5637 100644 --- a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee +++ b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee @@ -1,9 +1,18 @@ Admin.factory 'EnterpriseRelationships', ($http, enterprise_relationships) -> new class EnterpriseRelationships + create_errors: "" + constructor: -> @enterprise_relationships = enterprise_relationships + create: (parent_id, child_id) -> + $http.post('/admin/enterprise_relationships', {enterprise_relationship: {parent_id: parent_id, child_id: child_id}}).success (data, status) => + @enterprise_relationships.unshift(data) + @create_errors = "" + + .error (response, status) => + @create_errors = response.errors + delete: (er) -> - ers = @enterprise_relationships - $http.delete('/admin/enterprise_relationships/' + er.id).success (data) -> - ers.splice ers.indexOf(er), 1 + $http.delete('/admin/enterprise_relationships/' + er.id).success (data) => + @enterprise_relationships.splice @enterprise_relationships.indexOf(er), 1 diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index 1992f883d4..ec843edc9d 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -22,7 +22,7 @@ %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} %td.actions %input{type: "button", value: "Create", "ng-click" => "create()"} - .errors {{ errors }} + .errors {{ EnterpriseRelationships.create_errors }} %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} %td {{ enterprise_relationship.parent_name }} From 6026a74c7322b7b06594985d78c2d53e67777aeb Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 14:59:24 +1000 Subject: [PATCH 049/139] Table matcher have_table_row does not wait for full duration on should_not --- spec/support/matchers/table_matchers.rb | 34 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/spec/support/matchers/table_matchers.rb b/spec/support/matchers/table_matchers.rb index 71fb297e33..d0eb28d641 100644 --- a/spec/support/matchers/table_matchers.rb +++ b/spec/support/matchers/table_matchers.rb @@ -1,17 +1,37 @@ RSpec::Matchers.define :have_table_row do |row| - match do |node| + match_for_should do |node| @row = row - begin - wait_until { node.all('tr').map { |tr| tr.all('th, td').map(&:text) }.include? row } - rescue TimeoutError - false - else - true + false_on_timeout_error do + wait_until { rows_under(node).include? row } end end + match_for_should_not do |node| + @row = row + + false_on_timeout_error do + # Without this sleep, we trigger capybara's wait when looking up the table, for the full + # period of default_wait_time. + sleep 0.1 + wait_until { !rows_under(node).include? row } + end + end + + def rows_under(node) + node.all('tr').map { |tr| tr.all('th, td').map(&:text) } + end + + def false_on_timeout_error + yield + rescue TimeoutError + false + else + true + end + + failure_message_for_should do |text| "expected to find table row #{@row}" end From 92292c853ddbeb3e9833607081cfd91c84a9adb8 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 15:03:29 +1000 Subject: [PATCH 050/139] Extract partials from enterprise relationships admin page --- .../enterprise_relationships/_data.html.haml | 3 +++ .../_enterprise_relationship.html.haml | 4 ++++ .../enterprise_relationships/_form.html.haml | 8 ++++++++ .../enterprise_relationships/index.html.haml | 19 +++---------------- 4 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 app/views/admin/enterprise_relationships/_data.html.haml create mode 100644 app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml create mode 100644 app/views/admin/enterprise_relationships/_form.html.haml diff --git a/app/views/admin/enterprise_relationships/_data.html.haml b/app/views/admin/enterprise_relationships/_data.html.haml new file mode 100644 index 0000000000..2361755707 --- /dev/null +++ b/app/views/admin/enterprise_relationships/_data.html.haml @@ -0,0 +1,3 @@ +:javascript + angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}); + angular.module('ofn.admin').value('enterprises', #{render partial: "admin/json/enterprises", object: @enterprises}); diff --git a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml new file mode 100644 index 0000000000..237a0f5a38 --- /dev/null +++ b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml @@ -0,0 +1,4 @@ +%td {{ enterprise_relationship.parent_name }} +%td {{ enterprise_relationship.child_name }} +%td.actions + %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} diff --git a/app/views/admin/enterprise_relationships/_form.html.haml b/app/views/admin/enterprise_relationships/_form.html.haml new file mode 100644 index 0000000000..f0b5a9fe72 --- /dev/null +++ b/app/views/admin/enterprise_relationships/_form.html.haml @@ -0,0 +1,8 @@ +%tr + %td + %select{name: "enterprise_relationship_parent_name", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %td + %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %td.actions + %input{type: "button", value: "Create", "ng-click" => "create()"} + .errors {{ EnterpriseRelationships.create_errors }} diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index ec843edc9d..4e5cedb944 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -4,9 +4,7 @@ = render 'admin/shared/enterprises_sub_menu' %div{"ng-app" => "ofn.admin", "ng-controller" => "AdminEnterpriseRelationshipsCtrl"} - :javascript - angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}); - angular.module('ofn.admin').value('enterprises', #{render partial: "admin/json/enterprises", object: @enterprises}); + = render 'data' %table#enterprise-relationships %thead @@ -15,17 +13,6 @@ %th Child %th.actions %tbody - %tr - %td - %select{name: "enterprise_relationship_parent_name", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} - %td - %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} - %td.actions - %input{type: "button", value: "Create", "ng-click" => "create()"} - .errors {{ EnterpriseRelationships.create_errors }} - + = render 'form' %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} - %td {{ enterprise_relationship.parent_name }} - %td {{ enterprise_relationship.child_name }} - %td.actions - %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} + = render 'enterprise_relationship' From 76d1754c32509b9fc0290aec9ffcfe87df196c93 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 15:11:14 +1000 Subject: [PATCH 051/139] Reorder helper method at bottom --- spec/support/matchers/table_matchers.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/support/matchers/table_matchers.rb b/spec/support/matchers/table_matchers.rb index d0eb28d641..146002b751 100644 --- a/spec/support/matchers/table_matchers.rb +++ b/spec/support/matchers/table_matchers.rb @@ -19,6 +19,15 @@ RSpec::Matchers.define :have_table_row do |row| end end + failure_message_for_should do |text| + "expected to find table row #{@row}" + end + + failure_message_for_should_not do |text| + "expected not to find table row #{@row}" + end + + def rows_under(node) node.all('tr').map { |tr| tr.all('th, td').map(&:text) } end @@ -31,13 +40,4 @@ RSpec::Matchers.define :have_table_row do |row| true end - - failure_message_for_should do |text| - "expected to find table row #{@row}" - end - - failure_message_for_should_not do |text| - "expected not to find table row #{@row}" - end - end From 0c647841a6a157bcd134a6183a9781399d089088 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 16:18:07 +1000 Subject: [PATCH 052/139] Add dynamic filter to enterprise relationships --- app/assets/stylesheets/admin/openfoodnetwork.css.scss | 4 +++- app/views/admin/enterprise_relationships/index.html.haml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/admin/openfoodnetwork.css.scss b/app/assets/stylesheets/admin/openfoodnetwork.css.scss index 92092bd136..87983a6bc7 100644 --- a/app/assets/stylesheets/admin/openfoodnetwork.css.scss +++ b/app/assets/stylesheets/admin/openfoodnetwork.css.scss @@ -19,9 +19,11 @@ table .blank-action { } +input.search { + margin-bottom: 1em; +} #new_enterprise_fee_set input.search { float: right; - margin-bottom: 1em; } .ng .ng-invalid.ng-dirty { diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index 4e5cedb944..a12eaaa2b8 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -6,6 +6,8 @@ %div{"ng-app" => "ofn.admin", "ng-controller" => "AdminEnterpriseRelationshipsCtrl"} = render 'data' + %input.search{"ng-model" => "query", "placeholder" => "Search"} + %table#enterprise-relationships %thead %tr @@ -14,5 +16,5 @@ %th.actions %tbody = render 'form' - %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships"} + %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships | filter:query"} = render 'enterprise_relationship' From a049266732561c21b53c33a076f7bd2a0464fe05 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 16:28:27 +1000 Subject: [PATCH 053/139] Replace enterprise relationship parent/child concepts with 'X permits Y' --- .../_enterprise_relationship.html.haml | 1 + app/views/admin/enterprise_relationships/_form.html.haml | 1 + app/views/admin/enterprise_relationships/index.html.haml | 5 ----- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml index 237a0f5a38..3f93027ca1 100644 --- a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml +++ b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml @@ -1,4 +1,5 @@ %td {{ enterprise_relationship.parent_name }} +%td permits %td {{ enterprise_relationship.child_name }} %td.actions %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} diff --git a/app/views/admin/enterprise_relationships/_form.html.haml b/app/views/admin/enterprise_relationships/_form.html.haml index f0b5a9fe72..5cc10b0fe1 100644 --- a/app/views/admin/enterprise_relationships/_form.html.haml +++ b/app/views/admin/enterprise_relationships/_form.html.haml @@ -1,6 +1,7 @@ %tr %td %select{name: "enterprise_relationship_parent_name", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %td permits %td %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} %td.actions diff --git a/app/views/admin/enterprise_relationships/index.html.haml b/app/views/admin/enterprise_relationships/index.html.haml index a12eaaa2b8..e0e289efcf 100644 --- a/app/views/admin/enterprise_relationships/index.html.haml +++ b/app/views/admin/enterprise_relationships/index.html.haml @@ -9,11 +9,6 @@ %input.search{"ng-model" => "query", "placeholder" => "Search"} %table#enterprise-relationships - %thead - %tr - %th Parent - %th Child - %th.actions %tbody = render 'form' %tr{"ng-repeat" => "enterprise_relationship in EnterpriseRelationships.enterprise_relationships | filter:query"} From d8fa30ea6fbe3213a7fa5310e349e7b237536889 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 21 May 2014 16:54:26 +1000 Subject: [PATCH 054/139] Add a sequence to option type position, prevents inconsistent ordering in specs --- spec/factories.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index b2ed52b7a7..6da7824d47 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -190,6 +190,10 @@ FactoryGirl.modify do distributors { [Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise)] } end + factory :option_type do + # Prevent inconsistent ordering in specs when all option types have the same (0) position + sequence(:position) + end end From 48a7b9c3f86e7b6099830ab78592d68dbe6c8468 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 08:50:52 +1000 Subject: [PATCH 055/139] Fix specs from 'X permits Y' table format change --- spec/features/admin/enterprise_relationships_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index 0161677afe..ea95f86ba4 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -22,8 +22,8 @@ feature %q{ # Then I should see the relationships within('table#enterprise-relationships') do - page.should have_table_row [e1.name, e2.name, ''] - page.should have_table_row [e3.name, e4.name, ''] + page.should have_table_row [e1.name, 'permits', e2.name, ''] + page.should have_table_row [e3.name, 'permits', e4.name, ''] end end @@ -37,7 +37,7 @@ feature %q{ select 'Two', from: 'enterprise_relationship_child_name' click_button 'Create' - page.should have_table_row [e1.name, e2.name, ''] + page.should have_table_row [e1.name, 'permits', e2.name, ''] EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present end @@ -66,11 +66,11 @@ feature %q{ er = create(:enterprise_relationship, parent: e1, child: e2) visit admin_enterprise_relationships_path - page.should have_table_row [e1.name, e2.name, ''] + page.should have_table_row [e1.name, 'permits', e2.name, ''] first("a.delete-enterprise-relationship").click - page.should_not have_table_row [e1.name, e2.name, ''] + page.should_not have_table_row [e1.name, 'permits', e2.name, ''] EnterpriseRelationship.where(id: er.id).should be_empty end end From 2d0a42b2c232592d297833250bae71574bf4f0e0 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 14:09:48 +1000 Subject: [PATCH 056/139] Adding working modals --- .../controllers/products/product_node_controller.js.coffee | 2 ++ app/assets/javascripts/darkswarm/directives/modal.js.coffee | 5 ++++- app/views/modals/_producer.html.haml | 5 ++--- .../products/_modal.html.haml => modals/_product.html.haml} | 2 ++ app/views/shop/products/_summary.html.haml | 5 ++--- 5 files changed, 12 insertions(+), 7 deletions(-) rename app/views/{shop/products/_modal.html.haml => modals/_product.html.haml} (73%) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 4ec316e65f..3e24f006ae 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -6,4 +6,6 @@ Darkswarm.controller "ProductNodeCtrl", ($scope) -> else $scope.product.price + $scope.producer = $scope.product.supplier + $scope.hasVariants = $scope.product.variants.length > 0 diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index 73217b3812..6f62c7cb45 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -8,7 +8,10 @@ Darkswarm.directive "ofnModal", ($modal)-> link: (scope, elem, attrs, ctrl, transclude)-> scope.title = attrs.title contents = null - transclude scope, (clone)-> + + # We're using an isolate scope, which is a child of the original scope + # We have to compile the transclude against the original scope, not the isolate + transclude scope.$parent, (clone)-> contents = clone elem.on "click", => diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 691e9378d3..056f9e488f 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,10 +1,9 @@ %ofn-modal{title: "{{ producer.name }}"} - #producer_modal{bindonce: true} + #producer_modal .row .small-12.columns - %img{"bo-src" => "producer.promo_image"} + %img{"ng-src" => "producer.promo_image"} %h3 {{ producer.name }} - .row .small-6.columns %p diff --git a/app/views/shop/products/_modal.html.haml b/app/views/modals/_product.html.haml similarity index 73% rename from app/views/shop/products/_modal.html.haml rename to app/views/modals/_product.html.haml index 29a023704f..acca8f919b 100644 --- a/app/views/shop/products/_modal.html.haml +++ b/app/views/modals/_product.html.haml @@ -1,2 +1,4 @@ %ofn-modal{title: "{{product.name}}"} + + {{ product | json }} {{ product.description }} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index 5e777a5dbb..e41c6ef440 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -6,11 +6,10 @@ %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon.name'", name: "{{product.primary_taxon.name}}"} - {{ product.name}} - -#= render partial: "shop/products/modal" + = render partial: "modals/product" .small-5.columns.summary-header - {{ product.supplier.name }} + = render partial: "modals/producer" .small-2.columns.summary-price.text-right.price %span{"ng-if" => "hasVariants"} From 67e72f4504d04cb4a8894dcb4162f96c1e338014 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 16:39:59 +1000 Subject: [PATCH 057/139] Setting up after_login redirects --- .../authentication/login_controller.js.coffee | 7 ++++-- .../services/authentication_service.js.coffee | 2 +- .../darkswarm/services/redirections.js.coffee | 3 +++ .../admin/overview_controller_decorator.rb | 3 +-- app/helpers/shared_helper.rb | 5 +++++ app/views/json/_injection.html.haml | 2 ++ app/views/layouts/darkswarm.html.haml | 8 +++---- app/views/shared/_current_hub.haml | 2 -- app/views/shared/_current_user.haml | 2 -- spec/features/consumer/authentication_spec.rb | 22 ++++++++++++++++++- 10 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/services/redirections.js.coffee create mode 100644 app/views/json/_injection.html.haml delete mode 100644 app/views/shared/_current_hub.haml delete mode 100644 app/views/shared/_current_user.haml diff --git a/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee index c2211bc033..da625e3d34 100644 --- a/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee @@ -1,8 +1,11 @@ -Darkswarm.controller "LoginCtrl", ($scope, $http, $location, AuthenticationService) -> +Darkswarm.controller "LoginCtrl", ($scope, $http, AuthenticationService, Redirections) -> $scope.path = "/login" $scope.submit = -> $http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).success (data)-> - location.href = location.origin + location.pathname # Strips out hash fragments + if Redirections.after_login + location.href = location.origin + Redirections.after_login + else + location.href = location.origin + location.pathname # Strips out hash fragments .error (data) -> $scope.errors = data.message diff --git a/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee b/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee index eada8bc44b..820d5bde9c 100644 --- a/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location)-> +Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections)-> new class AuthenticationService selectedPath: "/login" diff --git a/app/assets/javascripts/darkswarm/services/redirections.js.coffee b/app/assets/javascripts/darkswarm/services/redirections.js.coffee new file mode 100644 index 0000000000..a479964e9e --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/redirections.js.coffee @@ -0,0 +1,3 @@ +Darkswarm.factory "Redirections", ($location)-> + new class Redirections + after_login: $location.search().after_login diff --git a/app/controllers/spree/admin/overview_controller_decorator.rb b/app/controllers/spree/admin/overview_controller_decorator.rb index 5c96901c1d..a6142d26c0 100644 --- a/app/controllers/spree/admin/overview_controller_decorator.rb +++ b/app/controllers/spree/admin/overview_controller_decorator.rb @@ -13,8 +13,7 @@ Spree::Admin::OverviewController.class_eval do redirect_to '/unauthorized' else store_location - url = respond_to?(:spree_login_path) ? spree_login_path : root_path - redirect_to url + redirect_to root_path(anchor: "login?after_login=#{spree.admin_path}") end end end diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index be1e0ba0f4..828277cb57 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -1,4 +1,9 @@ module SharedHelper + + def inject_json(name, partial) + render "json/injection", name: name, partial: partial + end + def distributor_link_class(distributor) cart = current_order(true) @active_distributors ||= Enterprise.distributors_with_active_order_cycles diff --git a/app/views/json/_injection.html.haml b/app/views/json/_injection.html.haml new file mode 100644 index 0000000000..95b921406b --- /dev/null +++ b/app/views/json/_injection.html.haml @@ -0,0 +1,2 @@ +:javascript + angular.module('Darkswarm').value("#{name.to_s}", #{render "json/#{partial.to_s}"}) diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 5c2dcaee66..edeffafeed 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -15,16 +15,16 @@ = csrf_meta_tags %body.off-canvas{"ng-app" => "Darkswarm"} + = inject_json "currentHub", "current_hub" + = inject_json "user", "current_user" + .off-canvas-wrap{offcanvas: true} .inner-wrap - = render partial: "shared/current_hub" - = render partial: "shared/current_user" = render partial: "shared/menu/menu" + = display_flash_messages %ofn-flash - -#= render "shared/sidebar" - %section{ role: "main" } = yield diff --git a/app/views/shared/_current_hub.haml b/app/views/shared/_current_hub.haml deleted file mode 100644 index 5a0ff7c564..0000000000 --- a/app/views/shared/_current_hub.haml +++ /dev/null @@ -1,2 +0,0 @@ -:javascript - angular.module('Darkswarm').value('currentHub', #{render "json/current_hub"}) diff --git a/app/views/shared/_current_user.haml b/app/views/shared/_current_user.haml deleted file mode 100644 index 9745a71313..0000000000 --- a/app/views/shared/_current_user.haml +++ /dev/null @@ -1,2 +0,0 @@ -:javascript - angular.module('Darkswarm').value('user', #{render "json/current_user"}) diff --git a/spec/features/consumer/authentication_spec.rb b/spec/features/consumer/authentication_spec.rb index 77b60290d1..76e4a20877 100644 --- a/spec/features/consumer/authentication_spec.rb +++ b/spec/features/consumer/authentication_spec.rb @@ -5,7 +5,27 @@ feature "Authentication", js: true do describe "login" do let(:user) { create(:user, password: "password", password_confirmation: "password") } - describe "newskool" do + describe "With redirects" do + scenario "logging in with a redirect set" do + visit groups_path(anchor: "login?after_login=#{producers_path}") + fill_in "Email", with: user.email + fill_in "Password", with: user.password + click_login_button + page.should have_content "Select a producer from the list below" + current_path.should == producers_path + end + + scenario "logging into admin redirects home, then back to admin" do + visit spree.admin_path + fill_in "Email", with: user.email + fill_in "Password", with: user.password + click_login_button + page.should have_content "Dashboard" + current_path.should == spree.admin_path + end + end + + describe "Loggin in from the home page" do before do visit root_path end From f997026796896aea652967cc249e86e56ccecd41 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 16:54:48 +1000 Subject: [PATCH 058/139] Reworking the JS specs --- .../product_node_controller.js.coffee | 1 + .../controllers/products_controller.js.coffee | 2 - .../darkswarm/services/product.js.coffee | 3 + .../hub_node_controller_spec.js.coffee | 11 ---- .../product_node_controller_spec.js.coffee | 24 +++++++ .../products_controller_spec.js.coffee | 64 ++++++------------- .../darkswarm/services/order_spec.js.coffee | 2 + .../{ => services}/product_spec.js.coffee | 2 +- 8 files changed, 50 insertions(+), 59 deletions(-) create mode 100644 spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee rename spec/javascripts/unit/darkswarm/{ => services}/product_spec.js.coffee (86%) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 3e24f006ae..959423e3ca 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -1,4 +1,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope) -> + $scope.price = -> if $scope.product.variants.length > 0 prices = (v.price for v in $scope.product.variants) diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 09df18ca38..323df2fc4e 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -12,5 +12,3 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) - code = e.keyCode || e.which if code == 13 e.preventDefault() - - $scope.productPrice = (product) -> diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index ca31d5e9c0..e58b83bacc 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -2,6 +2,9 @@ Darkswarm.factory 'Product', ($resource) -> new class Product constructor: -> @update() + + # TODO: don't need to scope this into object + # Already on object as far as controller scope is concerned data: products: null loading: true diff --git a/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee index a2d14f5811..cb77cb1703 100644 --- a/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee @@ -19,14 +19,3 @@ describe "HubNodeCtrl", -> expect(scope.current()).toEqual false scope.hub = {id: 99} expect(scope.current()).toEqual true - - it "knows whether selecting this hub will empty the cart", -> - CurrentHub.id = undefined - expect(scope.emptiesCart()).toEqual false - - CurrentHub.id = 99 - scope.hub.id = 99 - expect(scope.emptiesCart()).toEqual false - - scope.hub.id = 1 - expect(scope.emptiesCart()).toEqual true diff --git a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee new file mode 100644 index 0000000000..4b9e404b9e --- /dev/null +++ b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee @@ -0,0 +1,24 @@ +describe "ProductNodeCtrl", -> + ctrl = null + scope = null + product = + id: 99 + price: 10.00 + variants: [] + + beforeEach -> + module('Darkswarm') + inject ($controller) -> + scope = + product: product + ctrl = $controller 'ProductNodeCtrl', {$scope: scope} + + describe "determining the price to display for a product", -> + it "displays the product price when the product does not have variants", -> + expect(scope.price()).toEqual 10.00 + + it "displays the minimum variant price when the product has variants", -> + scope.product = + price: 11 + variants: [{price: 22}, {price: 33}] + expect(scope.price()).toEqual 22 diff --git a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee index 269c8385b8..685d495039 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee @@ -1,47 +1,21 @@ -describe 'All controllers', -> - describe 'ProductsCtrl', -> - ctrl = null - scope = null - event = null - Product = null +describe 'ProductsCtrl', -> + ctrl = null + scope = null + event = null + Product = null - beforeEach -> - module('Darkswarm') - Product = - all: -> - update: -> - data: "testy mctest" - OrderCycle = - order_cycle: {} - - inject ($controller) -> - scope = {} - ctrl = $controller 'ProductsCtrl', {$scope: scope, Product: Product, OrderCycle: OrderCycle} - - it 'fetches products from Product', -> - expect(scope.data).toEqual 'testy mctest' - - describe "determining the price to display for a product", -> - it "displays the product price when the product does not have variants", -> - product = {variants: [], price: 12.34} - expect(scope.productPrice(product)).toEqual 12.34 - - it "displays the minimum variant price when the product has variants", -> - product = - price: 11 - variants: [{price: 22}, {price: 33}] - expect(scope.productPrice(product)).toEqual 22 - - describe 'OrderCycleCtrl', -> - ctrl = null - scope = null - event = null - product_ctrl = null - OrderCycle = null - - beforeEach -> - module 'Darkswarm' + beforeEach -> + module('Darkswarm') + Product = + all: -> + update: -> + data: "testy mctest" + OrderCycle = + order_cycle: {} + + inject ($controller) -> scope = {} - inject ($controller) -> - scope = {} - ctrl = $controller 'OrderCycleCtrl', {$scope: scope} + ctrl = $controller 'ProductsCtrl', {$scope: scope, Product: Product, OrderCycle: OrderCycle} + + it 'fetches products from Product', -> + expect(scope.data).toEqual 'testy mctest' diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index 0462e92952..fedcf23629 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -26,8 +26,10 @@ describe 'Order service', -> } angular.module('Darkswarm').value('order', orderData) module 'Darkswarm' + inject ($injector, _$httpBackend_)-> $httpBackend = _$httpBackend_ + $httpBackend.expectGET("/shop/products").respond 200, [] Order = $injector.get("Order") Navigation = $injector.get("Navigation") flash = $injector.get("flash") diff --git a/spec/javascripts/unit/darkswarm/product_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee similarity index 86% rename from spec/javascripts/unit/darkswarm/product_spec.js.coffee rename to spec/javascripts/unit/darkswarm/services/product_spec.js.coffee index 7108d819af..260074a981 100644 --- a/spec/javascripts/unit/darkswarm/product_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee @@ -10,5 +10,5 @@ describe 'Product service', -> it "Fetches products from the backend on init", -> $httpBackend.expectGET("/shop/products").respond([{test : "cats"}]) - products = Product.all() $httpBackend.flush() + expect(Product.data.products[0].test).toEqual "cats" From 12dfcd0de96f89326497a1af25cbf61be67af5c1 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 10:43:26 +1000 Subject: [PATCH 059/139] Fixing auth workflowsg --- spec/support/request/authentication_workflow.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index e26932bfef..b7975ac7ec 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -33,7 +33,7 @@ module AuthenticationWorkflow :login => 'admin@ofn.org') admin_user.spree_roles << admin_role - login_to_admin_as admin_user + quick_login_as admin_user end def create_enterprise_user(enterprises = []) @@ -47,10 +47,12 @@ module AuthenticationWorkflow end def login_to_admin_as user + quick_login_as user visit spree.admin_path - fill_in 'spree_user_email', :with => user.email - fill_in 'spree_user_password', :with => user.password - click_button 'Login' + #visit spree.admin_path + #fill_in 'spree_user_email', :with => user.email + #fill_in 'spree_user_password', :with => user.password + #click_button 'Login' end def login_to_consumer_section From f6bc1a82beede476cd973e3db064486b8fdc48c3 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 10:54:51 +1000 Subject: [PATCH 060/139] Enterprise user can manage enterprise relationships --- app/models/spree/ability_decorator.rb | 7 ++++++- spec/models/spree/ability_spec.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index ee83e85bf7..44e7d5e02e 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -1,6 +1,6 @@ - class AbilityDecorator include CanCan::Ability + def initialize(user) if user.enterprises.count > 0 @@ -53,6 +53,11 @@ class AbilityDecorator (user.enterprises & shipping_method.distributors).any? end + can [:admin, :index, :create], EnterpriseRelationship + can [:destroy], EnterpriseRelationship do |enterprise_relationship| + user.enterprises.include? enterprise_relationship.parent + end + can [:create], OrderCycle can [:admin, :index, :read, :edit, :update, :bulk_update, :clone], OrderCycle do |order_cycle| user.enterprises.include? order_cycle.coordinator diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index fc13925bae..111c8e5196 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -17,6 +17,9 @@ module Spree let(:p1) { create(:product, supplier: s1, distributors:[d1, d2]) } let(:p2) { create(:product, supplier: s2, distributors:[d1, d2]) } + let(:er1) { create(:enterprise_relationship, parent: s1, child: d1) } + let(:er2) { create(:enterprise_relationship, parent: d1, child: s1) } + subject { user } let(:user) { nil } @@ -72,6 +75,18 @@ module Spree should have_ability([:admin, :index, :read, :create, :edit], for: Spree::Classification) end + it "should be able to read and create enterprise relationships" do + should have_ability([:admin, :index, :create], for: EnterpriseRelationship) + end + + it "should be able to destroy enterprise relationships for its enterprises" do + should have_ability(:destroy, for: er1) + end + + it "should not be able to destroy enterprise relationships for other enterprises" do + should_not have_ability(:destroy, for: er2) + end + end context "when is a distributor enterprise user" do @@ -146,6 +161,18 @@ module Spree it "should be able to read/write ShippingMethods" do should have_ability([:admin, :index, :create, :update, :destroy], for: Spree::ShippingMethod) end + + it "should be able to read and create enterprise relationships" do + should have_ability([:admin, :index, :create], for: EnterpriseRelationship) + end + + it "should be able to destroy enterprise relationships for its enterprises" do + should have_ability(:destroy, for: er2) + end + + it "should not be able to destroy enterprise relationships for other enterprises" do + should_not have_ability(:destroy, for: er1) + end end context 'Order Cycle co-ordinator' do From 66cd5c937f7d03623d023f100be1a3e6897220a4 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 10:59:41 +1000 Subject: [PATCH 061/139] Add a helper to make capybara specs fail fast --- spec/support/request/web_helper.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/support/request/web_helper.rb b/spec/support/request/web_helper.rb index 6add44834e..3a2cb82128 100644 --- a/spec/support/request/web_helper.rb +++ b/spec/support/request/web_helper.rb @@ -1,4 +1,22 @@ module WebHelper + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + # By default, Capybara uses a 30 s wait time, which is more reliable for CI, but too slow + # for TDD. Use this to make tests fail fast. Usage: + # + # describe "foo" do + # use_short_wait + # ... + # end + def use_short_wait + around { |example| Capybara.using_wait_time(2) { example.run } } + end + end + + def current_path_should_be path current_path = URI.parse(current_url).path current_path.should == path From fb05ad57e1ca8f00684fb406270b6bdc90a92ede Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 11:00:29 +1000 Subject: [PATCH 062/139] Tidy up spec helper, clean database before suite run --- spec/spec_helper.rb | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 49a7f39250..4f96a09070 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -71,26 +71,20 @@ RSpec.configure do |config| # rspec-rails. config.infer_base_class_for_anonymous_controllers = false - # ## Filters - # + # Filters config.filter_run_excluding :skip => true, :future => true, :to_figure_out => true - config.before(:each) do - Spree::Address.any_instance.stub(:geocode).and_return([1,1]) + # DatabaseCleaner + config.before(:suite) { DatabaseCleaner.clean_with :deletion, {except: ['spree_countries', 'spree_states']} } + config.before(:each) { DatabaseCleaner.strategy = :transaction } + config.before(:each, js: true) { DatabaseCleaner.strategy = :deletion, {except: ['spree_countries', 'spree_states']} } + config.before(:each) { DatabaseCleaner.start } + config.after(:each) { DatabaseCleaner.clean } - if example.metadata[:js] - DatabaseCleaner.strategy = :deletion, { :except => ['spree_countries', 'spree_states'] } - else - DatabaseCleaner.strategy = :transaction - end - - DatabaseCleaner.start - end - - config.after(:each) do - DatabaseCleaner.clean - end + # Geocoding + config.before(:each) { Spree::Address.any_instance.stub(:geocode).and_return([1,1]) } + # Helpers config.include Rails.application.routes.url_helpers config.include Spree::UrlHelpers config.include Spree::CheckoutHelpers @@ -103,7 +97,7 @@ RSpec.configure do |config| config.include OpenFoodNetwork::DistributionHelper config.include ActionView::Helpers::DateHelper - # Factory girl + # FactoryGirl require 'factory_girl_rails' config.include FactoryGirl::Syntax::Methods From 06955a024fb05d56f26d82fb559e5f724a165e11 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 11:02:03 +1000 Subject: [PATCH 063/139] Enterprise user can only create relationships with their own enterprises as parent --- .../admin/services/enterprises.js.coffee | 5 +- .../enterprise_relationships_controller.rb | 3 +- .../enterprise_relationships/_data.html.haml | 3 +- .../enterprise_relationships/_form.html.haml | 4 +- .../admin/enterprise_relationships_spec.rb | 124 ++++++++++-------- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/app/assets/javascripts/admin/services/enterprises.js.coffee b/app/assets/javascripts/admin/services/enterprises.js.coffee index 199b6294c3..778a915c22 100644 --- a/app/assets/javascripts/admin/services/enterprises.js.coffee +++ b/app/assets/javascripts/admin/services/enterprises.js.coffee @@ -1,4 +1,5 @@ -Admin.factory 'Enterprises', (enterprises) -> +Admin.factory 'Enterprises', (my_enterprises, all_enterprises) -> new class Enterprises constructor: -> - @enterprises = enterprises + @my_enterprises = my_enterprises + @all_enterprises = all_enterprises diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 46ac45a3e5..9bb94b7849 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -1,7 +1,8 @@ module Admin class EnterpriseRelationshipsController < ResourceController def index - @enterprises = Enterprise.managed_by(spree_current_user).by_name + @my_enterprises = Enterprise.managed_by(spree_current_user).by_name + @all_enterprises = Enterprise.by_name @enterprise_relationships = EnterpriseRelationship.by_name end diff --git a/app/views/admin/enterprise_relationships/_data.html.haml b/app/views/admin/enterprise_relationships/_data.html.haml index 2361755707..7c13978e90 100644 --- a/app/views/admin/enterprise_relationships/_data.html.haml +++ b/app/views/admin/enterprise_relationships/_data.html.haml @@ -1,3 +1,4 @@ :javascript angular.module('ofn.admin').value('enterprise_relationships', #{render partial: "admin/json/enterprise_relationships", object: @enterprise_relationships}); - angular.module('ofn.admin').value('enterprises', #{render partial: "admin/json/enterprises", object: @enterprises}); + angular.module('ofn.admin').value('my_enterprises', #{render partial: "admin/json/enterprises", object: @my_enterprises}); + angular.module('ofn.admin').value('all_enterprises', #{render partial: "admin/json/enterprises", object: @all_enterprises}); diff --git a/app/views/admin/enterprise_relationships/_form.html.haml b/app/views/admin/enterprise_relationships/_form.html.haml index 5cc10b0fe1..1a737ec3a5 100644 --- a/app/views/admin/enterprise_relationships/_form.html.haml +++ b/app/views/admin/enterprise_relationships/_form.html.haml @@ -1,9 +1,9 @@ %tr %td - %select{name: "enterprise_relationship_parent_name", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %select{name: "enterprise_relationship_parent_id", "ng-model" => "parent_id", "ng-options" => "e.id as e.name for e in Enterprises.my_enterprises"} %td permits %td - %select{name: "enterprise_relationship_child_name", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.enterprises"} + %select{name: "enterprise_relationship_child_id", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.all_enterprises"} %td.actions %input{type: "button", value: "Create", "ng-click" => "create()"} .errors {{ EnterpriseRelationships.create_errors }} diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index ea95f86ba4..9e17a44979 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -7,70 +7,86 @@ feature %q{ include AuthenticationWorkflow include WebHelper - before { login_to_admin_section } + + context "as a site administrator" do + before { login_to_admin_section } + + scenario "listing relationships" do + # Given some enterprises with relationships + e1, e2, e3, e4 = create(:enterprise), create(:enterprise), create(:enterprise), create(:enterprise) + create(:enterprise_relationship, parent: e1, child: e2) + create(:enterprise_relationship, parent: e3, child: e4) + + # When I go to the relationships page + click_link 'Enterprises' + click_link 'Relationships' + + # Then I should see the relationships + within('table#enterprise-relationships') do + page.should have_table_row [e1.name, 'permits', e2.name, ''] + page.should have_table_row [e3.name, 'permits', e4.name, ''] + end + end - scenario "listing relationships" do - # Given some enterprises with relationships - e1, e2, e3, e4 = create(:enterprise), create(:enterprise), create(:enterprise), create(:enterprise) - create(:enterprise_relationship, parent: e1, child: e2) - create(:enterprise_relationship, parent: e3, child: e4) + scenario "creating a relationship" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') - # When I go to the relationships page - click_link 'Enterprises' - click_link 'Relationships' + visit admin_enterprise_relationships_path + select 'One', from: 'enterprise_relationship_parent_id' + select 'Two', from: 'enterprise_relationship_child_id' + click_button 'Create' - # Then I should see the relationships - within('table#enterprise-relationships') do page.should have_table_row [e1.name, 'permits', e2.name, ''] - page.should have_table_row [e3.name, 'permits', e4.name, ''] + EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present + end + + + scenario "attempting to create a relationship with invalid data" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + create(:enterprise_relationship, parent: e1, child: e2) + + expect do + # When I attempt to create a duplicate relationship + visit admin_enterprise_relationships_path + select 'One', from: 'enterprise_relationship_parent_id' + select 'Two', from: 'enterprise_relationship_child_id' + click_button 'Create' + + # Then I should see an error message + page.should have_content "That relationship is already established." + end.to change(EnterpriseRelationship, :count).by(0) + end + + + scenario "deleting a relationship" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + er = create(:enterprise_relationship, parent: e1, child: e2) + + visit admin_enterprise_relationships_path + page.should have_table_row [e1.name, 'permits', e2.name, ''] + + first("a.delete-enterprise-relationship").click + + page.should_not have_table_row [e1.name, 'permits', e2.name, ''] + EnterpriseRelationship.where(id: er.id).should be_empty end end + context "as an enterprise user" do + let!(:d1) { create(:distributor_enterprise) } + let!(:d2) { create(:distributor_enterprise) } + let(:enterprise_user) { create_enterprise_user([d1]) } - scenario "creating a relationship" do - e1 = create(:enterprise, name: 'One') - e2 = create(:enterprise, name: 'Two') + before { login_to_admin_as enterprise_user } - visit admin_enterprise_relationships_path - select 'One', from: 'enterprise_relationship_parent_name' - select 'Two', from: 'enterprise_relationship_child_name' - click_button 'Create' - - page.should have_table_row [e1.name, 'permits', e2.name, ''] - EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present - end - - - scenario "attempting to create a relationship with invalid data" do - e1 = create(:enterprise, name: 'One') - e2 = create(:enterprise, name: 'Two') - create(:enterprise_relationship, parent: e1, child: e2) - - expect do - # When I attempt to create a duplicate relationship + scenario "enterprise user can only add their own enterprises as parent" do visit admin_enterprise_relationships_path - select 'One', from: 'enterprise_relationship_parent_name' - select 'Two', from: 'enterprise_relationship_child_name' - click_button 'Create' - - # Then I should see an error message - page.should have_content "That relationship is already established." - end.to change(EnterpriseRelationship, :count).by(0) - end - - - scenario "deleting a relationship" do - e1 = create(:enterprise, name: 'One') - e2 = create(:enterprise, name: 'Two') - er = create(:enterprise_relationship, parent: e1, child: e2) - - visit admin_enterprise_relationships_path - page.should have_table_row [e1.name, 'permits', e2.name, ''] - - first("a.delete-enterprise-relationship").click - - page.should_not have_table_row [e1.name, 'permits', e2.name, ''] - EnterpriseRelationship.where(id: er.id).should be_empty + page.should have_select 'enterprise_relationship_parent_id', options: ['', d1.name] + page.should have_select 'enterprise_relationship_child_id', options: ['', d1.name, d2.name] + end end end From d7b4318aff0826c06ac5f22d40c1d0a0b3dce1e2 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 11:25:37 +1000 Subject: [PATCH 064/139] Find enterprise relationships involving any of a number of enterprises --- app/models/enterprise_relationship.rb | 4 ++++ spec/models/enterprise_relationship_spec.rb | 23 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index 09fff8ba03..26bf8fc012 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -9,4 +9,8 @@ class EnterpriseRelationship < ActiveRecord::Base joins('LEFT JOIN enterprises AS parent_enterprises ON parent_enterprises.id = enterprise_relationships.parent_id'). joins('LEFT JOIN enterprises AS child_enterprises ON child_enterprises.id = enterprise_relationships.child_id') scope :by_name, with_enterprises.order('parent_enterprises.name, child_enterprises.name') + + scope :involving_enterprises, ->(enterprises) { + where('parent_id IN (?) OR child_id IN (?)', enterprises, enterprises) + } end diff --git a/spec/models/enterprise_relationship_spec.rb b/spec/models/enterprise_relationship_spec.rb index 7cca07472e..b715674594 100644 --- a/spec/models/enterprise_relationship_spec.rb +++ b/spec/models/enterprise_relationship_spec.rb @@ -2,15 +2,32 @@ require 'spec_helper' describe EnterpriseRelationship do describe "scopes" do + let(:e1) { create(:enterprise, name: 'A') } + let(:e2) { create(:enterprise, name: 'B') } + let(:e3) { create(:enterprise, name: 'C') } + it "sorts by parent, child enterprise name" do - e1 = create(:enterprise, name: 'A') - e2 = create(:enterprise, name: 'B') - e3 = create(:enterprise, name: 'C') er1 = create(:enterprise_relationship, parent: e1, child: e3) er2 = create(:enterprise_relationship, parent: e2, child: e1) er3 = create(:enterprise_relationship, parent: e1, child: e2) EnterpriseRelationship.by_name.should == [er3, er1, er2] end + + describe "finding relationships involving some enterprises" do + let!(:er) { create(:enterprise_relationship, parent: e1, child: e2) } + + it "returns relationships where an enterprise is the parent" do + EnterpriseRelationship.involving_enterprises([e1]).should == [er] + end + + it "returns relationships where an enterprise is the child" do + EnterpriseRelationship.involving_enterprises([e2]).should == [er] + end + + it "does not return other relationships" do + EnterpriseRelationship.involving_enterprises([e3]).should == [] + end + end end end From c2f762d570647ec7d1bd39de360ec9b0ae94cae9 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 11:27:19 +1000 Subject: [PATCH 065/139] Enterprise user can only see relationships involving their enterprises --- .../enterprise_relationships_controller.rb | 2 +- .../admin/enterprise_relationships_spec.rb | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/enterprise_relationships_controller.rb b/app/controllers/admin/enterprise_relationships_controller.rb index 9bb94b7849..212bf3849d 100644 --- a/app/controllers/admin/enterprise_relationships_controller.rb +++ b/app/controllers/admin/enterprise_relationships_controller.rb @@ -3,7 +3,7 @@ module Admin def index @my_enterprises = Enterprise.managed_by(spree_current_user).by_name @all_enterprises = Enterprise.by_name - @enterprise_relationships = EnterpriseRelationship.by_name + @enterprise_relationships = EnterpriseRelationship.by_name.involving_enterprises @my_enterprises end def create diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index 9e17a44979..7e15a243c8 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -76,17 +76,32 @@ feature %q{ end end + context "as an enterprise user" do let!(:d1) { create(:distributor_enterprise) } let!(:d2) { create(:distributor_enterprise) } + let!(:d3) { create(:distributor_enterprise) } let(:enterprise_user) { create_enterprise_user([d1]) } + let!(:er1) { create(:enterprise_relationship, parent: d1, child: d2) } + let!(:er2) { create(:enterprise_relationship, parent: d2, child: d1) } + let!(:er3) { create(:enterprise_relationship, parent: d2, child: d3) } + before { login_to_admin_as enterprise_user } + scenario "enterprise user can only see relationships involving their enterprises" do + visit admin_enterprise_relationships_path + + page.should have_table_row [d1.name, 'permits', d2.name, ''] + page.should have_table_row [d2.name, 'permits', d1.name, ''] + page.should_not have_table_row [d2.name, 'permits', d3.name, ''] + end + + scenario "enterprise user can only add their own enterprises as parent" do visit admin_enterprise_relationships_path page.should have_select 'enterprise_relationship_parent_id', options: ['', d1.name] - page.should have_select 'enterprise_relationship_child_id', options: ['', d1.name, d2.name] + page.should have_select 'enterprise_relationship_child_id', options: ['', d1.name, d2.name, d3.name] end end end From a16f726377306ddabee778c5a70bc132ecf93805 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 May 2014 11:32:37 +1000 Subject: [PATCH 066/139] Extract have_relationship test --- .../admin/enterprise_relationships_spec.rb | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb index 7e15a243c8..1443cd4c34 100644 --- a/spec/features/admin/enterprise_relationships_spec.rb +++ b/spec/features/admin/enterprise_relationships_spec.rb @@ -23,8 +23,8 @@ feature %q{ # Then I should see the relationships within('table#enterprise-relationships') do - page.should have_table_row [e1.name, 'permits', e2.name, ''] - page.should have_table_row [e3.name, 'permits', e4.name, ''] + page.should have_relationship e1, e2 + page.should have_relationship e3, e4 end end @@ -38,7 +38,7 @@ feature %q{ select 'Two', from: 'enterprise_relationship_child_id' click_button 'Create' - page.should have_table_row [e1.name, 'permits', e2.name, ''] + page.should have_relationship e1, e2 EnterpriseRelationship.where(parent_id: e1, child_id: e2).should be_present end @@ -67,11 +67,11 @@ feature %q{ er = create(:enterprise_relationship, parent: e1, child: e2) visit admin_enterprise_relationships_path - page.should have_table_row [e1.name, 'permits', e2.name, ''] + page.should have_relationship e1, e2 first("a.delete-enterprise-relationship").click - page.should_not have_table_row [e1.name, 'permits', e2.name, ''] + page.should_not have_relationship e1, e2 EnterpriseRelationship.where(id: er.id).should be_empty end end @@ -92,9 +92,9 @@ feature %q{ scenario "enterprise user can only see relationships involving their enterprises" do visit admin_enterprise_relationships_path - page.should have_table_row [d1.name, 'permits', d2.name, ''] - page.should have_table_row [d2.name, 'permits', d1.name, ''] - page.should_not have_table_row [d2.name, 'permits', d3.name, ''] + page.should have_relationship d1, d2 + page.should have_relationship d2, d1 + page.should_not have_relationship d2, d3 end @@ -104,4 +104,11 @@ feature %q{ page.should have_select 'enterprise_relationship_child_id', options: ['', d1.name, d2.name, d3.name] end end + + + private + + def have_relationship(parent, child) + have_table_row [parent.name, 'permits', child.name, ''] + end end From 34c31afabe853c4dadeb9867e4215d8f716240c1 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 11:34:46 +1000 Subject: [PATCH 067/139] Adding large image --- app/views/shop/products.rabl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index c79157dae5..c8b5d5398c 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -22,7 +22,8 @@ child :master => :master do child :images => :images do attributes :id, :alt node do |img| - {:small_url => img.attachment.url(:small, false)} + {:small_url => img.attachment.url(:small, false), + :large_url => img.attachment.url(:large, false)} end end end From 70f549e92a6308b94cd024b9e3e7603fa87d8005 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 11:46:06 +1000 Subject: [PATCH 068/139] Patching our modified admin login --- spec/support/request/authentication_workflow.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb index b7975ac7ec..add8de9f28 100644 --- a/spec/support/request/authentication_workflow.rb +++ b/spec/support/request/authentication_workflow.rb @@ -34,6 +34,7 @@ module AuthenticationWorkflow admin_user.spree_roles << admin_role quick_login_as admin_user + visit spree.admin_path end def create_enterprise_user(enterprises = []) From c69a4a5f1a023ef1589b5a251a1898f585885a26 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 12:12:10 +1000 Subject: [PATCH 069/139] Adding social media links --- app/views/admin/enterprises/_form.html.haml | 21 +++++++++++++------ ...2015012_add_social_media_to_enterprises.rb | 7 +++++++ db/schema.rb | 5 ++++- spec/features/admin/enterprises_spec.rb | 2 ++ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20140522015012_add_social_media_to_enterprises.rb diff --git a/app/views/admin/enterprises/_form.html.haml b/app/views/admin/enterprises/_form.html.haml index ab795d21fd..161f43d34d 100644 --- a/app/views/admin/enterprises/_form.html.haml +++ b/app/views/admin/enterprises/_form.html.haml @@ -116,12 +116,21 @@ = f.label :website .omega.eight.columns = f.text_field :website, { placeholder: "eg. www.truffles.com"} - -# TODO: Facebook model field - -#.row - -# .alpha.two.columns - -# = f.label :facebook, 'Facebook' - -# .omega.four.columns - -# = f.text_field :facebook + .row + .alpha.two.columns + = f.label :facebook, 'Facebook' + .omega.four.columns + = f.text_field :facebook + .row + .alpha.two.columns + = f.label :instagram, 'Instagram' + .omega.four.columns + = f.text_field :instagram + .row + .alpha.two.columns + = f.label :linkedin, 'LinkedIn' + .omega.four.columns + = f.text_field :linkedin .row .alpha.three.columns = f.label :twitter diff --git a/db/migrate/20140522015012_add_social_media_to_enterprises.rb b/db/migrate/20140522015012_add_social_media_to_enterprises.rb new file mode 100644 index 0000000000..9ca88cf0dc --- /dev/null +++ b/db/migrate/20140522015012_add_social_media_to_enterprises.rb @@ -0,0 +1,7 @@ +class AddSocialMediaToEnterprises < ActiveRecord::Migration + def change + add_column :enterprises, :facebook, :string + add_column :enterprises, :instagram, :string + add_column :enterprises, :linkedin, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 5394fcbd61..77df8baf75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140516045323) do +ActiveRecord::Schema.define(:version => 20140522015012) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -250,6 +250,9 @@ ActiveRecord::Schema.define(:version => 20140516045323) do t.integer "promo_image_file_size" t.datetime "promo_image_updated_at" t.boolean "visible", :default => true + t.string "facebook" + t.string "instagram" + t.string "linkedin" end add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id" diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb index f6d5e32fec..765a6251bf 100644 --- a/spec/features/admin/enterprises_spec.rb +++ b/spec/features/admin/enterprises_spec.rb @@ -76,6 +76,8 @@ feature %q{ fill_in 'enterprise_email', :with => 'info@eaterprises.com.au' fill_in 'enterprise_website', :with => 'http://eaterprises.com.au' fill_in 'enterprise_twitter', :with => '@eaterprises' + fill_in 'enterprise_facebook', :with => 'facebook.com/eaterprises' + fill_in 'enterprise_instagram', :with => 'eaterprises' fill_in 'enterprise_abn', :with => '09812309823' fill_in 'enterprise_acn', :with => '' From d6512a78d486a08e698c5529a2afe875a21fa46f Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 12:39:52 +1000 Subject: [PATCH 070/139] Removing position fixed --- .../shared/mm-foundation-tpls-0.2.0-SNAPSHOT.js | 2 +- .../assets/javascripts/mm-foundation-tpls-0.1.0.min.js | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 vendor/assets/javascripts/mm-foundation-tpls-0.1.0.min.js diff --git a/app/assets/javascripts/shared/mm-foundation-tpls-0.2.0-SNAPSHOT.js b/app/assets/javascripts/shared/mm-foundation-tpls-0.2.0-SNAPSHOT.js index d4fb9527d8..972b74247f 100644 --- a/app/assets/javascripts/shared/mm-foundation-tpls-0.2.0-SNAPSHOT.js +++ b/app/assets/javascripts/shared/mm-foundation-tpls-0.2.0-SNAPSHOT.js @@ -2477,7 +2477,7 @@ angular.module("template/modal/window.html", []).run(["$templateCache", function $templateCache.put("template/modal/window.html", "
\n" + + " style=\"display: block; visibility: visible\">\n" + "
\n" + "
\n" + ""); diff --git a/vendor/assets/javascripts/mm-foundation-tpls-0.1.0.min.js b/vendor/assets/javascripts/mm-foundation-tpls-0.1.0.min.js deleted file mode 100644 index 5fa09b885a..0000000000 --- a/vendor/assets/javascripts/mm-foundation-tpls-0.1.0.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * angular-mm-foundation - * http://madmimi.github.io/angular-foundation/ - - * Version: 0.1.0 - 2014-02-05 - * License: MIT - */ -angular.module("mm.foundation",["mm.foundation.tpls","mm.foundation.accordion","mm.foundation.alert","mm.foundation.bindHtml","mm.foundation.buttons","mm.foundation.position","mm.foundation.dropdownToggle","mm.foundation.transition","mm.foundation.modal","mm.foundation.pagination","mm.foundation.tooltip","mm.foundation.popover","mm.foundation.progressbar","mm.foundation.rating","mm.foundation.tabs","mm.foundation.tour","mm.foundation.typeahead"]),angular.module("mm.foundation.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/tour/tour.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]),angular.module("mm.foundation.accordion",[]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(this.groups.indexOf(a),1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",["$parse",function(a){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(b,c,d,e){var f,g;e.addGroup(b),b.isOpen=!1,d.isOpen&&(f=a(d.isOpen),g=f.assign,b.$parent.$watch(f,function(a){b.isOpen=!!a})),b.$watch("isOpen",function(a){a&&e.closeOthers(b),g&&g(b.$parent,a)})}}}]).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",compile:function(a,b,c){return function(a,b,d,e){e.setHeading(c(a,function(){}))}}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(a,b,c,d){a.$watch(function(){return d[c.accordionTransclude]},function(a){a&&(b.html(""),b.append(a))})}}}),angular.module("mm.foundation.alert",[]).controller("AlertController",["$scope","$attrs",function(a,b){a.closeable="close"in b}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"=",close:"&"}}}),angular.module("mm.foundation.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(a,b,c){b.addClass("ng-binding").data("$binding",c.bindHtmlUnsafe),a.$watch(c.bindHtmlUnsafe,function(a){b.html(a||"")})}}),angular.module("mm.foundation.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(a){this.activeClass=a.activeClass,this.toggleEvent=a.toggleEvent}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){var e=d[0],f=d[1];f.$render=function(){b.toggleClass(e.activeClass,angular.equals(f.$modelValue,a.$eval(c.btnRadio)))},b.bind(e.toggleEvent,function(){b.hasClass(e.activeClass)||a.$apply(function(){f.$setViewValue(a.$eval(c.btnRadio)),f.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){var d=a.$eval(b);return angular.isDefined(d)?d:c}var h=d[0],i=d[1];i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.bind(h.toggleEvent,function(){a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("mm.foundation.position",[]).factory("$position",["$document","$window",function(a,b){function c(a,c){return a.currentStyle?a.currentStyle[c]:b.getComputedStyle?b.getComputedStyle(a)[c]:a.style[c]}function d(a){return"static"===(c(a,"position")||"static")}var e=function(b){for(var c=a[0],e=b.offsetParent||c;e&&e!==c&&d(e);)e=e.offsetParent;return e||c};return{position:function(b){var c=this.offset(b),d={top:0,left:0},f=e(b[0]);f!=a[0]&&(d=this.offset(angular.element(f)),d.top+=f.clientTop-f.scrollTop,d.left+=f.clientLeft-f.scrollLeft);var g=b[0].getBoundingClientRect();return{width:g.width||b.prop("offsetWidth"),height:g.height||b.prop("offsetHeight"),top:c.top-d.top,left:c.left-d.left}},offset:function(c){var d=c[0].getBoundingClientRect();return{width:d.width||c.prop("offsetWidth"),height:d.height||c.prop("offsetHeight"),top:d.top+(b.pageYOffset||a[0].body.scrollTop||a[0].documentElement.scrollTop),left:d.left+(b.pageXOffset||a[0].body.scrollLeft||a[0].documentElement.scrollLeft)}}}}]),angular.module("mm.foundation.dropdownToggle",["mm.foundation.position"]).directive("dropdownToggle",["$document","$location","$position",function(a,b,c){var d=null,e=angular.noop;return{restrict:"CA",scope:{dropdownToggle:"@"},link:function(b,f){var g=angular.element(a[0].querySelector(b.dropdownToggle));b.$watch("$location.path",function(){e()}),g.css("display","none").bind("click",function(){e()}),f.bind("click",function(b){var h=f===d;if(b.preventDefault(),b.stopPropagation(),d&&e(),!h&&!f.hasClass("disabled")&&!f.prop("disabled")){g.css("display","block");var i=c.offset(f),j=c.offset(angular.element(g[0].offsetParent));g.css({left:i.left-j.left+"px",top:i.top-j.top+i.height+"px"}),d=f,e=function(b){b&&(b.preventDefault(),b.stopPropagation()),a.unbind("click",e),g.css("display","none"),e=angular.noop,d=null},a.bind("click",e)}})}}}]),angular.module("mm.foundation.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(a,b,c){function d(a){for(var b in a)if(void 0!==f.style[b])return a[b]}var e=function(d,f,g){g=g||{};var h=a.defer(),i=e[g.animation?"animationEndEventName":"transitionEndEventName"],j=function(){c.$apply(function(){d.unbind(i,j),h.resolve(d)})};return i&&d.bind(i,j),b(function(){angular.isString(f)?d.addClass(f):angular.isFunction(f)?f(d):angular.isObject(f)&&d.css(f),i||h.resolve(d)}),h.promise.cancel=function(){i&&d.unbind(i,j),h.reject("Transition cancelled")},h.promise},f=document.createElement("trans"),g={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},h={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return e.transitionEndEventName=d(g),e.animationEndEventName=d(h),e}]),angular.module("mm.foundation.modal",["mm.foundation.transition"]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c0)}function i(){if(k&&-1==g()){var a=l;j(k,l,150,function(){a.$destroy(),a=null}),k=void 0,l=void 0}}function j(c,d,e,f){function g(){g.done||(g.done=!0,c.remove(),f&&f())}d.animate=!1;var h=a.transitionEndEventName;if(h){var i=b(g,e);c.bind(h,function(){b.cancel(i),g(),d.$apply()})}else b(g,0)}var k,l,m="modal-open",n=f.createNew(),o={};return e.$watch(g,function(a){l&&(l.index=a)}),c.bind("keydown",function(a){var b;27===a.which&&(b=n.top(),b&&b.value.keyboard&&e.$apply(function(){o.dismiss(b.key)}))}),o.open=function(a,b){n.add(a,{deferred:b.deferred,modalScope:b.scope,backdrop:b.backdrop,keyboard:b.keyboard});var f=c.find("body").eq(0),h=g();h>=0&&!k&&(l=e.$new(!0),l.index=h,k=d("
")(l),f.append(k));var i=angular.element("
");i.attr("window-class",b.windowClass),i.attr("index",n.length()-1),i.attr("animate","animate"),i.html(b.content);var j=d(i)(b.scope);n.top().value.modalDomEl=j,f.append(j),f.addClass(m)},o.close=function(a,b){var c=n.get(a).value;c&&(c.deferred.resolve(b),h(a))},o.dismiss=function(a,b){var c=n.get(a).value;c&&(c.deferred.reject(b),h(a))},o.dismissAll=function(a){for(var b=this.getTop();b;)this.dismiss(b.key,a),b=this.getTop()},o.getTop=function(){return n.top()},o}]).provider("$modal",function(){var a={options:{backdrop:!0,keyboard:!0},$get:["$injector","$rootScope","$q","$http","$templateCache","$controller","$modalStack",function(b,c,d,e,f,g,h){function i(a){return a.template?d.when(a.template):e.get(a.templateUrl,{cache:f}).then(function(a){return a.data})}function j(a){var c=[];return angular.forEach(a,function(a){(angular.isFunction(a)||angular.isArray(a))&&c.push(d.when(b.invoke(a)))}),c}var k={};return k.open=function(b){var e=d.defer(),f=d.defer(),k={result:e.promise,opened:f.promise,close:function(a){h.close(k,a)},dismiss:function(a){h.dismiss(k,a)}};if(b=angular.extend({},a.options,b),b.resolve=b.resolve||{},!b.template&&!b.templateUrl)throw new Error("One of template or templateUrl options is required.");var l=d.all([i(b)].concat(j(b.resolve)));return l.then(function(a){var d=(b.scope||c).$new();d.$close=k.close,d.$dismiss=k.dismiss;var f,i={},j=1;b.controller&&(i.$scope=d,i.$modalInstance=k,angular.forEach(b.resolve,function(b,c){i[c]=a[j++]}),f=g(b.controller,i)),h.open(k,{scope:d,deferred:e,content:a[0],backdrop:b.backdrop,keyboard:b.keyboard,windowClass:b.windowClass})},function(a){e.reject(a)}),l.then(function(){f.resolve(!0)},function(){f.reject(!1)}),k},k}]};return a}),angular.module("mm.foundation.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse","$interpolate",function(a,b,c,d){var e=this,f=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(d){b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){e.itemsPerPage=parseInt(b,10),a.totalPages=e.calculateTotalPages()}):this.itemsPerPage=d},this.noPrevious=function(){return 1===this.page},this.noNext=function(){return this.page===a.totalPages},this.isActive=function(a){return this.page===a},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.getAttributeValue=function(b,c,e){return angular.isDefined(b)?e?d(b)(a.$parent):a.$parent.$eval(b):c},this.render=function(){this.page=parseInt(a.page,10)||1,this.page>0&&this.page<=a.totalPages&&(a.pages=this.getPages(this.page,a.totalPages))},a.selectPage=function(b){!e.isActive(b)&&b>0&&b<=a.totalPages&&(a.page=b,a.onSelectPage({page:b}))},a.$watch("page",function(){e.render()}),a.$watch("totalItems",function(){a.totalPages=e.calculateTotalPages()}),a.$watch("totalPages",function(b){f(a.$parent,b),e.page>b?a.selectPage(b):e.render()})}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(a,b){return{restrict:"EA",scope:{page:"=",totalItems:"=",onSelectPage:" &"},controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(c,d,e,f){function g(a,b,c,d){return{number:a,text:b,active:c,disabled:d}}var h,i=f.getAttributeValue(e.boundaryLinks,b.boundaryLinks),j=f.getAttributeValue(e.directionLinks,b.directionLinks),k=f.getAttributeValue(e.firstText,b.firstText,!0),l=f.getAttributeValue(e.previousText,b.previousText,!0),m=f.getAttributeValue(e.nextText,b.nextText,!0),n=f.getAttributeValue(e.lastText,b.lastText,!0),o=f.getAttributeValue(e.rotate,b.rotate);f.init(b.itemsPerPage),e.maxSize&&c.$parent.$watch(a(e.maxSize),function(a){h=parseInt(a,10),f.render()}),f.getPages=function(a,b){var c=[],d=1,e=b,p=angular.isDefined(h)&&b>h;p&&(o?(d=Math.max(a-Math.floor(h/2),1),e=d+h-1,e>b&&(e=b,d=e-h+1)):(d=(Math.ceil(a/h)-1)*h+1,e=Math.min(d+h-1,b)));for(var q=d;e>=q;q++){var r=g(q,q,f.isActive(q),!1);c.push(r)}if(p&&!o){if(d>1){var s=g(d-1,"...",!1,!1);c.unshift(s)}if(b>e){var t=g(e+1,"...",!1,!1);c.push(t)}}if(j){var u=g(a-1,l,!1,f.noPrevious());c.unshift(u);var v=g(a+1,m,!1,f.noNext());c.push(v)}if(i){var w=g(1,k,!1,f.noPrevious());c.unshift(w);var x=g(b,n,!1,f.noNext());c.push(x)}return c}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(a){return{restrict:"EA",scope:{page:"=",totalItems:"=",onSelectPage:" &"},controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(b,c,d,e){function f(a,b,c,d,e){return{number:a,text:b,disabled:c,previous:i&&d,next:i&&e}}var g=e.getAttributeValue(d.previousText,a.previousText,!0),h=e.getAttributeValue(d.nextText,a.nextText,!0),i=e.getAttributeValue(d.align,a.align);e.init(a.itemsPerPage),e.getPages=function(a){return[f(a-1,g,e.noPrevious(),!0,!1),f(a+1,h,e.noNext(),!1,!0)]}}}}]),angular.module("mm.foundation.tooltip",["mm.foundation.position","mm.foundation.bindHtml"]).provider("$tooltip",function(){function a(a){var b=/[A-Z]/g,c="-";return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",animation:!0,popupDelay:0},c={mouseenter:"mouseleave",click:"click",focus:"blur"},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$parse","$document","$position","$interpolate",function(e,f,g,h,i,j,k){return function(e,l,m){function n(a){var b=a||o.trigger||m,d=c[b]||b;return{show:b,hide:d}}var o=angular.extend({},b,d),p=a(e),q=k.startSymbol(),r=k.endSymbol(),s="
';return{restrict:"EA",scope:!0,compile:function(){var a=f(s);return function(b,c,d){function f(){b.tt_isOpen?m():k()}function k(){(!z||b.$eval(d[l+"Enable"]))&&(b.tt_popupDelay?(v=g(p,b.tt_popupDelay,!1),v.then(function(a){a()})):p()())}function m(){b.$apply(function(){q()})}function p(){return b.tt_content?(r(),u&&g.cancel(u),t.css({top:0,left:0,display:"block"}),w?i.find("body").append(t):c.after(t),A(),b.tt_isOpen=!0,b.$digest(),A):angular.noop}function q(){b.tt_isOpen=!1,g.cancel(v),b.tt_animation?u=g(s,500):s()}function r(){t&&s(),t=a(b,function(){}),b.$digest()}function s(){t&&(t.remove(),t=null)}var t,u,v,w=angular.isDefined(o.appendToBody)?o.appendToBody:!1,x=n(void 0),y=!1,z=angular.isDefined(d[l+"Enable"]),A=function(){var a,d,e,f;switch(a=w?j.offset(c):j.position(c),d=t.prop("offsetWidth"),e=t.prop("offsetHeight"),b.tt_placement){case"right":f={top:a.top+a.height/2-e/2,left:a.left+a.width+10};break;case"bottom":f={top:a.top+a.height+10,left:a.left};break;case"left":f={top:a.top+a.height/2-e/2,left:a.left-d-10};break;default:f={top:a.top-e-10,left:a.left}}f.top+="px",f.left+="px",t.css(f)};b.tt_isOpen=!1,d.$observe(e,function(a){b.tt_content=a,!a&&b.tt_isOpen&&q()}),d.$observe(l+"Title",function(a){b.tt_title=a}),d.$observe(l+"Placement",function(a){b.tt_placement=angular.isDefined(a)?a:o.placement}),d.$observe(l+"PopupDelay",function(a){var c=parseInt(a,10);b.tt_popupDelay=isNaN(c)?o.popupDelay:c});var B=function(){y&&(c.unbind(x.show,k),c.unbind(x.hide,m))},C=function(){};d.$observe(l+"Trigger",function(a){B(),C(),x=n(a),angular.isFunction(x.show)?C=b.$watch(function(){return x.show(b,c,d)},function(a){return g(a?p:q)}):x.show===x.hide?c.bind(x.show,f):(c.bind(x.show,k),c.bind(x.hide,m)),y=!0});var D=b.$eval(d[l+"Animation"]);b.tt_animation=angular.isDefined(D)?!!D:o.animation,d.$observe(l+"AppendToBody",function(a){w=angular.isDefined(a)?h(a)(b):w}),w&&b.$on("$locationChangeSuccess",function(){b.tt_isOpen&&q()}),b.$on("$destroy",function(){g.cancel(u),g.cancel(v),B(),C(),s()})}}}}}]}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(a){return a("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(a){return a("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("mm.foundation.popover",["mm.foundation.tooltip"]).directive("popoverPopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@",content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html"}}).directive("popover",["$tooltip",function(a){return a("popover","popover","click")}]),angular.module("mm.foundation.progressbar",["mm.foundation.transition"]).constant("progressConfig",{animate:!0,max:100}).controller("ProgressController",["$scope","$attrs","progressConfig","$transition",function(a,b,c,d){var e=this,f=[],g=angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max,h=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.addBar=function(a,b){var c=0,d=a.$parent.$index;angular.isDefined(d)&&f[d]&&(c=f[d].value),f.push(a),this.update(b,a.value,c),a.$watch("value",function(a,c){a!==c&&e.update(b,a,c)}),a.$on("$destroy",function(){e.removeBar(a)})},this.update=function(a,b,c){var e=this.getPercentage(b);h?(a.css("width",this.getPercentage(c)+"%"),d(a,{width:e+"%"})):a.css({transition:"none",width:e+"%"})},this.removeBar=function(a){f.splice(f.indexOf(a),1)},this.getPercentage=function(a){return Math.round(100*a/g)}}]).directive("progress",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",require:"progress",scope:{},template:'
'}}).directive("bar",function(){return{restrict:"EA",replace:!0,transclude:!0,require:"^progress",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b)}}}).directive("progressbar",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]))}}}),angular.module("mm.foundation.rating",[]).constant("ratingConfig",{max:5,stateOn:null,stateOff:null}).controller("RatingController",["$scope","$attrs","$parse","ratingConfig",function(a,b,c,d){this.maxRange=angular.isDefined(b.max)?a.$parent.$eval(b.max):d.max,this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):d.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):d.stateOff,this.createRateObjects=function(a){for(var b={stateOn:this.stateOn,stateOff:this.stateOff},c=0,d=a.length;d>c;c++)a[c]=angular.extend({index:c},b,a[c]);return a},a.range=this.createRateObjects(angular.isDefined(b.ratingStates)?angular.copy(a.$parent.$eval(b.ratingStates)):new Array(this.maxRange)),a.rate=function(b){a.value===b||a.readonly||(a.value=b)},a.enter=function(b){a.readonly||(a.val=b),a.onHover({value:b})},a.reset=function(){a.val=angular.copy(a.value),a.onLeave()},a.$watch("value",function(b){a.val=b}),a.readonly=!1,b.readonly&&a.$parent.$watch(c(b.readonly),function(b){a.readonly=!!b})}]).directive("rating",function(){return{restrict:"EA",scope:{value:"=",onHover:"&",onLeave:"&"},controller:"RatingController",templateUrl:"template/rating/rating.html",replace:!0}}),angular.module("mm.foundation.tabs",[]).controller("TabsetController",["$scope",function(a){var b=this,c=b.tabs=a.tabs=[];b.select=function(a){angular.forEach(c,function(a){a.active=!1}),a.active=!0},b.addTab=function(a){c.push(a),(1===c.length||a.active)&&b.select(a)},b.removeTab=function(a){var d=c.indexOf(a);if(a.active&&c.length>1){var e=d==c.length-1?d-1:d+1;b.select(c[e])}c.splice(d,1)}}]).directive("tabset",function(){return{restrict:"EA",transclude:!0,replace:!0,scope:{},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(a,b,c){a.vertical=angular.isDefined(c.vertical)?a.$parent.$eval(c.vertical):!1,a.justified=angular.isDefined(c.justified)?a.$parent.$eval(c.justified):!1,a.type=angular.isDefined(c.type)?a.$parent.$eval(c.type):"tabs"}}}).directive("tab",["$parse",function(a){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},compile:function(b,c,d){return function(b,c,e,f){var g,h;e.active?(g=a(e.active),h=g.assign,b.$parent.$watch(g,function(a,c){a!==c&&(b.active=!!a)}),b.active=g(b.$parent)):h=g=angular.noop,b.$watch("active",function(a){h(b.$parent,a),a?(f.select(b),b.onSelect()):b.onDeselect()}),b.disabled=!1,e.disabled&&b.$parent.$watch(a(e.disabled),function(a){b.disabled=!!a}),b.select=function(){b.disabled||(b.active=!0)},f.addTab(b),b.$on("$destroy",function(){f.removeTab(b)}),b.$transcludeFn=d}}}}]).directive("tabHeadingTransclude",[function(){return{restrict:"A",require:"^tab",link:function(a,b){a.$watch("headingElement",function(a){a&&(b.html(""),b.append(a))})}}}]).directive("tabContentTransclude",function(){function a(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:"^tabset",link:function(b,c,d){var e=b.$eval(d.tabContentTransclude);e.$transcludeFn(e.$parent,function(b){angular.forEach(b,function(b){a(b)?e.headingElement=b:c.append(b)})})}}}),angular.module("mm.foundation.tour",["mm.foundation.position","mm.foundation.tooltip"]).service("$tour",["$window",function(a){function b(){return parseInt(a.localStorage.getItem("mm.tour.step"),10)}function c(b){d=b,a.localStorage.setItem("mm.tour.step",b)}var d=b(),e={};this.add=function(a,b){e[a]=b},this.has=function(a){return!!e[a]},this.isActive=function(){return d>0},this.current=function(a){return a?void c(d):d},this.start=function(){c(1)},this.next=function(){c(d+1)},this.end=function(){c(0)}}]).directive("stepPopup",["$tour",function(a){return{restrict:"EA",replace:!0,scope:{title:"@",content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tour/tour.html",link:function(b,c){b.isLastStep=function(){return!a.has(a.current()+1)},b.endTour=function(){c.remove(),a.end()},b.nextStep=function(){c.remove(),a.next()}}}}]).directive("step",["$position","$tooltip","$tour","$window",function(a,b,c,d){function e(a){var b=a[0].getBoundingClientRect();return b.top>=0&&b.left>=0&&b.bottom<=d.innerHeight-80&&b.right<=d.innerWidth}function f(b,f,g){var h=parseInt(g.stepIndex,10);if(c.isActive()&&h&&(c.add(h,g),h===c.current())){if(!e(f)){var i=a.offset(f);d.scrollTo(0,i.top-d.innerHeight/2)}return!0}return!1}return b("step","step",f)}]),angular.module("mm.foundation.typeahead",["mm.foundation.position","mm.foundation.bindHtml"]).factory("typeaheadParser",["$parse",function(a){var b=/^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error("Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_' but got '"+c+"'.");return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$position","typeaheadParser",function(a,b,c,d,e,f,g){var h=[9,13,27,38,40];return{require:"ngModel",link:function(i,j,k,l){var m,n=i.$eval(k.typeaheadMinLength)||1,o=i.$eval(k.typeaheadWaitMs)||0,p=i.$eval(k.typeaheadEditable)!==!1,q=b(k.typeaheadLoading).assign||angular.noop,r=b(k.typeaheadOnSelect),s=k.typeaheadInputFormatter?b(k.typeaheadInputFormatter):void 0,t=k.typeaheadAppendToBody?b(k.typeaheadAppendToBody):!1,u=b(k.ngModel).assign,v=g.parse(k.typeahead),w=angular.element("
");w.attr({matches:"matches",active:"activeIdx",select:"select(activeIdx)",query:"query",position:"position"}),angular.isDefined(k.typeaheadTemplateUrl)&&w.attr("template-url",k.typeaheadTemplateUrl);var x=i.$new();i.$on("$destroy",function(){x.$destroy()});var y=function(){x.matches=[],x.activeIdx=-1},z=function(a){var b={$viewValue:a};q(i,!0),c.when(v.source(i,b)).then(function(c){if(a===l.$viewValue&&m){if(c.length>0){x.activeIdx=0,x.matches.length=0;for(var d=0;d=n?o>0?(A&&d.cancel(A),A=d(function(){z(a)},o)):z(a):(q(i,!1),y()),p?a:a?void l.$setValidity("editable",!1):(l.$setValidity("editable",!0),a)}),l.$formatters.push(function(a){var b,c,d={};return s?(d.$model=a,s(i,d)):(d[v.itemName]=a,b=v.viewMapper(i,d),d[v.itemName]=void 0,c=v.viewMapper(i,d),b!==c?b:a)}),x.select=function(a){var b,c,d={};d[v.itemName]=c=x.matches[a].model,b=v.modelMapper(i,d),u(i,b),l.$setValidity("editable",!0),r(i,{$item:c,$model:b,$label:v.viewMapper(i,d)}),y(),j[0].focus()},j.bind("keydown",function(a){0!==x.matches.length&&-1!==h.indexOf(a.which)&&(a.preventDefault(),40===a.which?(x.activeIdx=(x.activeIdx+1)%x.matches.length,x.$digest()):38===a.which?(x.activeIdx=(x.activeIdx?x.activeIdx:x.matches.length)-1,x.$digest()):13===a.which||9===a.which?x.$apply(function(){x.select(x.activeIdx)}):27===a.which&&(a.stopPropagation(),y(),x.$digest()))}),j.bind("blur",function(){m=!1});var B=function(a){j[0]!==a.target&&(y(),x.$digest())};e.bind("click",B),i.$on("$destroy",function(){e.unbind("click",B)});var C=a(w)(x);t?e.find("body").append(C):j.after(C)}}}]).directive("typeaheadPopup",function(){return{restrict:"EA",scope:{matches:"=",query:"=",active:"=",position:"=",select:"&"},replace:!0,templateUrl:"template/typeahead/typeahead-popup.html",link:function(a,b,c){a.templateUrl=c.templateUrl,a.isOpen=function(){return a.matches.length>0},a.isActive=function(b){return a.active==b},a.selectActive=function(b){a.active=b},a.selectMatch=function(b){a.select({activeIdx:b})}}}}).directive("typeaheadMatch",["$http","$templateCache","$compile","$parse",function(a,b,c,d){return{restrict:"EA",scope:{index:"=",match:"=",query:"="},link:function(e,f,g){var h=d(g.templateUrl)(e.$parent)||"template/typeahead/typeahead-match.html";a.get(h,{cache:b}).success(function(a){f.replaceWith(c(a.trim())(e))})}}}]).filter("typeaheadHighlight",function(){function a(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}return function(b,c){return c?b.replace(new RegExp(a(c),"gi"),"$&"):b}}),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion-group.html",'
\n {{heading}}\n
\n
\n')}]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion.html",'
\n')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(a){a.put("template/alert/alert.html","
\n \n ×\n
\n")}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'
\n')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'
\n
\n
\n')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pager.html",'\n')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pagination.html",'\n')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-unsafe-popup.html",'\n \n \n\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-popup.html",'\n \n \n\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover.html",'
\n \n
\n

\n

\n
\n
\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/bar.html",'\n') -}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progress.html",'
\n')}]),angular.module("template/progressbar/progressbar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progressbar.html",'
\n \n
\n')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(a){a.put("template/rating/rating.html",'\n \n\n')}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tab.html",'
\n {{heading}}\n
\n')}]),angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset.html",'
\n
\n
\n
\n
\n
\n
\n
\n')}]),angular.module("template/tour/tour.html",[]).run(["$templateCache",function(a){a.put("template/tour/tour.html",'
\n \n
\n

\n

\n Next\n End\n ×\n
\n
\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html","
    \n"+'
  • \n
    \n
  • \n
\n')}]); \ No newline at end of file From 0140472fbc2240bd5dd73f62da876a836fc95434 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 14:09:48 +1000 Subject: [PATCH 071/139] Adding working modals --- .../controllers/products/product_node_controller.js.coffee | 2 ++ app/assets/javascripts/darkswarm/directives/modal.js.coffee | 5 ++++- app/views/modals/_producer.html.haml | 5 ++--- .../products/_modal.html.haml => modals/_product.html.haml} | 2 ++ app/views/shop/products/_summary.html.haml | 5 ++--- 5 files changed, 12 insertions(+), 7 deletions(-) rename app/views/{shop/products/_modal.html.haml => modals/_product.html.haml} (73%) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 4ec316e65f..3e24f006ae 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -6,4 +6,6 @@ Darkswarm.controller "ProductNodeCtrl", ($scope) -> else $scope.product.price + $scope.producer = $scope.product.supplier + $scope.hasVariants = $scope.product.variants.length > 0 diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index 73217b3812..6f62c7cb45 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -8,7 +8,10 @@ Darkswarm.directive "ofnModal", ($modal)-> link: (scope, elem, attrs, ctrl, transclude)-> scope.title = attrs.title contents = null - transclude scope, (clone)-> + + # We're using an isolate scope, which is a child of the original scope + # We have to compile the transclude against the original scope, not the isolate + transclude scope.$parent, (clone)-> contents = clone elem.on "click", => diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 691e9378d3..056f9e488f 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,10 +1,9 @@ %ofn-modal{title: "{{ producer.name }}"} - #producer_modal{bindonce: true} + #producer_modal .row .small-12.columns - %img{"bo-src" => "producer.promo_image"} + %img{"ng-src" => "producer.promo_image"} %h3 {{ producer.name }} - .row .small-6.columns %p diff --git a/app/views/shop/products/_modal.html.haml b/app/views/modals/_product.html.haml similarity index 73% rename from app/views/shop/products/_modal.html.haml rename to app/views/modals/_product.html.haml index 29a023704f..acca8f919b 100644 --- a/app/views/shop/products/_modal.html.haml +++ b/app/views/modals/_product.html.haml @@ -1,2 +1,4 @@ %ofn-modal{title: "{{product.name}}"} + + {{ product | json }} {{ product.description }} diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml index 5e777a5dbb..e41c6ef440 100644 --- a/app/views/shop/products/_summary.html.haml +++ b/app/views/shop/products/_summary.html.haml @@ -6,11 +6,10 @@ %img{"bo-src" => "product.primary_taxon.icon", "ng-click" => "ordering.order = 'primary_taxon.name'", name: "{{product.primary_taxon.name}}"} - {{ product.name}} - -#= render partial: "shop/products/modal" + = render partial: "modals/product" .small-5.columns.summary-header - {{ product.supplier.name }} + = render partial: "modals/producer" .small-2.columns.summary-price.text-right.price %span{"ng-if" => "hasVariants"} From 272cb0469f1f90f1d7d9462e09a3ac99d5cfa786 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 16:39:59 +1000 Subject: [PATCH 072/139] Setting up after_login redirects --- .../authentication/login_controller.js.coffee | 7 ++++-- .../services/authentication_service.js.coffee | 2 +- .../darkswarm/services/redirections.js.coffee | 3 +++ .../admin/overview_controller_decorator.rb | 3 +-- app/helpers/shared_helper.rb | 5 +++++ app/views/json/_injection.html.haml | 2 ++ app/views/layouts/darkswarm.html.haml | 8 +++---- app/views/shared/_current_hub.haml | 2 -- app/views/shared/_current_user.haml | 2 -- spec/features/consumer/authentication_spec.rb | 22 ++++++++++++++++++- 10 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/services/redirections.js.coffee create mode 100644 app/views/json/_injection.html.haml delete mode 100644 app/views/shared/_current_hub.haml delete mode 100644 app/views/shared/_current_user.haml diff --git a/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee index c2211bc033..da625e3d34 100644 --- a/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/authentication/login_controller.js.coffee @@ -1,8 +1,11 @@ -Darkswarm.controller "LoginCtrl", ($scope, $http, $location, AuthenticationService) -> +Darkswarm.controller "LoginCtrl", ($scope, $http, AuthenticationService, Redirections) -> $scope.path = "/login" $scope.submit = -> $http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).success (data)-> - location.href = location.origin + location.pathname # Strips out hash fragments + if Redirections.after_login + location.href = location.origin + Redirections.after_login + else + location.href = location.origin + location.pathname # Strips out hash fragments .error (data) -> $scope.errors = data.message diff --git a/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee b/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee index eada8bc44b..820d5bde9c 100644 --- a/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/authentication_service.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location)-> +Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redirections)-> new class AuthenticationService selectedPath: "/login" diff --git a/app/assets/javascripts/darkswarm/services/redirections.js.coffee b/app/assets/javascripts/darkswarm/services/redirections.js.coffee new file mode 100644 index 0000000000..a479964e9e --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/redirections.js.coffee @@ -0,0 +1,3 @@ +Darkswarm.factory "Redirections", ($location)-> + new class Redirections + after_login: $location.search().after_login diff --git a/app/controllers/spree/admin/overview_controller_decorator.rb b/app/controllers/spree/admin/overview_controller_decorator.rb index 5c96901c1d..a6142d26c0 100644 --- a/app/controllers/spree/admin/overview_controller_decorator.rb +++ b/app/controllers/spree/admin/overview_controller_decorator.rb @@ -13,8 +13,7 @@ Spree::Admin::OverviewController.class_eval do redirect_to '/unauthorized' else store_location - url = respond_to?(:spree_login_path) ? spree_login_path : root_path - redirect_to url + redirect_to root_path(anchor: "login?after_login=#{spree.admin_path}") end end end diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index be1e0ba0f4..828277cb57 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -1,4 +1,9 @@ module SharedHelper + + def inject_json(name, partial) + render "json/injection", name: name, partial: partial + end + def distributor_link_class(distributor) cart = current_order(true) @active_distributors ||= Enterprise.distributors_with_active_order_cycles diff --git a/app/views/json/_injection.html.haml b/app/views/json/_injection.html.haml new file mode 100644 index 0000000000..95b921406b --- /dev/null +++ b/app/views/json/_injection.html.haml @@ -0,0 +1,2 @@ +:javascript + angular.module('Darkswarm').value("#{name.to_s}", #{render "json/#{partial.to_s}"}) diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 5c2dcaee66..edeffafeed 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -15,16 +15,16 @@ = csrf_meta_tags %body.off-canvas{"ng-app" => "Darkswarm"} + = inject_json "currentHub", "current_hub" + = inject_json "user", "current_user" + .off-canvas-wrap{offcanvas: true} .inner-wrap - = render partial: "shared/current_hub" - = render partial: "shared/current_user" = render partial: "shared/menu/menu" + = display_flash_messages %ofn-flash - -#= render "shared/sidebar" - %section{ role: "main" } = yield diff --git a/app/views/shared/_current_hub.haml b/app/views/shared/_current_hub.haml deleted file mode 100644 index 5a0ff7c564..0000000000 --- a/app/views/shared/_current_hub.haml +++ /dev/null @@ -1,2 +0,0 @@ -:javascript - angular.module('Darkswarm').value('currentHub', #{render "json/current_hub"}) diff --git a/app/views/shared/_current_user.haml b/app/views/shared/_current_user.haml deleted file mode 100644 index 9745a71313..0000000000 --- a/app/views/shared/_current_user.haml +++ /dev/null @@ -1,2 +0,0 @@ -:javascript - angular.module('Darkswarm').value('user', #{render "json/current_user"}) diff --git a/spec/features/consumer/authentication_spec.rb b/spec/features/consumer/authentication_spec.rb index 77b60290d1..76e4a20877 100644 --- a/spec/features/consumer/authentication_spec.rb +++ b/spec/features/consumer/authentication_spec.rb @@ -5,7 +5,27 @@ feature "Authentication", js: true do describe "login" do let(:user) { create(:user, password: "password", password_confirmation: "password") } - describe "newskool" do + describe "With redirects" do + scenario "logging in with a redirect set" do + visit groups_path(anchor: "login?after_login=#{producers_path}") + fill_in "Email", with: user.email + fill_in "Password", with: user.password + click_login_button + page.should have_content "Select a producer from the list below" + current_path.should == producers_path + end + + scenario "logging into admin redirects home, then back to admin" do + visit spree.admin_path + fill_in "Email", with: user.email + fill_in "Password", with: user.password + click_login_button + page.should have_content "Dashboard" + current_path.should == spree.admin_path + end + end + + describe "Loggin in from the home page" do before do visit root_path end From d1b27edefe8e301a51c6a33523c97096a867dc3f Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 21 May 2014 16:54:48 +1000 Subject: [PATCH 073/139] Reworking the JS specs --- .../product_node_controller.js.coffee | 1 + .../controllers/products_controller.js.coffee | 2 - .../darkswarm/services/product.js.coffee | 3 + .../hub_node_controller_spec.js.coffee | 11 ---- .../product_node_controller_spec.js.coffee | 24 +++++++ .../products_controller_spec.js.coffee | 64 ++++++------------- .../darkswarm/services/order_spec.js.coffee | 2 + .../{ => services}/product_spec.js.coffee | 2 +- 8 files changed, 50 insertions(+), 59 deletions(-) create mode 100644 spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee rename spec/javascripts/unit/darkswarm/{ => services}/product_spec.js.coffee (86%) diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index 3e24f006ae..959423e3ca 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -1,4 +1,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope) -> + $scope.price = -> if $scope.product.variants.length > 0 prices = (v.price for v in $scope.product.variants) diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 09df18ca38..323df2fc4e 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -12,5 +12,3 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) - code = e.keyCode || e.which if code == 13 e.preventDefault() - - $scope.productPrice = (product) -> diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index ca31d5e9c0..e58b83bacc 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -2,6 +2,9 @@ Darkswarm.factory 'Product', ($resource) -> new class Product constructor: -> @update() + + # TODO: don't need to scope this into object + # Already on object as far as controller scope is concerned data: products: null loading: true diff --git a/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee index a2d14f5811..cb77cb1703 100644 --- a/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/hub_node_controller_spec.js.coffee @@ -19,14 +19,3 @@ describe "HubNodeCtrl", -> expect(scope.current()).toEqual false scope.hub = {id: 99} expect(scope.current()).toEqual true - - it "knows whether selecting this hub will empty the cart", -> - CurrentHub.id = undefined - expect(scope.emptiesCart()).toEqual false - - CurrentHub.id = 99 - scope.hub.id = 99 - expect(scope.emptiesCart()).toEqual false - - scope.hub.id = 1 - expect(scope.emptiesCart()).toEqual true diff --git a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee new file mode 100644 index 0000000000..4b9e404b9e --- /dev/null +++ b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee @@ -0,0 +1,24 @@ +describe "ProductNodeCtrl", -> + ctrl = null + scope = null + product = + id: 99 + price: 10.00 + variants: [] + + beforeEach -> + module('Darkswarm') + inject ($controller) -> + scope = + product: product + ctrl = $controller 'ProductNodeCtrl', {$scope: scope} + + describe "determining the price to display for a product", -> + it "displays the product price when the product does not have variants", -> + expect(scope.price()).toEqual 10.00 + + it "displays the minimum variant price when the product has variants", -> + scope.product = + price: 11 + variants: [{price: 22}, {price: 33}] + expect(scope.price()).toEqual 22 diff --git a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee index 269c8385b8..685d495039 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee @@ -1,47 +1,21 @@ -describe 'All controllers', -> - describe 'ProductsCtrl', -> - ctrl = null - scope = null - event = null - Product = null +describe 'ProductsCtrl', -> + ctrl = null + scope = null + event = null + Product = null - beforeEach -> - module('Darkswarm') - Product = - all: -> - update: -> - data: "testy mctest" - OrderCycle = - order_cycle: {} - - inject ($controller) -> - scope = {} - ctrl = $controller 'ProductsCtrl', {$scope: scope, Product: Product, OrderCycle: OrderCycle} - - it 'fetches products from Product', -> - expect(scope.data).toEqual 'testy mctest' - - describe "determining the price to display for a product", -> - it "displays the product price when the product does not have variants", -> - product = {variants: [], price: 12.34} - expect(scope.productPrice(product)).toEqual 12.34 - - it "displays the minimum variant price when the product has variants", -> - product = - price: 11 - variants: [{price: 22}, {price: 33}] - expect(scope.productPrice(product)).toEqual 22 - - describe 'OrderCycleCtrl', -> - ctrl = null - scope = null - event = null - product_ctrl = null - OrderCycle = null - - beforeEach -> - module 'Darkswarm' + beforeEach -> + module('Darkswarm') + Product = + all: -> + update: -> + data: "testy mctest" + OrderCycle = + order_cycle: {} + + inject ($controller) -> scope = {} - inject ($controller) -> - scope = {} - ctrl = $controller 'OrderCycleCtrl', {$scope: scope} + ctrl = $controller 'ProductsCtrl', {$scope: scope, Product: Product, OrderCycle: OrderCycle} + + it 'fetches products from Product', -> + expect(scope.data).toEqual 'testy mctest' diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index 0462e92952..fedcf23629 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -26,8 +26,10 @@ describe 'Order service', -> } angular.module('Darkswarm').value('order', orderData) module 'Darkswarm' + inject ($injector, _$httpBackend_)-> $httpBackend = _$httpBackend_ + $httpBackend.expectGET("/shop/products").respond 200, [] Order = $injector.get("Order") Navigation = $injector.get("Navigation") flash = $injector.get("flash") diff --git a/spec/javascripts/unit/darkswarm/product_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee similarity index 86% rename from spec/javascripts/unit/darkswarm/product_spec.js.coffee rename to spec/javascripts/unit/darkswarm/services/product_spec.js.coffee index 7108d819af..260074a981 100644 --- a/spec/javascripts/unit/darkswarm/product_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee @@ -10,5 +10,5 @@ describe 'Product service', -> it "Fetches products from the backend on init", -> $httpBackend.expectGET("/shop/products").respond([{test : "cats"}]) - products = Product.all() $httpBackend.flush() + expect(Product.data.products[0].test).toEqual "cats" From d7bc1a9b95a24dfe46c1feab73859d807bdf2434 Mon Sep 17 00:00:00 2001 From: summerscope Date: Thu, 22 May 2014 14:40:35 +1000 Subject: [PATCH 074/139] Styling for shop page product modal --- app/assets/stylesheets/darkswarm/all.scss | 3 -- .../stylesheets/darkswarm/images.css.sass | 21 ++++++++++ .../stylesheets/darkswarm/overrides.css.sass | 3 -- .../stylesheets/darkswarm/shop.css.sass | 3 +- app/views/modals/_producer.html.haml | 40 +++++++++++++------ app/views/modals/_producers.html.haml | 3 +- app/views/modals/_product.html.haml | 14 ++++++- 7 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/images.css.sass diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index 80e43cdc8b..a8ac8af078 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -9,6 +9,3 @@ */ @import 'foundation-icons'; -ofn-modal { - display: block; -} \ No newline at end of file diff --git a/app/assets/stylesheets/darkswarm/images.css.sass b/app/assets/stylesheets/darkswarm/images.css.sass new file mode 100644 index 0000000000..24c1c77824 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/images.css.sass @@ -0,0 +1,21 @@ +@import mixins +@import variables +@import branding + +.product-img + border-bottom: 40px white solid + border-top: 20px white solid + border-left: 20px white solid + border-right: 20px white solid + outline: 1px solid #ccc + @include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25)) + +@media only screen and (max-width: 1024px) + .product-img + margin-top: 2em + margin-bottom: 1em + + + + + diff --git a/app/assets/stylesheets/darkswarm/overrides.css.sass b/app/assets/stylesheets/darkswarm/overrides.css.sass index 917d6dd2e3..fcec6b455d 100644 --- a/app/assets/stylesheets/darkswarm/overrides.css.sass +++ b/app/assets/stylesheets/darkswarm/overrides.css.sass @@ -1,5 +1,2 @@ .row max-width: 74em - -.reveal-modal - position: fixed diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index 0c2972367a..e0030a7d7a 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -81,8 +81,7 @@ padding-top: 1em input.button.right float: left - - + product:hover, product:focus, product:active border-color: $clr-brick @include box-shadow(0 0 3px 0 $clr-brick-bright) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 056f9e488f..ab8764358c 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,12 +1,28 @@ -%ofn-modal{title: "{{ producer.name }}"} - #producer_modal - .row - .small-12.columns - %img{"ng-src" => "producer.promo_image"} - %h3 {{ producer.name }} - .row - .small-6.columns - %p - {{ producer.description }} - .small-6.columns - Stay in touch with {{ producer.name }} +/ %ofn-modal{title: "{{ producer.name }}"} +/ #producer_modal +/ .row +/ .small-12.columns +/ %img{"ng-src" => "producer.promo_image"} +/ %h3 {{ producer.name }} +/ .row +/ .small-6.columns +/ %p +/ {{ producer.description }} +/ .small-6.columns +/ Stay in touch with {{ producer.name }} +/ %a.close-reveal-modal{"ng-click" => "$close()"} × + + +%ofn-modal{title: "{{producer.name}}"} + .row + .columns.small-12 + %img.product-img{"ng-src" => "{{producer.promo_image.images[0].large_url}}"} + %h3 {{ producer.name }} + .row + .columns.small-12.large-6 + %p {{ producer.description }} + .columns.small-12.large-6 + Stay in touch with {{ producer.name }} + / %pre + / {{ producer | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × \ No newline at end of file diff --git a/app/views/modals/_producers.html.haml b/app/views/modals/_producers.html.haml index 153e4dcae3..89d8ccabae 100644 --- a/app/views/modals/_producers.html.haml +++ b/app/views/modals/_producers.html.haml @@ -1,4 +1,3 @@ %h2 Producers -%h5 Our producers make the food! All the delicious! -%p More text goes here. +%p Our producers make all the delicious food you can shop for on the Open Food Network. %a.close-reveal-modal{"ng-click" => "cancel()"} × \ No newline at end of file diff --git a/app/views/modals/_product.html.haml b/app/views/modals/_product.html.haml index acca8f919b..70137ba987 100644 --- a/app/views/modals/_product.html.haml +++ b/app/views/modals/_product.html.haml @@ -1,4 +1,14 @@ %ofn-modal{title: "{{product.name}}"} - {{ product | json }} - {{ product.description }} + .row + .columns.small-12.large-6 + %img.product-img{"ng-src" => "{{product.master.images[0].large_url}}"} + .columns.small-12.large-6 + %h2 + %img{"ng-src" => "{{product.primary_taxon.icon}}"} + {{product.name}} + %p {{product.description}} + / %pre + / {{ product | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × + \ No newline at end of file From 1a7c6f87edc17b1827b0a4ef2c41f25c73d6d706 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 14:47:10 +1000 Subject: [PATCH 075/139] Adding fields to product supplier --- app/views/shop/products.rabl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index c8b5d5398c..ee5e567285 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -10,7 +10,14 @@ node do |product| end child :supplier => :supplier do - attributes :id, :name, :description + attributes :id, :name, :description, :long_description, :website, :instagram, :facebook, :linkedin, :twitter + + node :logo do |supplier| + supplier.logo.url + end + node :promo_image do |supplier| + supplier.promo_image.url + end end child :primary_taxon => :primary_taxon do From 465728576961706c0137b51952476113ffdd3419 Mon Sep 17 00:00:00 2001 From: summerscope Date: Thu, 22 May 2014 16:35:48 +1000 Subject: [PATCH 076/139] Producers modal styling and markup --- .../stylesheets/darkswarm/images.css.sass | 27 ++++++++- app/views/modals/_producer.html.haml | 57 ++++++++++++------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/images.css.sass b/app/assets/stylesheets/darkswarm/images.css.sass index 24c1c77824..927e906842 100644 --- a/app/assets/stylesheets/darkswarm/images.css.sass +++ b/app/assets/stylesheets/darkswarm/images.css.sass @@ -9,7 +9,32 @@ border-right: 20px white solid outline: 1px solid #ccc @include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25)) - + +.producer-hero + position: relative + padding: 0 + +.producer-hero-img + background-color: #999 + width: 100% + height: inherit + max-height: 260px + overflow: hidden + margin-top: 2em + margin-bottom: 1em + + +h3.producer-name + background-color: rgba(255,255,255,0.65) + height: 2.5em + width: 100% + position: absolute + bottom: 0 + padding: 0.5em + +.producer-logo + max-width: 220px + @media only screen and (max-width: 1024px) .product-img margin-top: 2em diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index ab8764358c..6031537089 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,28 +1,43 @@ -/ %ofn-modal{title: "{{ producer.name }}"} -/ #producer_modal -/ .row -/ .small-12.columns -/ %img{"ng-src" => "producer.promo_image"} -/ %h3 {{ producer.name }} -/ .row -/ .small-6.columns -/ %p -/ {{ producer.description }} -/ .small-6.columns -/ Stay in touch with {{ producer.name }} -/ %a.close-reveal-modal{"ng-click" => "$close()"} × - - %ofn-modal{title: "{{producer.name}}"} .row - .columns.small-12 - %img.product-img{"ng-src" => "{{producer.promo_image.images[0].large_url}}"} - %h3 {{ producer.name }} + .columns.small-12.producer-hero + %img.producer-hero-img{"ng-src" => "{{producer.promo_image}}"} + / Will - scale large images down to 1200px wide, crop in to img aspect ratio 60W:13H + %h3.producer-name {{ producer.name }} .row + .columns.small-12.large-6{"ng-bind-html" => "{{producer.long_description}}"} + / Will to fix this .columns.small-12.large-6 - %p {{ producer.description }} - .columns.small-12.large-6 - Stay in touch with {{ producer.name }} + / Will needs logic to add in following only if data is available for each type: + / Will needs better formatting of URLs printed on-screen (minus http://www.) + / Will needs formatting of URLs driving %a regardless of user input (plus http://www.) + %img.producer-logo{"ng-src" => "{{producer.logo}}"} + %h4 Stay in touch with {{ producer.name }} + %ul.small-block-grid-1 + %li + %a{href: "{{producer.website}}", target: "_blank" } + %i.fi-web + {{ producer.website }} + %li + %a{href: "{{producer.twitter}}", target: "_blank"} + / Will needs logic to allow user to input @twitterhandle to drive a logical URL + %i.fi-social-twitter + {{ producer.twitter }} + %li + %a{href: "{{producer.facebook}}", target: "_blank"} + %i.fi-social-facebook + {{ producer.facebook }} + %li + %a{href: "{{producer.linkedin}}", target: "_blank"} + %i.fi-social-linkedin + {{ producer.linkedin }} + %li + %a{href: "{{producer.instagram}}", target: "_blank"} + / Will needs logic to allow user to input @instagramhandle to drive a logical URL + %i.fi-social-instagram + {{ producer.instagram }} + / %pre / {{ producer | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × \ No newline at end of file From 9b15c213d142c04dba147a705fba5b810a1a8caa Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 11:22:04 +1000 Subject: [PATCH 077/139] When an enterprise user saves an order cycle for which it manages only some of the enterprises involved, do not delete the other exchanges --- .../admin/order_cycles_controller.rb | 4 +-- app/helpers/enterprises_helper.rb | 4 +++ app/models/exchange.rb | 4 +++ .../order_cycle_form_applicator.rb | 10 +++++-- spec/features/admin/order_cycles_spec.rb | 9 ++++++ .../order_cycle_form_applicator_spec.rb | 30 +++++++++++++++++++ spec/models/exchange_spec.rb | 22 ++++++++++---- 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 46273d0eff..566c660112 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -23,7 +23,7 @@ module Admin respond_to do |format| if @order_cycle.save - OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle).go! + OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle, managed_enterprises).go! flash[:notice] = 'Your order cycle has been created.' format.html { redirect_to admin_order_cycles_path } @@ -40,7 +40,7 @@ module Admin respond_to do |format| if @order_cycle.update_attributes(params[:order_cycle]) - OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle).go! + OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle, managed_enterprises).go! flash[:notice] = 'Your order cycle has been updated.' format.html { redirect_to admin_order_cycles_path } diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb index 4b0f2f4a93..ed22831589 100644 --- a/app/helpers/enterprises_helper.rb +++ b/app/helpers/enterprises_helper.rb @@ -2,6 +2,10 @@ module EnterprisesHelper def current_distributor @current_distributor ||= current_order(false).andand.distributor end + + def managed_enterprises + Enterprise.managed_by(spree_current_user) + end def enterprises_options enterprises enterprises.map { |enterprise| [enterprise.name + ": " + enterprise.address.address1 + ", " + enterprise.address.city, enterprise.id.to_i] } diff --git a/app/models/exchange.rb b/app/models/exchange.rb index 18c3f81447..c491748d5d 100644 --- a/app/models/exchange.rb +++ b/app/models/exchange.rb @@ -54,6 +54,10 @@ class Exchange < ActiveRecord::Base incoming? ? 'supplier' : 'distributor' end + def participant + incoming? ? sender : receiver + end + def to_h(core_only=false) h = attributes.merge({ 'variant_ids' => variant_ids.sort, 'enterprise_fee_ids' => enterprise_fee_ids.sort }) h.reject! { |k| %w(id order_cycle_id created_at updated_at).include? k } if core_only diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index dc5056d53a..4ef5b44e24 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -5,8 +5,10 @@ module OpenFoodNetwork # translation is more a responsibility of Angular, so I'd be inclined to refactor this class to move # as much as possible (if not all) of its logic into Angular. class OrderCycleFormApplicator - def initialize(order_cycle) + # The applicator will only touch exchanges where a permitted enterprise is the participant + def initialize(order_cycle, permitted_enterprises=[]) @order_cycle = order_cycle + @permitted_enterprises = permitted_enterprises end def go! @@ -68,7 +70,7 @@ module OpenFoodNetwork end def destroy_untouched_exchanges - untouched_exchanges.each { |exchange| exchange.destroy } + with_permission(untouched_exchanges).each(&:destroy) end def untouched_exchanges @@ -76,6 +78,10 @@ module OpenFoodNetwork @order_cycle.exchanges.reject { |ex| touched_exchange_ids.include? ex.id } end + def with_permission(exchanges) + exchanges.select { |ex| @permitted_enterprises.include? ex.participant } + end + def exchange_variant_ids(exchange) exchange[:variants].select { |k, v| v }.keys.map { |k| k.to_i } diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 6cb3a501a4..2423a6dc05 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -514,6 +514,15 @@ feature %q{ # I should not see exchanges for supplier2 or distributor2 page.all('tr.supplier').count.should == 1 page.all('tr.distributor').count.should == 1 + + # When I save, then those exchanges should remain + click_button 'Update' + page.should have_content "Your order cycle has been updated." + + oc.reload + oc.suppliers.sort.should == [supplier1, supplier2] + oc.coordinator.should == supplier1 + oc.distributors.sort.should == [distributor1, distributor2] end scenario "cloning an order cycle" do diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb index 81cd925569..11b7655368 100644 --- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb +++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb @@ -115,6 +115,18 @@ module OpenFoodNetwork applicator.send(:untouched_exchanges).should == [] end + + it "does not destroy exchanges involving enterprises it does not have permission to touch" do + applicator = OrderCycleFormApplicator.new(nil) + exchanges = double(:exchanges) + permitted_exchanges = [double(:exchange), double(:exchange)] + + applicator.should_receive(:with_permission).with(exchanges) { permitted_exchanges } + applicator.stub(:untouched_exchanges) { exchanges } + permitted_exchanges.each { |ex| ex.should_receive(:destroy) } + + applicator.send(:destroy_untouched_exchanges) + end end it "converts exchange variant ids hash to an array of ids" do @@ -122,6 +134,24 @@ module OpenFoodNetwork applicator.send(:exchange_variant_ids, {:enterprise_id => 123, :variants => {'1' => true, '2' => false, '3' => true}}).should == [1, 3] end + + describe "filtering exchanges for permission" do + it "returns exchanges involving enterprises we have permission to touch" do + e = double(:enterprise) + ex = double(:exchange, participant: e) + + applicator = OrderCycleFormApplicator.new(nil, [e]) + applicator.send(:with_permission, [ex]).should == [ex] + end + + it "does not return other exchanges" do + e = double(:enterprise) + ex = double(:exchange, participant: e) + + applicator = OrderCycleFormApplicator.new(nil, []) + applicator.send(:with_permission, [ex]).should == [] + end + end end context "integration specs" do diff --git a/spec/models/exchange_spec.rb b/spec/models/exchange_spec.rb index ed6cdbfc93..0dfceadbad 100644 --- a/spec/models/exchange_spec.rb +++ b/spec/models/exchange_spec.rb @@ -48,7 +48,7 @@ describe Exchange do e.enterprise_fees.count.should == 1 end - describe "reporting whether it is an incoming exchange" do + describe "exchange directionality" do let(:supplier) { create(:supplier_enterprise) } let(:coordinator) { create(:distributor_enterprise) } let(:distributor) { create(:distributor_enterprise) } @@ -56,12 +56,24 @@ describe Exchange do let(:incoming_exchange) { oc.exchanges.create! sender: supplier, receiver: coordinator, incoming: true } let(:outgoing_exchange) { oc.exchanges.create! sender: coordinator, receiver: distributor, incoming: false } - it "returns true for incoming exchanges" do - incoming_exchange.should be_incoming + describe "reporting whether it is an incoming exchange" do + it "returns true for incoming exchanges" do + incoming_exchange.should be_incoming + end + + it "returns false for outgoing exchanges" do + outgoing_exchange.should_not be_incoming + end end - it "returns false for outgoing exchanges" do - outgoing_exchange.should_not be_incoming + describe "finding the exchange participant (the enterprise other than the coordinator)" do + it "returns the sender for incoming exchanges" do + incoming_exchange.participant.should == supplier + end + + it "returns the receiver for outgoing exchanges" do + outgoing_exchange.participant.should == distributor + end end end From 095b9bf67a9bbcb440fee10ab807bce650fa849d Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 12:05:46 +1000 Subject: [PATCH 078/139] Enterprise user can only update order cycle exchanges where it manages the participant enterprise --- .../order_cycle_form_applicator.rb | 12 +++-- .../order_cycle_form_applicator_spec.rb | 53 ++++++++++++++----- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 4ef5b44e24..9da681c61a 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -64,9 +64,11 @@ module OpenFoodNetwork def update_exchange(sender_id, receiver_id, incoming, attrs={}) exchange = @order_cycle.exchanges.where(:sender_id => sender_id, :receiver_id => receiver_id, :incoming => incoming).first - exchange.update_attributes!(attrs) - @touched_exchanges << exchange + if permission_for(exchange) + exchange.update_attributes!(attrs) + @touched_exchanges << exchange + end end def destroy_untouched_exchanges @@ -79,7 +81,11 @@ module OpenFoodNetwork end def with_permission(exchanges) - exchanges.select { |ex| @permitted_enterprises.include? ex.participant } + exchanges.select { |ex| permission_for(ex) } + end + + def permission_for(exchange) + @permitted_enterprises.include? exchange.participant end diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb index 11b7655368..a6f83d77cf 100644 --- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb +++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb @@ -136,20 +136,31 @@ module OpenFoodNetwork end describe "filtering exchanges for permission" do - it "returns exchanges involving enterprises we have permission to touch" do - e = double(:enterprise) - ex = double(:exchange, participant: e) + describe "checking permission on a single exchange" do + it "returns true when it has permission" do + e = double(:enterprise) + ex = double(:exchange, participant: e) - applicator = OrderCycleFormApplicator.new(nil, [e]) - applicator.send(:with_permission, [ex]).should == [ex] + applicator = OrderCycleFormApplicator.new(nil, [e]) + applicator.send(:permission_for, ex).should be_true + end + + it "returns false otherwise" do + e = double(:enterprise) + ex = double(:exchange, participant: e) + + applicator = OrderCycleFormApplicator.new(nil, []) + applicator.send(:permission_for, ex).should be_false + end end - it "does not return other exchanges" do - e = double(:enterprise) - ex = double(:exchange, participant: e) - - applicator = OrderCycleFormApplicator.new(nil, []) - applicator.send(:with_permission, [ex]).should == [] + describe "filtering many exchanges" do + it "returns exchanges involving enterprises we have permission to touch" do + ex1, ex2 = double(:exchange), double(:exchange) + applicator = OrderCycleFormApplicator.new(nil, []) + applicator.stub(:permission_for).and_return(true, false) + applicator.send(:with_permission, [ex1, ex2]).should == [ex1] + end end end end @@ -197,10 +208,11 @@ module OpenFoodNetwork end it "updates exchanges" do - oc = FactoryGirl.create(:simple_order_cycle) - applicator = OrderCycleFormApplicator.new(oc) sender = FactoryGirl.create(:enterprise) receiver = FactoryGirl.create(:enterprise) + oc = FactoryGirl.create(:simple_order_cycle) + applicator = OrderCycleFormApplicator.new(oc, [sender, receiver]) + incoming = true variant1 = FactoryGirl.create(:variant) variant2 = FactoryGirl.create(:variant) @@ -219,6 +231,21 @@ module OpenFoodNetwork exchange.enterprise_fees.sort.should == [enterprise_fee2, enterprise_fee3] applicator.send(:touched_exchanges).should == [exchange] end + + it "does not update exchanges it is not permitted to touch" do + sender = FactoryGirl.create(:enterprise) + receiver = FactoryGirl.create(:enterprise) + oc = FactoryGirl.create(:simple_order_cycle) + applicator = OrderCycleFormApplicator.new(oc, []) + incoming = true + exchange = FactoryGirl.create(:exchange, order_cycle: oc, sender: sender, receiver: receiver, incoming: incoming) + variant1 = FactoryGirl.create(:variant) + + applicator.send(:touched_exchanges=, []) + applicator.send(:update_exchange, sender.id, receiver.id, incoming, {:variant_ids => [variant1.id]}) + + exchange.variants.should_not == [variant1] + end end end end From 14dee8d7fecc11c3156b65c818043131852d323b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 12:09:38 +1000 Subject: [PATCH 079/139] OrderCycleFormApplicator requires permitted_enterprises to be set explicitly --- .../order_cycle_form_applicator.rb | 2 +- .../order_cycle_form_applicator_spec.rb | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 9da681c61a..11bf85a341 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -6,7 +6,7 @@ module OpenFoodNetwork # as much as possible (if not all) of its logic into Angular. class OrderCycleFormApplicator # The applicator will only touch exchanges where a permitted enterprise is the participant - def initialize(order_cycle, permitted_enterprises=[]) + def initialize(order_cycle, permitted_enterprises) @order_cycle = order_cycle @permitted_enterprises = permitted_enterprises end diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb index a6f83d77cf..b11229055a 100644 --- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb +++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb @@ -11,7 +11,7 @@ module OpenFoodNetwork oc = double(:order_cycle, :coordinator_id => coordinator_id, :exchanges => [], :incoming_exchanges => [incoming_exchange], :outgoing_exchanges => []) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.should_receive(:exchange_variant_ids).with(incoming_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(supplier_id, coordinator_id, true).and_return(false) @@ -29,7 +29,7 @@ module OpenFoodNetwork oc = double(:order_cycle, :coordinator_id => coordinator_id, :exchanges => [], :incoming_exchanges => [], :outgoing_exchanges => [outgoing_exchange]) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.should_receive(:exchange_variant_ids).with(outgoing_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(coordinator_id, distributor_id, false).and_return(false) @@ -51,7 +51,7 @@ module OpenFoodNetwork :incoming_exchanges => [incoming_exchange], :outgoing_exchanges => []) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.should_receive(:exchange_variant_ids).with(incoming_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(supplier_id, coordinator_id, true).and_return(true) @@ -73,7 +73,7 @@ module OpenFoodNetwork :incoming_exchanges => [], :outgoing_exchanges => [outgoing_exchange]) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.should_receive(:exchange_variant_ids).with(outgoing_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(coordinator_id, distributor_id, false).and_return(true) @@ -95,7 +95,7 @@ module OpenFoodNetwork :incoming_exchanges => [], :outgoing_exchanges => []) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.should_receive(:destroy_untouched_exchanges) @@ -108,7 +108,7 @@ module OpenFoodNetwork e2 = double(:exchange2, id: 1, foo: 2) oc = double(:order_cycle, :exchanges => [e1]) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.instance_eval do @touched_exchanges = [e2] end @@ -117,7 +117,7 @@ module OpenFoodNetwork end it "does not destroy exchanges involving enterprises it does not have permission to touch" do - applicator = OrderCycleFormApplicator.new(nil) + applicator = OrderCycleFormApplicator.new(nil, []) exchanges = double(:exchanges) permitted_exchanges = [double(:exchange), double(:exchange)] @@ -130,7 +130,7 @@ module OpenFoodNetwork end it "converts exchange variant ids hash to an array of ids" do - applicator = OrderCycleFormApplicator.new(nil) + applicator = OrderCycleFormApplicator.new(nil, []) applicator.send(:exchange_variant_ids, {:enterprise_id => 123, :variants => {'1' => true, '2' => false, '3' => true}}).should == [1, 3] end @@ -173,7 +173,7 @@ module OpenFoodNetwork it "checks whether exchanges exist" do oc = FactoryGirl.create(:simple_order_cycle) exchange = FactoryGirl.create(:exchange, order_cycle: oc) - applicator = OrderCycleFormApplicator.new(oc) + applicator = OrderCycleFormApplicator.new(oc, []) applicator.send(:exchange_exists?, exchange.sender_id, exchange.receiver_id, exchange.incoming).should be_true applicator.send(:exchange_exists?, exchange.sender_id, exchange.receiver_id, !exchange.incoming).should be_false @@ -184,10 +184,10 @@ module OpenFoodNetwork end it "adds exchanges" do - oc = FactoryGirl.create(:simple_order_cycle) - applicator = OrderCycleFormApplicator.new(oc) sender = FactoryGirl.create(:enterprise) receiver = FactoryGirl.create(:enterprise) + oc = FactoryGirl.create(:simple_order_cycle) + applicator = OrderCycleFormApplicator.new(oc, [sender, receiver]) incoming = true variant1 = FactoryGirl.create(:variant) variant2 = FactoryGirl.create(:variant) From 9e46108e9a40cbbaa7010ac6f7e44e4bb50aac62 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 12:18:22 +1000 Subject: [PATCH 080/139] Enterprise user can only add order cycle exchanges where it manages the participant enterprise --- .../order_cycle_form_applicator.rb | 10 +++++++--- .../order_cycle_form_applicator_spec.rb | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 11bf85a341..6556223dac 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -58,14 +58,18 @@ module OpenFoodNetwork def add_exchange(sender_id, receiver_id, incoming, attrs={}) attrs = attrs.reverse_merge(:sender_id => sender_id, :receiver_id => receiver_id, :incoming => incoming) - exchange = @order_cycle.exchanges.create! attrs - @touched_exchanges << exchange + exchange = @order_cycle.exchanges.build attrs + + if permission_for exchange + exchange.save! + @touched_exchanges << exchange + end end def update_exchange(sender_id, receiver_id, incoming, attrs={}) exchange = @order_cycle.exchanges.where(:sender_id => sender_id, :receiver_id => receiver_id, :incoming => incoming).first - if permission_for(exchange) + if permission_for exchange exchange.update_attributes!(attrs) @touched_exchanges << exchange end diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb index b11229055a..c63d1eac25 100644 --- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb +++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb @@ -232,6 +232,19 @@ module OpenFoodNetwork applicator.send(:touched_exchanges).should == [exchange] end + it "does not add exchanges it is not permitted to touch" do + sender = FactoryGirl.create(:enterprise) + receiver = FactoryGirl.create(:enterprise) + oc = FactoryGirl.create(:simple_order_cycle) + applicator = OrderCycleFormApplicator.new(oc, []) + incoming = true + + expect do + applicator.send(:touched_exchanges=, []) + applicator.send(:add_exchange, sender.id, receiver.id, incoming) + end.to change(Exchange, :count).by(0) + end + it "does not update exchanges it is not permitted to touch" do sender = FactoryGirl.create(:enterprise) receiver = FactoryGirl.create(:enterprise) From 84b6f99321a328a14bfe2044dbebde702860bced Mon Sep 17 00:00:00 2001 From: summerscope Date: Thu, 22 May 2014 14:40:35 +1000 Subject: [PATCH 081/139] Styling for shop page product modal --- app/assets/stylesheets/darkswarm/all.scss | 3 -- .../stylesheets/darkswarm/images.css.sass | 21 ++++++++++ .../stylesheets/darkswarm/overrides.css.sass | 3 -- .../stylesheets/darkswarm/shop.css.sass | 3 +- app/views/modals/_producer.html.haml | 40 +++++++++++++------ app/views/modals/_producers.html.haml | 3 +- app/views/modals/_product.html.haml | 14 ++++++- 7 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/images.css.sass diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index 80e43cdc8b..a8ac8af078 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -9,6 +9,3 @@ */ @import 'foundation-icons'; -ofn-modal { - display: block; -} \ No newline at end of file diff --git a/app/assets/stylesheets/darkswarm/images.css.sass b/app/assets/stylesheets/darkswarm/images.css.sass new file mode 100644 index 0000000000..24c1c77824 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/images.css.sass @@ -0,0 +1,21 @@ +@import mixins +@import variables +@import branding + +.product-img + border-bottom: 40px white solid + border-top: 20px white solid + border-left: 20px white solid + border-right: 20px white solid + outline: 1px solid #ccc + @include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25)) + +@media only screen and (max-width: 1024px) + .product-img + margin-top: 2em + margin-bottom: 1em + + + + + diff --git a/app/assets/stylesheets/darkswarm/overrides.css.sass b/app/assets/stylesheets/darkswarm/overrides.css.sass index 917d6dd2e3..fcec6b455d 100644 --- a/app/assets/stylesheets/darkswarm/overrides.css.sass +++ b/app/assets/stylesheets/darkswarm/overrides.css.sass @@ -1,5 +1,2 @@ .row max-width: 74em - -.reveal-modal - position: fixed diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index 0c2972367a..e0030a7d7a 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -81,8 +81,7 @@ padding-top: 1em input.button.right float: left - - + product:hover, product:focus, product:active border-color: $clr-brick @include box-shadow(0 0 3px 0 $clr-brick-bright) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 056f9e488f..ab8764358c 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,12 +1,28 @@ -%ofn-modal{title: "{{ producer.name }}"} - #producer_modal - .row - .small-12.columns - %img{"ng-src" => "producer.promo_image"} - %h3 {{ producer.name }} - .row - .small-6.columns - %p - {{ producer.description }} - .small-6.columns - Stay in touch with {{ producer.name }} +/ %ofn-modal{title: "{{ producer.name }}"} +/ #producer_modal +/ .row +/ .small-12.columns +/ %img{"ng-src" => "producer.promo_image"} +/ %h3 {{ producer.name }} +/ .row +/ .small-6.columns +/ %p +/ {{ producer.description }} +/ .small-6.columns +/ Stay in touch with {{ producer.name }} +/ %a.close-reveal-modal{"ng-click" => "$close()"} × + + +%ofn-modal{title: "{{producer.name}}"} + .row + .columns.small-12 + %img.product-img{"ng-src" => "{{producer.promo_image.images[0].large_url}}"} + %h3 {{ producer.name }} + .row + .columns.small-12.large-6 + %p {{ producer.description }} + .columns.small-12.large-6 + Stay in touch with {{ producer.name }} + / %pre + / {{ producer | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × \ No newline at end of file diff --git a/app/views/modals/_producers.html.haml b/app/views/modals/_producers.html.haml index 153e4dcae3..89d8ccabae 100644 --- a/app/views/modals/_producers.html.haml +++ b/app/views/modals/_producers.html.haml @@ -1,4 +1,3 @@ %h2 Producers -%h5 Our producers make the food! All the delicious! -%p More text goes here. +%p Our producers make all the delicious food you can shop for on the Open Food Network. %a.close-reveal-modal{"ng-click" => "cancel()"} × \ No newline at end of file diff --git a/app/views/modals/_product.html.haml b/app/views/modals/_product.html.haml index acca8f919b..70137ba987 100644 --- a/app/views/modals/_product.html.haml +++ b/app/views/modals/_product.html.haml @@ -1,4 +1,14 @@ %ofn-modal{title: "{{product.name}}"} - {{ product | json }} - {{ product.description }} + .row + .columns.small-12.large-6 + %img.product-img{"ng-src" => "{{product.master.images[0].large_url}}"} + .columns.small-12.large-6 + %h2 + %img{"ng-src" => "{{product.primary_taxon.icon}}"} + {{product.name}} + %p {{product.description}} + / %pre + / {{ product | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × + \ No newline at end of file From 6d24a6555e217f760d8c7bd602e13d5e5a1cde87 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 14:47:10 +1000 Subject: [PATCH 082/139] Adding fields to product supplier --- app/views/shop/products.rabl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index c8b5d5398c..ee5e567285 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -10,7 +10,14 @@ node do |product| end child :supplier => :supplier do - attributes :id, :name, :description + attributes :id, :name, :description, :long_description, :website, :instagram, :facebook, :linkedin, :twitter + + node :logo do |supplier| + supplier.logo.url + end + node :promo_image do |supplier| + supplier.promo_image.url + end end child :primary_taxon => :primary_taxon do From fd1e7ebaa3976327f518e0ef4ee1f347adb8fa8a Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 15:49:10 +1000 Subject: [PATCH 083/139] Adding primary taxon field to product --- app/models/enterprise.rb | 1 + app/models/spree/classification_decorator.rb | 10 ++++++++++ app/models/spree/product_decorator.rb | 13 ++++++++----- ...0140522044009_add_primary_taxon_to_products.rb | 5 +++++ db/schema.rb | 3 ++- spec/factories.rb | 7 +++++++ spec/models/spree/classification_spec.rb | 15 +++++++++++++++ spec/models/spree/product_spec.rb | 11 +++++++++-- 8 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 app/models/spree/classification_decorator.rb create mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb create mode 100644 spec/models/spree/classification_spec.rb diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index a72c6fdbd6..5e53316607 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -15,6 +15,7 @@ class Enterprise < ActiveRecord::Base has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods', class_name: 'Spree::PaymentMethod', foreign_key: 'distributor_id' has_and_belongs_to_many :shipping_methods, join_table: 'distributors_shipping_methods', class_name: 'Spree::ShippingMethod', foreign_key: 'distributor_id' + delegate :latitude, :longitude, :city, :state_name, :to => :address accepts_nested_attributes_for :address diff --git a/app/models/spree/classification_decorator.rb b/app/models/spree/classification_decorator.rb new file mode 100644 index 0000000000..7e34e6890e --- /dev/null +++ b/app/models/spree/classification_decorator.rb @@ -0,0 +1,10 @@ +Spree::Classification.class_eval do + before_destroy :dont_destroy_if_primary_taxon + + def dont_destroy_if_primary_taxon + if product.primary_taxon == taxon + errors.add :base, "Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted" + return false + end + end +end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index ba7cbc253d..13491f94df 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -6,6 +6,7 @@ Spree::Product.class_eval do belongs_to :supplier, :class_name => 'Enterprise' + belongs_to :primary_taxon, class_name: 'Spree::Taxon' has_many :product_distributions, :dependent => :destroy has_many :distributors, :through => :product_distributions @@ -13,9 +14,10 @@ Spree::Product.class_eval do accepts_nested_attributes_for :product_distributions, :allow_destroy => true delegate_belongs_to :master, :unit_value, :unit_description - attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes + attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes validates_presence_of :supplier + validates_presence_of :primary_taxon validates_presence_of :variant_unit, if: :has_variants? validates_presence_of :variant_unit_scale, @@ -25,6 +27,7 @@ Spree::Product.class_eval do after_initialize :set_available_on_to_now, :if => :new_record? after_save :update_units + before_save :add_primary_taxon_to_taxons # -- Joins @@ -118,10 +121,6 @@ Spree::Product.class_eval do order_cycle.variants_distributed_by(distributor).where(product_id: self) end - def primary_taxon - self.taxons.order.first - end - # Build a product distribution for each distributor def build_product_distributions_for_user user Enterprise.is_distributor.managed_by(user).each do |distributor| @@ -157,6 +156,10 @@ Spree::Product.class_eval do end end + def add_primary_taxon_to_taxons + taxons << primary_taxon unless taxons.find_by_id(primary_taxon) + end + def self.all_variant_unit_option_types Spree::OptionType.where('name LIKE ?', 'unit_%%') end diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb new file mode 100644 index 0000000000..ec8e3772b1 --- /dev/null +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -0,0 +1,5 @@ +class AddPrimaryTaxonToProducts < ActiveRecord::Migration + def change + add_column :spree_products, :primary_taxon_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 77df8baf75..69e79c2829 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140522015012) do +ActiveRecord::Schema.define(:version => 20140522044009) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -681,6 +681,7 @@ ActiveRecord::Schema.define(:version => 20140522015012) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" + t.integer "primary_taxon_id" end add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" diff --git a/spec/factories.rb b/spec/factories.rb index 6da7824d47..394112125a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -2,6 +2,9 @@ require 'ffaker' require 'spree/core/testing_support/factories' FactoryGirl.define do + factory :classification, class: Spree::Classification do + end + factory :order_cycle, :parent => :simple_order_cycle do coordinator_fees { [create(:enterprise_fee, enterprise: coordinator)] } @@ -150,6 +153,9 @@ end FactoryGirl.modify do + factory :product do + primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } + end factory :simple_product do # Fix product factory name sequence with Kernel.rand so it is not interpreted as a Spree::Product method # Pull request: https://github.com/spree/spree/pull/1964 @@ -157,6 +163,7 @@ FactoryGirl.modify do sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" } supplier { Enterprise.is_primary_producer.first || FactoryGirl.create(:supplier_enterprise) } + primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } on_hand 3 variant_unit 'weight' diff --git a/spec/models/spree/classification_spec.rb b/spec/models/spree/classification_spec.rb new file mode 100644 index 0000000000..f26f6da0c0 --- /dev/null +++ b/spec/models/spree/classification_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +module Spree + describe Classification do + let(:product) { create(:simple_product) } + let(:taxon) { create(:taxon) } + let(:classification) { create(:classification, taxon: taxon, product: product) } + + it "won't destroy if classification is the primary taxon" do + product.primary_taxon = taxon + classification.destroy.should be_false + classification.errors.messages[:base].should == ["Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted"] + end + end +end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6d90b70761..6a50190448 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -5,6 +5,7 @@ module Spree describe "associations" do it { should belong_to(:supplier) } + it { should belong_to(:primary_taxon) } it { should have_many(:product_distributions) } end @@ -13,6 +14,12 @@ module Spree create(:product).should be_valid end + it "requires a primary taxon" do + product = create(:simple_product) + product.primary_taxon = nil + product.should_not be_valid + end + it "requires a supplier" do product = create(:simple_product) product.supplier = nil @@ -551,10 +558,10 @@ module Spree describe "Taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product) { create(:simple_product, taxons: [taxon1, taxon2]) } + let(:product) { create(:simple_product) } it "returns the first taxon as the primary taxon" do - product.primary_taxon.should == taxon1 + product.taxons.should == [product.primary_taxon] end end end From 110a6f2d14a8ecb09628abf76f2836a275ff6777 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 16:13:47 +1000 Subject: [PATCH 084/139] Adding primary taxon to admin forms --- .../admin/products/_form/add_notes_field.html.haml.deface | 1 - db/migrate/20140522044009_add_primary_taxon_to_products.rb | 2 ++ db/schema.rb | 2 ++ spec/features/admin/products_spec.rb | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface index dadebd01d4..dcc7937d6b 100644 --- a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface @@ -4,4 +4,3 @@ = f.label :notes, t(:notes) = f.text_area :notes, { :class => 'fullwidth', rows: 5 } = f.error_message_on :notes - diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb index ec8e3772b1..f6ff3cfe96 100644 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -1,5 +1,7 @@ class AddPrimaryTaxonToProducts < ActiveRecord::Migration def change add_column :spree_products, :primary_taxon_id, :integer + add_index :spree_products, :primary_taxon_id + add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id end end diff --git a/db/schema.rb b/db/schema.rb index 69e79c2829..6005fd7cb5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -689,6 +689,7 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_index "spree_products", ["name"], :name => "index_products_on_name" add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true + add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" @@ -1093,6 +1094,7 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" + add_foreign_key "spree_products", "spree_taxons", name: "spree_products_primary_taxon_id_fk", column: "primary_taxon_id" add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id" diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index b9f9d7a206..b9fec1ef9f 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -6,6 +6,7 @@ feature %q{ } do include AuthenticationWorkflow include WebHelper + let!(:taxon) { create(:taxon) } background do @supplier = create(:supplier_enterprise, :name => 'New supplier') @@ -22,6 +23,7 @@ feature %q{ fill_in 'product_name', with: 'A new product !!!' fill_in 'product_price', with: '19.99' + select taxon.name, from: "product_primary_taxon_id" select 'New supplier', from: 'product_supplier_id' click_button 'Create' @@ -43,6 +45,8 @@ feature %q{ product.reload product.distributors.sort.should == [@distributors[0], @distributors[2]].sort + + product.product_distributions.map { |pd| pd.enterprise_fee }.sort.should == [@enterprise_fees[0], @enterprise_fees[2]].sort end @@ -55,6 +59,7 @@ feature %q{ fill_in 'product_name', :with => 'A new product !!!' fill_in 'product_price', :with => '19.99' + select taxon.name, from: "product_primary_taxon_id" select 'New supplier', :from => 'product_supplier_id' choose 'product_group_buy_1' fill_in 'Group buy unit size', :with => '10' @@ -99,6 +104,7 @@ feature %q{ page.should have_selector('#product_supplier_id') select 'Another Supplier', :from => 'product_supplier_id' + select taxon.name, from: "product_primary_taxon_id" # Should only have suppliers listed which the user can manage within "#product_supplier_id" do From 58112fb10597ae51e4d7744f9378493abfd217cb Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 23 May 2014 16:01:24 +1000 Subject: [PATCH 085/139] Adding primary taxon --- app/overrides/add_primary_taxon_to_admin_product.rb | 4 ++++ app/overrides/add_primary_taxon_to_admin_product_new.rb | 4 ++++ app/views/spree/admin/products/_primary_taxon_form.html.haml | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 app/overrides/add_primary_taxon_to_admin_product.rb create mode 100644 app/overrides/add_primary_taxon_to_admin_product_new.rb create mode 100644 app/views/spree/admin/products/_primary_taxon_form.html.haml diff --git a/app/overrides/add_primary_taxon_to_admin_product.rb b/app/overrides/add_primary_taxon_to_admin_product.rb new file mode 100644 index 0000000000..9f7c5edde5 --- /dev/null +++ b/app/overrides/add_primary_taxon_to_admin_product.rb @@ -0,0 +1,4 @@ +Deface::Override.new(:virtual_path => "spree/admin/products/_form", + :insert_top => "[data-hook='admin_product_form_right']", + :partial => "spree/admin/products/primary_taxon_form", + :name => "add_primary_taxon_to_admin_product") diff --git a/app/overrides/add_primary_taxon_to_admin_product_new.rb b/app/overrides/add_primary_taxon_to_admin_product_new.rb new file mode 100644 index 0000000000..e5c9d24e7f --- /dev/null +++ b/app/overrides/add_primary_taxon_to_admin_product_new.rb @@ -0,0 +1,4 @@ +Deface::Override.new(:virtual_path => "spree/admin/products/new", + :insert_before => "[data-hook='new_product_attrs']", + :partial => "spree/admin/products/primary_taxon_form", + :name => "add_primary_taxon_to_admin_product_new") diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml new file mode 100644 index 0000000000..a844f4f447 --- /dev/null +++ b/app/views/spree/admin/products/_primary_taxon_form.html.haml @@ -0,0 +1,5 @@ += f.field_container :primary_taxon_id do + = f.label :primary_taxon_id + %br + = f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) + = f.error_message_on :primary_taxon_id From aa23b03f98eec508dcd342e3a4618e97a8aa40e0 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 23 May 2014 17:29:18 +1000 Subject: [PATCH 086/139] Always showing social media --- app/views/modals/_producer.html.haml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index be34e3c20a..6798598f49 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -17,20 +17,19 @@ %a{"bo-href" => "{{producer.website}}", target: "_blank" } %i.fi-web {{ producer.website }} - {{ producer.twitterific }} - %li{"ng-show" => "producer.twitterific"} + %li %a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"} %i.fi-social-twitter {{ producer.twitter }} - %li{"bo-if" => "producer.facebook"} + %li %a{"bo-href" => "{{producer.facebook}}", target: "_blank"} %i.fi-social-facebook {{ producer.facebook }} - %li{"bo-if" => "producer.linkedin"} + %li %a{"bo-href" => "{{producer.linkedin}}", target: "_blank"} %i.fi-social-linkedin {{ producer.linkedin }} - %li{"bo-if" => "producer.instagram"} + %li %a{"bo-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} / Will needs logic to allow user to input @instagramhandle to drive a logical URL %i.fi-social-instagram From 2987ca763db4c755ceaebf761c4c3e43f79ef929 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 15:09:08 +1000 Subject: [PATCH 087/139] Add additional data sanitisation for foreign key migration --- db/migrate/20140402033428_add_foreign_keys.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/db/migrate/20140402033428_add_foreign_keys.rb b/db/migrate/20140402033428_add_foreign_keys.rb index f072127158..fce1ffd009 100644 --- a/db/migrate/20140402033428_add_foreign_keys.rb +++ b/db/migrate/20140402033428_add_foreign_keys.rb @@ -32,6 +32,11 @@ class AddForeignKeys < ActiveRecord::Migration say "Destroying #{orphaned_exchange_variants.count} orphaned ExchangeVariants (of total #{ExchangeVariant.count})" orphaned_exchange_variants.destroy_all + # Remove orphaned ExchangeFee records + orphaned_exchange_fees = ExchangeFee.joins('LEFT OUTER JOIN enterprise_fees ON enterprise_fees.id=exchange_fees.enterprise_fee_id').where('enterprise_fees.id IS NULL') + say "Destroying #{orphaned_exchange_fees.count} orphaned ExchangeFees (of total #{ExchangeFee.count})" + orphaned_exchange_fees.destroy_all + # Remove orphaned Spree::InventoryUnits orphaned_inventory_units = Spree::InventoryUnit.joins('LEFT OUTER JOIN spree_variants ON spree_variants.id=spree_inventory_units.variant_id').where('spree_variants.id IS NULL') say "Destroying #{orphaned_inventory_units.count} orphaned InventoryUnits (of total #{Spree::InventoryUnit.count})" From 9aadc9d1ce76995f5aaedd193e873211cef436b4 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 15:10:21 +1000 Subject: [PATCH 088/139] Add initial user import/export via CSV --- lib/tasks/users.rake | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/tasks/users.rake diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake new file mode 100644 index 0000000000..0f8b8a411b --- /dev/null +++ b/lib/tasks/users.rake @@ -0,0 +1,70 @@ +require 'csv' + +namespace :openfoodnetwork do + + namespace :dev do + desc 'export users to CSV' + task export_users: :environment do + CSV.open('db/users.csv', 'wb') do |csv| + csv << header + # Skip some spambot users + users = Spree::User.all.reject { |u| u.email =~ /example.net/ } + users.each do |user| + csv << row(user) + end + end + end + + + desc 'import users from CSV' + task import_users: :environment do + ActionMailer::Base.delivery_method = :test + + CSV.foreach('db/users.csv') do |row| + next if row[0] == 'encrypted_password' + + create_user_from row + end + end + + + private + + def header + ["encrypted_password", "password_salt", "email", "remember_token", "persistence_token", "reset_password_token", "perishable_token", "sign_in_count", "failed_attempts", "last_request_at", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "login", "created_at", "updated_at", "authentication_token", "unlock_token", "locked_at", "remember_created_at", "reset_password_sent_at", + + "role_name", + + "ship_address_firstname", "ship_address_lastname", "ship_address_address1", "ship_address_address2", "ship_address_city", "ship_address_zipcode", "ship_address_phone", "ship_address_state", "ship_address_country", "ship_address_created_at", "ship_address_updated_at", "ship_address_company", "ship_address_latitude", "ship_address_longitude", + + "bill_address_firstname", "bill_address_lastname", "bill_address_address1", "bill_address_address2", "bill_address_city", "bill_address_zipcode", "bill_address_phone", "bill_address_state", "bill_address_country", "bill_address_created_at", "bill_address_updated_at", "bill_address_company", "bill_address_latitude", "bill_address_longitude"] + end + + + def row(user) + # sa = user.ship_address + # ba = user.bill_address + + [user.encrypted_password, user.password_salt, user.email, user.remember_token, user.persistence_token, user.reset_password_token, user.perishable_token, user.sign_in_count, user.failed_attempts, user.last_request_at, user.current_sign_in_at, user.last_sign_in_at, user.current_sign_in_ip, user.last_sign_in_ip, user.login, user.created_at, user.updated_at, user.authentication_token, user.unlock_token, user.locked_at, user.remember_created_at, user.reset_password_sent_at, + + user.spree_roles.first.andand.name] + + # sa.andand.firstname, sa.andand.lastname, sa.andand.address1, sa.andand.address2, sa.andand.city, sa.andand.zipcode, sa.andand.phone, sa.andand.state, sa.andand.country, sa.andand.created_at, sa.andand.updated_at, sa.andand.company, sa.andand.latitude, sa.andand.longitude, + + # ba.andand.firstname, ba.andand.lastname, ba.andand.address1, ba.andand.address2, ba.andand.city, ba.andand.zipcode, ba.andand.phone, ba.andand.state, ba.andand.country, ba.andand.created_at, ba.andand.updated_at, ba.andand.company, ba.andand.latitude, ba.andand.longitude] + end + + + def create_user_from(row) + user = Spree::User.create!({password: 'changeme123', password_confirmation: 'changeme123', email: row[2], remember_token: row[3], persistence_token: row[4], reset_password_token: row[5], perishable_token: row[6], sign_in_count: row[7], failed_attempts: row[8], last_request_at: row[9], current_sign_in_at: row[10], last_sign_in_at: row[11], current_sign_in_ip: row[12], last_sign_in_ip: row[13], login: row[14], created_at: row[15], updated_at: row[16], authentication_token: row[17], unlock_token: row[18], locked_at: row[19], remember_created_at: row[20], reset_password_sent_at: row[21]}, without_protection: true) + + user.update_column :encrypted_password, row[0] + user.update_column :password_salt, row[1] + + role = Spree::Role.find_by_name row[24] + user.spree_roles << role if role + rescue ActiveRecord::RecordInvalid => e + puts "#{row[2]} - #{e.message}" + end + end +end From d1028cb912555c1909ae103660623d49c51dc724 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 May 2014 17:51:02 +1000 Subject: [PATCH 089/139] User import/export includes addresses --- lib/tasks/users.rake | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake index 0f8b8a411b..323c679fb0 100644 --- a/lib/tasks/users.rake +++ b/lib/tasks/users.rake @@ -7,8 +7,6 @@ namespace :openfoodnetwork do task export_users: :environment do CSV.open('db/users.csv', 'wb') do |csv| csv << header - # Skip some spambot users - users = Spree::User.all.reject { |u| u.email =~ /example.net/ } users.each do |user| csv << row(user) end @@ -30,28 +28,34 @@ namespace :openfoodnetwork do private + def users + # Skip some spambot users + Spree::User.all.reject { |u| u.email =~ /example.net/ } + end + + def header ["encrypted_password", "password_salt", "email", "remember_token", "persistence_token", "reset_password_token", "perishable_token", "sign_in_count", "failed_attempts", "last_request_at", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "login", "created_at", "updated_at", "authentication_token", "unlock_token", "locked_at", "remember_created_at", "reset_password_sent_at", "role_name", - "ship_address_firstname", "ship_address_lastname", "ship_address_address1", "ship_address_address2", "ship_address_city", "ship_address_zipcode", "ship_address_phone", "ship_address_state", "ship_address_country", "ship_address_created_at", "ship_address_updated_at", "ship_address_company", "ship_address_latitude", "ship_address_longitude", + "ship_address_firstname", "ship_address_lastname", "ship_address_address1", "ship_address_address2", "ship_address_city", "ship_address_zipcode", "ship_address_phone", "ship_address_state", "ship_address_country", "ship_address_created_at", "ship_address_updated_at", "ship_address_company", - "bill_address_firstname", "bill_address_lastname", "bill_address_address1", "bill_address_address2", "bill_address_city", "bill_address_zipcode", "bill_address_phone", "bill_address_state", "bill_address_country", "bill_address_created_at", "bill_address_updated_at", "bill_address_company", "bill_address_latitude", "bill_address_longitude"] + "bill_address_firstname", "bill_address_lastname", "bill_address_address1", "bill_address_address2", "bill_address_city", "bill_address_zipcode", "bill_address_phone", "bill_address_state", "bill_address_country", "bill_address_created_at", "bill_address_updated_at", "bill_address_company",] end def row(user) - # sa = user.ship_address - # ba = user.bill_address + sa = user.orders.last.andand.ship_address + ba = user.orders.last.andand.bill_address [user.encrypted_password, user.password_salt, user.email, user.remember_token, user.persistence_token, user.reset_password_token, user.perishable_token, user.sign_in_count, user.failed_attempts, user.last_request_at, user.current_sign_in_at, user.last_sign_in_at, user.current_sign_in_ip, user.last_sign_in_ip, user.login, user.created_at, user.updated_at, user.authentication_token, user.unlock_token, user.locked_at, user.remember_created_at, user.reset_password_sent_at, - user.spree_roles.first.andand.name] + user.spree_roles.first.andand.name, - # sa.andand.firstname, sa.andand.lastname, sa.andand.address1, sa.andand.address2, sa.andand.city, sa.andand.zipcode, sa.andand.phone, sa.andand.state, sa.andand.country, sa.andand.created_at, sa.andand.updated_at, sa.andand.company, sa.andand.latitude, sa.andand.longitude, + sa.andand.firstname, sa.andand.lastname, sa.andand.address1, sa.andand.address2, sa.andand.city, sa.andand.zipcode, sa.andand.phone, sa.andand.state, sa.andand.country, sa.andand.created_at, sa.andand.updated_at, sa.andand.company, - # ba.andand.firstname, ba.andand.lastname, ba.andand.address1, ba.andand.address2, ba.andand.city, ba.andand.zipcode, ba.andand.phone, ba.andand.state, ba.andand.country, ba.andand.created_at, ba.andand.updated_at, ba.andand.company, ba.andand.latitude, ba.andand.longitude] + ba.andand.firstname, ba.andand.lastname, ba.andand.address1, ba.andand.address2, ba.andand.city, ba.andand.zipcode, ba.andand.phone, ba.andand.state, ba.andand.country, ba.andand.created_at, ba.andand.updated_at, ba.andand.company,] end @@ -61,8 +65,20 @@ namespace :openfoodnetwork do user.update_column :encrypted_password, row[0] user.update_column :password_salt, row[1] - role = Spree::Role.find_by_name row[24] - user.spree_roles << role if role + # Safer if we don't make new users into admins + #role = Spree::Role.find_by_name row[24] + #user.spree_roles << role if role + + sa_state = Spree::State.find_by_name row[30] + sa_country = Spree::Country.find_by_name row[31] + sa = Spree::Address.create!({firstname: row[23], lastname: row[24], address1: row[25], address2: row[26], city: row[27], zipcode: row[28], phone: row[29], state: sa_state, country: sa_country, created_at: row[32], updated_at: row[33], company: row[34]}, without_protection: true) + user.update_column :ship_address_id, sa.id + + ba_state = Spree::State.find_by_name row[42] + ba_country = Spree::Country.find_by_name row[43] + ba = Spree::Address.create!({firstname: row[35], lastname: row[36], address1: row[37], address2: row[38], city: row[39], zipcode: row[40], phone: row[41], state: ba_state, country: ba_country, created_at: row[44], updated_at: row[45], company: row[46]}, without_protection: true) + user.update_column :bill_address_id, ba.id + rescue ActiveRecord::RecordInvalid => e puts "#{row[2]} - #{e.message}" end From a7566e34130a6169f98398bbe4ed63b764bdd151 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:07:52 +1000 Subject: [PATCH 090/139] Revert "Always showing social media" This reverts commit aa23b03f98eec508dcd342e3a4618e97a8aa40e0. --- app/views/modals/_producer.html.haml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 6798598f49..be34e3c20a 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -17,19 +17,20 @@ %a{"bo-href" => "{{producer.website}}", target: "_blank" } %i.fi-web {{ producer.website }} - %li + {{ producer.twitterific }} + %li{"ng-show" => "producer.twitterific"} %a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"} %i.fi-social-twitter {{ producer.twitter }} - %li + %li{"bo-if" => "producer.facebook"} %a{"bo-href" => "{{producer.facebook}}", target: "_blank"} %i.fi-social-facebook {{ producer.facebook }} - %li + %li{"bo-if" => "producer.linkedin"} %a{"bo-href" => "{{producer.linkedin}}", target: "_blank"} %i.fi-social-linkedin {{ producer.linkedin }} - %li + %li{"bo-if" => "producer.instagram"} %a{"bo-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} / Will needs logic to allow user to input @instagramhandle to drive a logical URL %i.fi-social-instagram From 7ac33beb65783c1e5fc7624427edd57ccfc5e75b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:07:55 +1000 Subject: [PATCH 091/139] Revert "Adding primary taxon" This reverts commit 58112fb10597ae51e4d7744f9378493abfd217cb. --- app/overrides/add_primary_taxon_to_admin_product.rb | 4 ---- app/overrides/add_primary_taxon_to_admin_product_new.rb | 4 ---- app/views/spree/admin/products/_primary_taxon_form.html.haml | 5 ----- 3 files changed, 13 deletions(-) delete mode 100644 app/overrides/add_primary_taxon_to_admin_product.rb delete mode 100644 app/overrides/add_primary_taxon_to_admin_product_new.rb delete mode 100644 app/views/spree/admin/products/_primary_taxon_form.html.haml diff --git a/app/overrides/add_primary_taxon_to_admin_product.rb b/app/overrides/add_primary_taxon_to_admin_product.rb deleted file mode 100644 index 9f7c5edde5..0000000000 --- a/app/overrides/add_primary_taxon_to_admin_product.rb +++ /dev/null @@ -1,4 +0,0 @@ -Deface::Override.new(:virtual_path => "spree/admin/products/_form", - :insert_top => "[data-hook='admin_product_form_right']", - :partial => "spree/admin/products/primary_taxon_form", - :name => "add_primary_taxon_to_admin_product") diff --git a/app/overrides/add_primary_taxon_to_admin_product_new.rb b/app/overrides/add_primary_taxon_to_admin_product_new.rb deleted file mode 100644 index e5c9d24e7f..0000000000 --- a/app/overrides/add_primary_taxon_to_admin_product_new.rb +++ /dev/null @@ -1,4 +0,0 @@ -Deface::Override.new(:virtual_path => "spree/admin/products/new", - :insert_before => "[data-hook='new_product_attrs']", - :partial => "spree/admin/products/primary_taxon_form", - :name => "add_primary_taxon_to_admin_product_new") diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml deleted file mode 100644 index a844f4f447..0000000000 --- a/app/views/spree/admin/products/_primary_taxon_form.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -= f.field_container :primary_taxon_id do - = f.label :primary_taxon_id - %br - = f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) - = f.error_message_on :primary_taxon_id From 79393476b040707d52bcd182e26ae5fe9ddc6ce4 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:07:56 +1000 Subject: [PATCH 092/139] Revert "Adding primary taxon to admin forms" This reverts commit 110a6f2d14a8ecb09628abf76f2836a275ff6777. --- .../admin/products/_form/add_notes_field.html.haml.deface | 1 + db/migrate/20140522044009_add_primary_taxon_to_products.rb | 2 -- db/schema.rb | 2 -- spec/features/admin/products_spec.rb | 6 ------ 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface index dcc7937d6b..dadebd01d4 100644 --- a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface @@ -4,3 +4,4 @@ = f.label :notes, t(:notes) = f.text_area :notes, { :class => 'fullwidth', rows: 5 } = f.error_message_on :notes + diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb index f6ff3cfe96..ec8e3772b1 100644 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -1,7 +1,5 @@ class AddPrimaryTaxonToProducts < ActiveRecord::Migration def change add_column :spree_products, :primary_taxon_id, :integer - add_index :spree_products, :primary_taxon_id - add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id end end diff --git a/db/schema.rb b/db/schema.rb index 6005fd7cb5..69e79c2829 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -689,7 +689,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_index "spree_products", ["name"], :name => "index_products_on_name" add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true - add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" @@ -1094,7 +1093,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" - add_foreign_key "spree_products", "spree_taxons", name: "spree_products_primary_taxon_id_fk", column: "primary_taxon_id" add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id" diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index b9fec1ef9f..b9f9d7a206 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -6,7 +6,6 @@ feature %q{ } do include AuthenticationWorkflow include WebHelper - let!(:taxon) { create(:taxon) } background do @supplier = create(:supplier_enterprise, :name => 'New supplier') @@ -23,7 +22,6 @@ feature %q{ fill_in 'product_name', with: 'A new product !!!' fill_in 'product_price', with: '19.99' - select taxon.name, from: "product_primary_taxon_id" select 'New supplier', from: 'product_supplier_id' click_button 'Create' @@ -45,8 +43,6 @@ feature %q{ product.reload product.distributors.sort.should == [@distributors[0], @distributors[2]].sort - - product.product_distributions.map { |pd| pd.enterprise_fee }.sort.should == [@enterprise_fees[0], @enterprise_fees[2]].sort end @@ -59,7 +55,6 @@ feature %q{ fill_in 'product_name', :with => 'A new product !!!' fill_in 'product_price', :with => '19.99' - select taxon.name, from: "product_primary_taxon_id" select 'New supplier', :from => 'product_supplier_id' choose 'product_group_buy_1' fill_in 'Group buy unit size', :with => '10' @@ -104,7 +99,6 @@ feature %q{ page.should have_selector('#product_supplier_id') select 'Another Supplier', :from => 'product_supplier_id' - select taxon.name, from: "product_primary_taxon_id" # Should only have suppliers listed which the user can manage within "#product_supplier_id" do From ad1f852bdda2cb9e4744ebbf26c55607b70ef523 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:07:57 +1000 Subject: [PATCH 093/139] Revert "Adding primary taxon field to product" This reverts commit fd1e7ebaa3976327f518e0ef4ee1f347adb8fa8a. --- app/models/enterprise.rb | 1 - app/models/spree/classification_decorator.rb | 10 ---------- app/models/spree/product_decorator.rb | 13 +++++-------- ...0140522044009_add_primary_taxon_to_products.rb | 5 ----- db/schema.rb | 3 +-- spec/factories.rb | 7 ------- spec/models/spree/classification_spec.rb | 15 --------------- spec/models/spree/product_spec.rb | 11 ++--------- 8 files changed, 8 insertions(+), 57 deletions(-) delete mode 100644 app/models/spree/classification_decorator.rb delete mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb delete mode 100644 spec/models/spree/classification_spec.rb diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 5e53316607..a72c6fdbd6 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -15,7 +15,6 @@ class Enterprise < ActiveRecord::Base has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods', class_name: 'Spree::PaymentMethod', foreign_key: 'distributor_id' has_and_belongs_to_many :shipping_methods, join_table: 'distributors_shipping_methods', class_name: 'Spree::ShippingMethod', foreign_key: 'distributor_id' - delegate :latitude, :longitude, :city, :state_name, :to => :address accepts_nested_attributes_for :address diff --git a/app/models/spree/classification_decorator.rb b/app/models/spree/classification_decorator.rb deleted file mode 100644 index 7e34e6890e..0000000000 --- a/app/models/spree/classification_decorator.rb +++ /dev/null @@ -1,10 +0,0 @@ -Spree::Classification.class_eval do - before_destroy :dont_destroy_if_primary_taxon - - def dont_destroy_if_primary_taxon - if product.primary_taxon == taxon - errors.add :base, "Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted" - return false - end - end -end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 13491f94df..ba7cbc253d 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -6,7 +6,6 @@ Spree::Product.class_eval do belongs_to :supplier, :class_name => 'Enterprise' - belongs_to :primary_taxon, class_name: 'Spree::Taxon' has_many :product_distributions, :dependent => :destroy has_many :distributors, :through => :product_distributions @@ -14,10 +13,9 @@ Spree::Product.class_eval do accepts_nested_attributes_for :product_distributions, :allow_destroy => true delegate_belongs_to :master, :unit_value, :unit_description - attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes + attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes validates_presence_of :supplier - validates_presence_of :primary_taxon validates_presence_of :variant_unit, if: :has_variants? validates_presence_of :variant_unit_scale, @@ -27,7 +25,6 @@ Spree::Product.class_eval do after_initialize :set_available_on_to_now, :if => :new_record? after_save :update_units - before_save :add_primary_taxon_to_taxons # -- Joins @@ -121,6 +118,10 @@ Spree::Product.class_eval do order_cycle.variants_distributed_by(distributor).where(product_id: self) end + def primary_taxon + self.taxons.order.first + end + # Build a product distribution for each distributor def build_product_distributions_for_user user Enterprise.is_distributor.managed_by(user).each do |distributor| @@ -156,10 +157,6 @@ Spree::Product.class_eval do end end - def add_primary_taxon_to_taxons - taxons << primary_taxon unless taxons.find_by_id(primary_taxon) - end - def self.all_variant_unit_option_types Spree::OptionType.where('name LIKE ?', 'unit_%%') end diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb deleted file mode 100644 index ec8e3772b1..0000000000 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPrimaryTaxonToProducts < ActiveRecord::Migration - def change - add_column :spree_products, :primary_taxon_id, :integer - end -end diff --git a/db/schema.rb b/db/schema.rb index 69e79c2829..77df8baf75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140522044009) do +ActiveRecord::Schema.define(:version => 20140522015012) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -681,7 +681,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" - t.integer "primary_taxon_id" end add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" diff --git a/spec/factories.rb b/spec/factories.rb index 394112125a..6da7824d47 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -2,9 +2,6 @@ require 'ffaker' require 'spree/core/testing_support/factories' FactoryGirl.define do - factory :classification, class: Spree::Classification do - end - factory :order_cycle, :parent => :simple_order_cycle do coordinator_fees { [create(:enterprise_fee, enterprise: coordinator)] } @@ -153,9 +150,6 @@ end FactoryGirl.modify do - factory :product do - primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } - end factory :simple_product do # Fix product factory name sequence with Kernel.rand so it is not interpreted as a Spree::Product method # Pull request: https://github.com/spree/spree/pull/1964 @@ -163,7 +157,6 @@ FactoryGirl.modify do sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" } supplier { Enterprise.is_primary_producer.first || FactoryGirl.create(:supplier_enterprise) } - primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } on_hand 3 variant_unit 'weight' diff --git a/spec/models/spree/classification_spec.rb b/spec/models/spree/classification_spec.rb deleted file mode 100644 index f26f6da0c0..0000000000 --- a/spec/models/spree/classification_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -module Spree - describe Classification do - let(:product) { create(:simple_product) } - let(:taxon) { create(:taxon) } - let(:classification) { create(:classification, taxon: taxon, product: product) } - - it "won't destroy if classification is the primary taxon" do - product.primary_taxon = taxon - classification.destroy.should be_false - classification.errors.messages[:base].should == ["Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted"] - end - end -end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6a50190448..6d90b70761 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -5,7 +5,6 @@ module Spree describe "associations" do it { should belong_to(:supplier) } - it { should belong_to(:primary_taxon) } it { should have_many(:product_distributions) } end @@ -14,12 +13,6 @@ module Spree create(:product).should be_valid end - it "requires a primary taxon" do - product = create(:simple_product) - product.primary_taxon = nil - product.should_not be_valid - end - it "requires a supplier" do product = create(:simple_product) product.supplier = nil @@ -558,10 +551,10 @@ module Spree describe "Taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product) { create(:simple_product) } + let(:product) { create(:simple_product, taxons: [taxon1, taxon2]) } it "returns the first taxon as the primary taxon" do - product.taxons.should == [product.primary_taxon] + product.primary_taxon.should == taxon1 end end end From bb1b7cfa90238a8515605b571dfade30116f0298 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:07:58 +1000 Subject: [PATCH 094/139] Revert "Adding fields to product supplier" This reverts commit 6d24a6555e217f760d8c7bd602e13d5e5a1cde87. --- app/views/shop/products.rabl | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index ee5e567285..c8b5d5398c 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -10,14 +10,7 @@ node do |product| end child :supplier => :supplier do - attributes :id, :name, :description, :long_description, :website, :instagram, :facebook, :linkedin, :twitter - - node :logo do |supplier| - supplier.logo.url - end - node :promo_image do |supplier| - supplier.promo_image.url - end + attributes :id, :name, :description end child :primary_taxon => :primary_taxon do From 69e0e71eb617e75182e58ccacabbf12db427e71f Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:12:24 +1000 Subject: [PATCH 095/139] Revert "Styling for shop page product modal" This reverts commit 84b6f99321a328a14bfe2044dbebde702860bced. Conflicts: app/assets/stylesheets/darkswarm/images.css.sass app/views/modals/_producer.html.haml --- app/assets/stylesheets/darkswarm/all.scss | 3 ++ .../stylesheets/darkswarm/images.css.sass | 46 ---------------- .../stylesheets/darkswarm/overrides.css.sass | 3 ++ .../stylesheets/darkswarm/shop.css.sass | 3 +- app/views/modals/_producer.html.haml | 52 +++++-------------- app/views/modals/_producers.html.haml | 3 +- app/views/modals/_product.html.haml | 14 +---- 7 files changed, 24 insertions(+), 100 deletions(-) delete mode 100644 app/assets/stylesheets/darkswarm/images.css.sass diff --git a/app/assets/stylesheets/darkswarm/all.scss b/app/assets/stylesheets/darkswarm/all.scss index a8ac8af078..80e43cdc8b 100644 --- a/app/assets/stylesheets/darkswarm/all.scss +++ b/app/assets/stylesheets/darkswarm/all.scss @@ -9,3 +9,6 @@ */ @import 'foundation-icons'; +ofn-modal { + display: block; +} \ No newline at end of file diff --git a/app/assets/stylesheets/darkswarm/images.css.sass b/app/assets/stylesheets/darkswarm/images.css.sass deleted file mode 100644 index 927e906842..0000000000 --- a/app/assets/stylesheets/darkswarm/images.css.sass +++ /dev/null @@ -1,46 +0,0 @@ -@import mixins -@import variables -@import branding - -.product-img - border-bottom: 40px white solid - border-top: 20px white solid - border-left: 20px white solid - border-right: 20px white solid - outline: 1px solid #ccc - @include box-shadow(0 1px 2px 1px rgba(0,0,0,0.25)) - -.producer-hero - position: relative - padding: 0 - -.producer-hero-img - background-color: #999 - width: 100% - height: inherit - max-height: 260px - overflow: hidden - margin-top: 2em - margin-bottom: 1em - - -h3.producer-name - background-color: rgba(255,255,255,0.65) - height: 2.5em - width: 100% - position: absolute - bottom: 0 - padding: 0.5em - -.producer-logo - max-width: 220px - -@media only screen and (max-width: 1024px) - .product-img - margin-top: 2em - margin-bottom: 1em - - - - - diff --git a/app/assets/stylesheets/darkswarm/overrides.css.sass b/app/assets/stylesheets/darkswarm/overrides.css.sass index fcec6b455d..917d6dd2e3 100644 --- a/app/assets/stylesheets/darkswarm/overrides.css.sass +++ b/app/assets/stylesheets/darkswarm/overrides.css.sass @@ -1,2 +1,5 @@ .row max-width: 74em + +.reveal-modal + position: fixed diff --git a/app/assets/stylesheets/darkswarm/shop.css.sass b/app/assets/stylesheets/darkswarm/shop.css.sass index e0030a7d7a..0c2972367a 100644 --- a/app/assets/stylesheets/darkswarm/shop.css.sass +++ b/app/assets/stylesheets/darkswarm/shop.css.sass @@ -81,7 +81,8 @@ padding-top: 1em input.button.right float: left - + + product:hover, product:focus, product:active border-color: $clr-brick @include box-shadow(0 0 3px 0 $clr-brick-bright) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index be34e3c20a..056f9e488f 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,40 +1,12 @@ -%ofn-modal{title: "{{producer.name}}"} - .row - .columns.small-12.producer-hero - %img.producer-hero-img{"ng-src" => "{{producer.promo_image}}"} - / Will - scale large images down to 1200px wide, crop in to img aspect ratio 60W:13H - %h3.producer-name {{ producer.name }} - .row - .columns.small-12.large-6{"inject-html" => "producer.long_description"} - .columns.small-12.large-6 - / Will needs logic to add in following only if data is available for each type: - / Will needs better formatting of URLs printed on-screen (minus http://www.) - / Will needs formatting of URLs driving %a regardless of user input (plus http://www.) - %img.producer-logo{"ng-src" => "{{producer.logo}}"} - %h4 Stay in touch with {{ producer.name }} - %ul.small-block-grid-1{bindonce: true} - %li{"bo-if" => "producer.website"} - %a{"bo-href" => "{{producer.website}}", target: "_blank" } - %i.fi-web - {{ producer.website }} - {{ producer.twitterific }} - %li{"ng-show" => "producer.twitterific"} - %a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"} - %i.fi-social-twitter - {{ producer.twitter }} - %li{"bo-if" => "producer.facebook"} - %a{"bo-href" => "{{producer.facebook}}", target: "_blank"} - %i.fi-social-facebook - {{ producer.facebook }} - %li{"bo-if" => "producer.linkedin"} - %a{"bo-href" => "{{producer.linkedin}}", target: "_blank"} - %i.fi-social-linkedin - {{ producer.linkedin }} - %li{"bo-if" => "producer.instagram"} - %a{"bo-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} - / Will needs logic to allow user to input @instagramhandle to drive a logical URL - %i.fi-social-instagram - {{ producer.instagram }} - - - %a.close-reveal-modal{"ng-click" => "$close()"} × +%ofn-modal{title: "{{ producer.name }}"} + #producer_modal + .row + .small-12.columns + %img{"ng-src" => "producer.promo_image"} + %h3 {{ producer.name }} + .row + .small-6.columns + %p + {{ producer.description }} + .small-6.columns + Stay in touch with {{ producer.name }} diff --git a/app/views/modals/_producers.html.haml b/app/views/modals/_producers.html.haml index 89d8ccabae..153e4dcae3 100644 --- a/app/views/modals/_producers.html.haml +++ b/app/views/modals/_producers.html.haml @@ -1,3 +1,4 @@ %h2 Producers -%p Our producers make all the delicious food you can shop for on the Open Food Network. +%h5 Our producers make the food! All the delicious! +%p More text goes here. %a.close-reveal-modal{"ng-click" => "cancel()"} × \ No newline at end of file diff --git a/app/views/modals/_product.html.haml b/app/views/modals/_product.html.haml index 70137ba987..acca8f919b 100644 --- a/app/views/modals/_product.html.haml +++ b/app/views/modals/_product.html.haml @@ -1,14 +1,4 @@ %ofn-modal{title: "{{product.name}}"} - .row - .columns.small-12.large-6 - %img.product-img{"ng-src" => "{{product.master.images[0].large_url}}"} - .columns.small-12.large-6 - %h2 - %img{"ng-src" => "{{product.primary_taxon.icon}}"} - {{product.name}} - %p {{product.description}} - / %pre - / {{ product | json }} - %a.close-reveal-modal{"ng-click" => "$close()"} × - \ No newline at end of file + {{ product | json }} + {{ product.description }} From 223caa046c0547dbb6e7e4110ac25204c94fcf4d Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:15:22 +1000 Subject: [PATCH 096/139] Revert "Producers modal styling and markup" This reverts commit 465728576961706c0137b51952476113ffdd3419. Conflicts: app/assets/stylesheets/darkswarm/images.css.sass app/views/modals/_producer.html.haml --- app/views/modals/_producer.html.haml | 40 +++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 056f9e488f..037a95398b 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,12 +1,28 @@ -%ofn-modal{title: "{{ producer.name }}"} - #producer_modal - .row - .small-12.columns - %img{"ng-src" => "producer.promo_image"} - %h3 {{ producer.name }} - .row - .small-6.columns - %p - {{ producer.description }} - .small-6.columns - Stay in touch with {{ producer.name }} +/ %ofn-modal{title: "{{ producer.name }}"} +/ #producer_modal +/ .row +/ .small-12.columns +/ %img{"ng-src" => "producer.promo_image"} +/ %h3 {{ producer.name }} +/ .row +/ .small-6.columns +/ %p +/ {{ producer.description }} +/ .small-6.columns +/ Stay in touch with {{ producer.name }} +/ %a.close-reveal-modal{"ng-click" => "$close()"} × + + +%ofn-modal{title: "{{producer.name}}"} + .row + .columns.small-12 + %img.product-img{"ng-src" => "{{producer.promo_image.images[0].large_url}}"} + %h3 {{ producer.name }} + .row + .columns.small-12.large-6 + %p {{ producer.description }} + .columns.small-12.large-6 + Stay in touch with {{ producer.name }} + / %pre + / {{ producer | json }} + %a.close-reveal-modal{"ng-click" => "$close()"} × From e119192cf17ec433456c26d2cb8c15c2ad1b9315 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 09:21:48 +1000 Subject: [PATCH 097/139] Manually revert merge commit "Hack patching the modals" --- Gemfile.lock | 2 +- .../javascripts/darkswarm/all.js.coffee | 1 - .../product_node_controller.js.coffee | 9 +---- .../javascripts/darkswarm/darkswarm.js.coffee | 1 - .../darkswarm/directives/modal.js.coffee | 8 ---- app/views/modals/_producer.html.haml | 40 ++++++------------- 6 files changed, 15 insertions(+), 46 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index cb0e11cced..733ef43572 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -150,7 +150,7 @@ GEM railties (>= 3.1) sprockets tilt - angularjs-rails (1.2.16) + angularjs-rails (1.2.13) ansi (1.4.2) arel (3.0.3) awesome_nested_set (2.1.5) diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index 3a039394ca..20d849f60c 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -6,7 +6,6 @@ #= require angular #= require angular-cookies #= require angular-resource -#= require angular-sanitize #= require ../shared/mm-foundation-tpls-0.2.0-SNAPSHOT #= require ../shared/bindonce.min.js #= require ../shared/ng-infinite-scroll.min.js diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index fa0daababc..959423e3ca 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.controller "ProductNodeCtrl", ($scope, $sce) -> +Darkswarm.controller "ProductNodeCtrl", ($scope) -> $scope.price = -> if $scope.product.variants.length > 0 @@ -8,10 +8,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $sce) -> $scope.product.price $scope.producer = $scope.product.supplier - $scope.producer.twitterific = true + $scope.hasVariants = $scope.product.variants.length > 0 - -Darkswarm.filter "unsafe", ($sce) -> - (val) -> - $sce.trustAsHtml val - diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 8d26384c14..fe128b963a 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -5,7 +5,6 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource", 'infinite-scroll', 'angular-flash.service', 'templates', - 'ngSanitize', 'backstretch']).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) -> $httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') $httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index f641c29cb5..6f62c7cb45 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -16,11 +16,3 @@ Darkswarm.directive "ofnModal", ($modal)-> elem.on "click", => scope.modalInstance = $modal.open(controller: ctrl, template: contents) - -# TODO THIS IS TERRIBLE PLEASE FIX NG-BIND-HTML -Darkswarm.directive "injectHtml", -> - restrict: 'A' - scope: - injectHtml: "=" - link: (scope, elem, attrs, ctrl)-> - elem.html(scope.injectHtml) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 037a95398b..056f9e488f 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -1,28 +1,12 @@ -/ %ofn-modal{title: "{{ producer.name }}"} -/ #producer_modal -/ .row -/ .small-12.columns -/ %img{"ng-src" => "producer.promo_image"} -/ %h3 {{ producer.name }} -/ .row -/ .small-6.columns -/ %p -/ {{ producer.description }} -/ .small-6.columns -/ Stay in touch with {{ producer.name }} -/ %a.close-reveal-modal{"ng-click" => "$close()"} × - - -%ofn-modal{title: "{{producer.name}}"} - .row - .columns.small-12 - %img.product-img{"ng-src" => "{{producer.promo_image.images[0].large_url}}"} - %h3 {{ producer.name }} - .row - .columns.small-12.large-6 - %p {{ producer.description }} - .columns.small-12.large-6 - Stay in touch with {{ producer.name }} - / %pre - / {{ producer | json }} - %a.close-reveal-modal{"ng-click" => "$close()"} × +%ofn-modal{title: "{{ producer.name }}"} + #producer_modal + .row + .small-12.columns + %img{"ng-src" => "producer.promo_image"} + %h3 {{ producer.name }} + .row + .small-6.columns + %p + {{ producer.description }} + .small-6.columns + Stay in touch with {{ producer.name }} From 17f09d18528f1211aef99ce1d1676894bae48282 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 15:49:10 +1000 Subject: [PATCH 098/139] Adding primary taxon field to product --- app/models/enterprise.rb | 1 + app/models/spree/classification_decorator.rb | 10 ++++++++++ app/models/spree/product_decorator.rb | 13 ++++++++----- ...0140522044009_add_primary_taxon_to_products.rb | 5 +++++ db/schema.rb | 3 ++- spec/factories.rb | 7 +++++++ spec/models/spree/classification_spec.rb | 15 +++++++++++++++ spec/models/spree/product_spec.rb | 11 +++++++++-- 8 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 app/models/spree/classification_decorator.rb create mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb create mode 100644 spec/models/spree/classification_spec.rb diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index a72c6fdbd6..5e53316607 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -15,6 +15,7 @@ class Enterprise < ActiveRecord::Base has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods', class_name: 'Spree::PaymentMethod', foreign_key: 'distributor_id' has_and_belongs_to_many :shipping_methods, join_table: 'distributors_shipping_methods', class_name: 'Spree::ShippingMethod', foreign_key: 'distributor_id' + delegate :latitude, :longitude, :city, :state_name, :to => :address accepts_nested_attributes_for :address diff --git a/app/models/spree/classification_decorator.rb b/app/models/spree/classification_decorator.rb new file mode 100644 index 0000000000..7e34e6890e --- /dev/null +++ b/app/models/spree/classification_decorator.rb @@ -0,0 +1,10 @@ +Spree::Classification.class_eval do + before_destroy :dont_destroy_if_primary_taxon + + def dont_destroy_if_primary_taxon + if product.primary_taxon == taxon + errors.add :base, "Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted" + return false + end + end +end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index ba7cbc253d..13491f94df 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -6,6 +6,7 @@ Spree::Product.class_eval do belongs_to :supplier, :class_name => 'Enterprise' + belongs_to :primary_taxon, class_name: 'Spree::Taxon' has_many :product_distributions, :dependent => :destroy has_many :distributors, :through => :product_distributions @@ -13,9 +14,10 @@ Spree::Product.class_eval do accepts_nested_attributes_for :product_distributions, :allow_destroy => true delegate_belongs_to :master, :unit_value, :unit_description - attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes + attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes validates_presence_of :supplier + validates_presence_of :primary_taxon validates_presence_of :variant_unit, if: :has_variants? validates_presence_of :variant_unit_scale, @@ -25,6 +27,7 @@ Spree::Product.class_eval do after_initialize :set_available_on_to_now, :if => :new_record? after_save :update_units + before_save :add_primary_taxon_to_taxons # -- Joins @@ -118,10 +121,6 @@ Spree::Product.class_eval do order_cycle.variants_distributed_by(distributor).where(product_id: self) end - def primary_taxon - self.taxons.order.first - end - # Build a product distribution for each distributor def build_product_distributions_for_user user Enterprise.is_distributor.managed_by(user).each do |distributor| @@ -157,6 +156,10 @@ Spree::Product.class_eval do end end + def add_primary_taxon_to_taxons + taxons << primary_taxon unless taxons.find_by_id(primary_taxon) + end + def self.all_variant_unit_option_types Spree::OptionType.where('name LIKE ?', 'unit_%%') end diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb new file mode 100644 index 0000000000..ec8e3772b1 --- /dev/null +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -0,0 +1,5 @@ +class AddPrimaryTaxonToProducts < ActiveRecord::Migration + def change + add_column :spree_products, :primary_taxon_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 77df8baf75..69e79c2829 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140522015012) do +ActiveRecord::Schema.define(:version => 20140522044009) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -681,6 +681,7 @@ ActiveRecord::Schema.define(:version => 20140522015012) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" + t.integer "primary_taxon_id" end add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" diff --git a/spec/factories.rb b/spec/factories.rb index 6da7824d47..394112125a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -2,6 +2,9 @@ require 'ffaker' require 'spree/core/testing_support/factories' FactoryGirl.define do + factory :classification, class: Spree::Classification do + end + factory :order_cycle, :parent => :simple_order_cycle do coordinator_fees { [create(:enterprise_fee, enterprise: coordinator)] } @@ -150,6 +153,9 @@ end FactoryGirl.modify do + factory :product do + primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } + end factory :simple_product do # Fix product factory name sequence with Kernel.rand so it is not interpreted as a Spree::Product method # Pull request: https://github.com/spree/spree/pull/1964 @@ -157,6 +163,7 @@ FactoryGirl.modify do sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" } supplier { Enterprise.is_primary_producer.first || FactoryGirl.create(:supplier_enterprise) } + primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } on_hand 3 variant_unit 'weight' diff --git a/spec/models/spree/classification_spec.rb b/spec/models/spree/classification_spec.rb new file mode 100644 index 0000000000..f26f6da0c0 --- /dev/null +++ b/spec/models/spree/classification_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +module Spree + describe Classification do + let(:product) { create(:simple_product) } + let(:taxon) { create(:taxon) } + let(:classification) { create(:classification, taxon: taxon, product: product) } + + it "won't destroy if classification is the primary taxon" do + product.primary_taxon = taxon + classification.destroy.should be_false + classification.errors.messages[:base].should == ["Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted"] + end + end +end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6d90b70761..6a50190448 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -5,6 +5,7 @@ module Spree describe "associations" do it { should belong_to(:supplier) } + it { should belong_to(:primary_taxon) } it { should have_many(:product_distributions) } end @@ -13,6 +14,12 @@ module Spree create(:product).should be_valid end + it "requires a primary taxon" do + product = create(:simple_product) + product.primary_taxon = nil + product.should_not be_valid + end + it "requires a supplier" do product = create(:simple_product) product.supplier = nil @@ -551,10 +558,10 @@ module Spree describe "Taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product) { create(:simple_product, taxons: [taxon1, taxon2]) } + let(:product) { create(:simple_product) } it "returns the first taxon as the primary taxon" do - product.primary_taxon.should == taxon1 + product.taxons.should == [product.primary_taxon] end end end From 0a8f5d91ba50e24a6455b670b7cc790fde91395d Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 22 May 2014 16:13:47 +1000 Subject: [PATCH 099/139] Adding primary taxon to admin forms --- .../admin/products/_form/add_notes_field.html.haml.deface | 1 - db/migrate/20140522044009_add_primary_taxon_to_products.rb | 2 ++ db/schema.rb | 2 ++ spec/features/admin/products_spec.rb | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface index dadebd01d4..dcc7937d6b 100644 --- a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface @@ -4,4 +4,3 @@ = f.label :notes, t(:notes) = f.text_area :notes, { :class => 'fullwidth', rows: 5 } = f.error_message_on :notes - diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb index ec8e3772b1..f6ff3cfe96 100644 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -1,5 +1,7 @@ class AddPrimaryTaxonToProducts < ActiveRecord::Migration def change add_column :spree_products, :primary_taxon_id, :integer + add_index :spree_products, :primary_taxon_id + add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id end end diff --git a/db/schema.rb b/db/schema.rb index 69e79c2829..6005fd7cb5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -689,6 +689,7 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_index "spree_products", ["name"], :name => "index_products_on_name" add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true + add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" @@ -1093,6 +1094,7 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" + add_foreign_key "spree_products", "spree_taxons", name: "spree_products_primary_taxon_id_fk", column: "primary_taxon_id" add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id" diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index b9f9d7a206..b9fec1ef9f 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -6,6 +6,7 @@ feature %q{ } do include AuthenticationWorkflow include WebHelper + let!(:taxon) { create(:taxon) } background do @supplier = create(:supplier_enterprise, :name => 'New supplier') @@ -22,6 +23,7 @@ feature %q{ fill_in 'product_name', with: 'A new product !!!' fill_in 'product_price', with: '19.99' + select taxon.name, from: "product_primary_taxon_id" select 'New supplier', from: 'product_supplier_id' click_button 'Create' @@ -43,6 +45,8 @@ feature %q{ product.reload product.distributors.sort.should == [@distributors[0], @distributors[2]].sort + + product.product_distributions.map { |pd| pd.enterprise_fee }.sort.should == [@enterprise_fees[0], @enterprise_fees[2]].sort end @@ -55,6 +59,7 @@ feature %q{ fill_in 'product_name', :with => 'A new product !!!' fill_in 'product_price', :with => '19.99' + select taxon.name, from: "product_primary_taxon_id" select 'New supplier', :from => 'product_supplier_id' choose 'product_group_buy_1' fill_in 'Group buy unit size', :with => '10' @@ -99,6 +104,7 @@ feature %q{ page.should have_selector('#product_supplier_id') select 'Another Supplier', :from => 'product_supplier_id' + select taxon.name, from: "product_primary_taxon_id" # Should only have suppliers listed which the user can manage within "#product_supplier_id" do From 2db63540eee3194825e2ed39785484f81c880c56 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 23 May 2014 16:01:24 +1000 Subject: [PATCH 100/139] Adding primary taxon --- app/overrides/add_primary_taxon_to_admin_product.rb | 4 ++++ app/overrides/add_primary_taxon_to_admin_product_new.rb | 4 ++++ app/views/spree/admin/products/_primary_taxon_form.html.haml | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 app/overrides/add_primary_taxon_to_admin_product.rb create mode 100644 app/overrides/add_primary_taxon_to_admin_product_new.rb create mode 100644 app/views/spree/admin/products/_primary_taxon_form.html.haml diff --git a/app/overrides/add_primary_taxon_to_admin_product.rb b/app/overrides/add_primary_taxon_to_admin_product.rb new file mode 100644 index 0000000000..9f7c5edde5 --- /dev/null +++ b/app/overrides/add_primary_taxon_to_admin_product.rb @@ -0,0 +1,4 @@ +Deface::Override.new(:virtual_path => "spree/admin/products/_form", + :insert_top => "[data-hook='admin_product_form_right']", + :partial => "spree/admin/products/primary_taxon_form", + :name => "add_primary_taxon_to_admin_product") diff --git a/app/overrides/add_primary_taxon_to_admin_product_new.rb b/app/overrides/add_primary_taxon_to_admin_product_new.rb new file mode 100644 index 0000000000..e5c9d24e7f --- /dev/null +++ b/app/overrides/add_primary_taxon_to_admin_product_new.rb @@ -0,0 +1,4 @@ +Deface::Override.new(:virtual_path => "spree/admin/products/new", + :insert_before => "[data-hook='new_product_attrs']", + :partial => "spree/admin/products/primary_taxon_form", + :name => "add_primary_taxon_to_admin_product_new") diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml new file mode 100644 index 0000000000..a844f4f447 --- /dev/null +++ b/app/views/spree/admin/products/_primary_taxon_form.html.haml @@ -0,0 +1,5 @@ += f.field_container :primary_taxon_id do + = f.label :primary_taxon_id + %br + = f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) + = f.error_message_on :primary_taxon_id From e6461ba01eb374e3e7a82d045516393836e9bea8 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 10:34:22 +1000 Subject: [PATCH 101/139] Fix enterprises spec - primary taxons change --- spec/models/enterprise_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index f375b8890a..fac9286d9b 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -422,8 +422,8 @@ describe Enterprise do let(:supplier) { create(:supplier_enterprise) } let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product1) { create(:simple_product, taxons: [taxon1]) } - let(:product2) { create(:simple_product, taxons: [taxon1, taxon2]) } + let(:product1) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1]) } + let(:product2) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1, taxon2]) } it "gets all taxons of all distributed products" do Spree::Product.stub(:in_distributor).and_return [product1, product2] From acbe49b8dea8e7bd1c8c3a91e98fd40930ed946b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 17:11:36 +1000 Subject: [PATCH 102/139] Revert primary taxons --- app/models/enterprise.rb | 1 - app/models/spree/classification_decorator.rb | 10 ---------- app/models/spree/product_decorator.rb | 13 +++++-------- .../add_primary_taxon_to_admin_product.rb | 4 ---- .../add_primary_taxon_to_admin_product_new.rb | 4 ---- .../_form/add_notes_field.html.haml.deface | 1 + .../admin/products/_primary_taxon_form.html.haml | 5 ----- ...0140522044009_add_primary_taxon_to_products.rb | 7 ------- db/schema.rb | 5 +---- spec/factories.rb | 7 ------- spec/features/admin/products_spec.rb | 6 ------ spec/models/enterprise_spec.rb | 4 ++-- spec/models/spree/classification_spec.rb | 15 --------------- spec/models/spree/product_spec.rb | 11 ++--------- 14 files changed, 11 insertions(+), 82 deletions(-) delete mode 100644 app/models/spree/classification_decorator.rb delete mode 100644 app/overrides/add_primary_taxon_to_admin_product.rb delete mode 100644 app/overrides/add_primary_taxon_to_admin_product_new.rb delete mode 100644 app/views/spree/admin/products/_primary_taxon_form.html.haml delete mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb delete mode 100644 spec/models/spree/classification_spec.rb diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 5e53316607..a72c6fdbd6 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -15,7 +15,6 @@ class Enterprise < ActiveRecord::Base has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods', class_name: 'Spree::PaymentMethod', foreign_key: 'distributor_id' has_and_belongs_to_many :shipping_methods, join_table: 'distributors_shipping_methods', class_name: 'Spree::ShippingMethod', foreign_key: 'distributor_id' - delegate :latitude, :longitude, :city, :state_name, :to => :address accepts_nested_attributes_for :address diff --git a/app/models/spree/classification_decorator.rb b/app/models/spree/classification_decorator.rb deleted file mode 100644 index 7e34e6890e..0000000000 --- a/app/models/spree/classification_decorator.rb +++ /dev/null @@ -1,10 +0,0 @@ -Spree::Classification.class_eval do - before_destroy :dont_destroy_if_primary_taxon - - def dont_destroy_if_primary_taxon - if product.primary_taxon == taxon - errors.add :base, "Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted" - return false - end - end -end diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 13491f94df..ba7cbc253d 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -6,7 +6,6 @@ Spree::Product.class_eval do belongs_to :supplier, :class_name => 'Enterprise' - belongs_to :primary_taxon, class_name: 'Spree::Taxon' has_many :product_distributions, :dependent => :destroy has_many :distributors, :through => :product_distributions @@ -14,10 +13,9 @@ Spree::Product.class_eval do accepts_nested_attributes_for :product_distributions, :allow_destroy => true delegate_belongs_to :master, :unit_value, :unit_description - attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes + attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes validates_presence_of :supplier - validates_presence_of :primary_taxon validates_presence_of :variant_unit, if: :has_variants? validates_presence_of :variant_unit_scale, @@ -27,7 +25,6 @@ Spree::Product.class_eval do after_initialize :set_available_on_to_now, :if => :new_record? after_save :update_units - before_save :add_primary_taxon_to_taxons # -- Joins @@ -121,6 +118,10 @@ Spree::Product.class_eval do order_cycle.variants_distributed_by(distributor).where(product_id: self) end + def primary_taxon + self.taxons.order.first + end + # Build a product distribution for each distributor def build_product_distributions_for_user user Enterprise.is_distributor.managed_by(user).each do |distributor| @@ -156,10 +157,6 @@ Spree::Product.class_eval do end end - def add_primary_taxon_to_taxons - taxons << primary_taxon unless taxons.find_by_id(primary_taxon) - end - def self.all_variant_unit_option_types Spree::OptionType.where('name LIKE ?', 'unit_%%') end diff --git a/app/overrides/add_primary_taxon_to_admin_product.rb b/app/overrides/add_primary_taxon_to_admin_product.rb deleted file mode 100644 index 9f7c5edde5..0000000000 --- a/app/overrides/add_primary_taxon_to_admin_product.rb +++ /dev/null @@ -1,4 +0,0 @@ -Deface::Override.new(:virtual_path => "spree/admin/products/_form", - :insert_top => "[data-hook='admin_product_form_right']", - :partial => "spree/admin/products/primary_taxon_form", - :name => "add_primary_taxon_to_admin_product") diff --git a/app/overrides/add_primary_taxon_to_admin_product_new.rb b/app/overrides/add_primary_taxon_to_admin_product_new.rb deleted file mode 100644 index e5c9d24e7f..0000000000 --- a/app/overrides/add_primary_taxon_to_admin_product_new.rb +++ /dev/null @@ -1,4 +0,0 @@ -Deface::Override.new(:virtual_path => "spree/admin/products/new", - :insert_before => "[data-hook='new_product_attrs']", - :partial => "spree/admin/products/primary_taxon_form", - :name => "add_primary_taxon_to_admin_product_new") diff --git a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface index dcc7937d6b..dadebd01d4 100644 --- a/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface +++ b/app/overrides/spree/admin/products/_form/add_notes_field.html.haml.deface @@ -4,3 +4,4 @@ = f.label :notes, t(:notes) = f.text_area :notes, { :class => 'fullwidth', rows: 5 } = f.error_message_on :notes + diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml deleted file mode 100644 index a844f4f447..0000000000 --- a/app/views/spree/admin/products/_primary_taxon_form.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -= f.field_container :primary_taxon_id do - = f.label :primary_taxon_id - %br - = f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) - = f.error_message_on :primary_taxon_id diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb deleted file mode 100644 index f6ff3cfe96..0000000000 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddPrimaryTaxonToProducts < ActiveRecord::Migration - def change - add_column :spree_products, :primary_taxon_id, :integer - add_index :spree_products, :primary_taxon_id - add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id - end -end diff --git a/db/schema.rb b/db/schema.rb index 6005fd7cb5..77df8baf75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140522044009) do +ActiveRecord::Schema.define(:version => 20140522015012) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -681,7 +681,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" - t.integer "primary_taxon_id" end add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" @@ -689,7 +688,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_index "spree_products", ["name"], :name => "index_products_on_name" add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true - add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" @@ -1094,7 +1092,6 @@ ActiveRecord::Schema.define(:version => 20140522044009) do add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" - add_foreign_key "spree_products", "spree_taxons", name: "spree_products_primary_taxon_id_fk", column: "primary_taxon_id" add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id" diff --git a/spec/factories.rb b/spec/factories.rb index 394112125a..6da7824d47 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -2,9 +2,6 @@ require 'ffaker' require 'spree/core/testing_support/factories' FactoryGirl.define do - factory :classification, class: Spree::Classification do - end - factory :order_cycle, :parent => :simple_order_cycle do coordinator_fees { [create(:enterprise_fee, enterprise: coordinator)] } @@ -153,9 +150,6 @@ end FactoryGirl.modify do - factory :product do - primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } - end factory :simple_product do # Fix product factory name sequence with Kernel.rand so it is not interpreted as a Spree::Product method # Pull request: https://github.com/spree/spree/pull/1964 @@ -163,7 +157,6 @@ FactoryGirl.modify do sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" } supplier { Enterprise.is_primary_producer.first || FactoryGirl.create(:supplier_enterprise) } - primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) } on_hand 3 variant_unit 'weight' diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index b9fec1ef9f..b9f9d7a206 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -6,7 +6,6 @@ feature %q{ } do include AuthenticationWorkflow include WebHelper - let!(:taxon) { create(:taxon) } background do @supplier = create(:supplier_enterprise, :name => 'New supplier') @@ -23,7 +22,6 @@ feature %q{ fill_in 'product_name', with: 'A new product !!!' fill_in 'product_price', with: '19.99' - select taxon.name, from: "product_primary_taxon_id" select 'New supplier', from: 'product_supplier_id' click_button 'Create' @@ -45,8 +43,6 @@ feature %q{ product.reload product.distributors.sort.should == [@distributors[0], @distributors[2]].sort - - product.product_distributions.map { |pd| pd.enterprise_fee }.sort.should == [@enterprise_fees[0], @enterprise_fees[2]].sort end @@ -59,7 +55,6 @@ feature %q{ fill_in 'product_name', :with => 'A new product !!!' fill_in 'product_price', :with => '19.99' - select taxon.name, from: "product_primary_taxon_id" select 'New supplier', :from => 'product_supplier_id' choose 'product_group_buy_1' fill_in 'Group buy unit size', :with => '10' @@ -104,7 +99,6 @@ feature %q{ page.should have_selector('#product_supplier_id') select 'Another Supplier', :from => 'product_supplier_id' - select taxon.name, from: "product_primary_taxon_id" # Should only have suppliers listed which the user can manage within "#product_supplier_id" do diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index fac9286d9b..f375b8890a 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -422,8 +422,8 @@ describe Enterprise do let(:supplier) { create(:supplier_enterprise) } let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product1) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1]) } - let(:product2) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1, taxon2]) } + let(:product1) { create(:simple_product, taxons: [taxon1]) } + let(:product2) { create(:simple_product, taxons: [taxon1, taxon2]) } it "gets all taxons of all distributed products" do Spree::Product.stub(:in_distributor).and_return [product1, product2] diff --git a/spec/models/spree/classification_spec.rb b/spec/models/spree/classification_spec.rb deleted file mode 100644 index f26f6da0c0..0000000000 --- a/spec/models/spree/classification_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -module Spree - describe Classification do - let(:product) { create(:simple_product) } - let(:taxon) { create(:taxon) } - let(:classification) { create(:classification, taxon: taxon, product: product) } - - it "won't destroy if classification is the primary taxon" do - product.primary_taxon = taxon - classification.destroy.should be_false - classification.errors.messages[:base].should == ["Taxon #{taxon.name} is the primary taxon of #{product.name} and cannot be deleted"] - end - end -end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 6a50190448..6d90b70761 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -5,7 +5,6 @@ module Spree describe "associations" do it { should belong_to(:supplier) } - it { should belong_to(:primary_taxon) } it { should have_many(:product_distributions) } end @@ -14,12 +13,6 @@ module Spree create(:product).should be_valid end - it "requires a primary taxon" do - product = create(:simple_product) - product.primary_taxon = nil - product.should_not be_valid - end - it "requires a supplier" do product = create(:simple_product) product.supplier = nil @@ -558,10 +551,10 @@ module Spree describe "Taxons" do let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } - let(:product) { create(:simple_product) } + let(:product) { create(:simple_product, taxons: [taxon1, taxon2]) } it "returns the first taxon as the primary taxon" do - product.taxons.should == [product.primary_taxon] + product.primary_taxon.should == taxon1 end end end From 403e957111a594bbb7a07219b5705e5af5d52574 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 11:14:14 +1000 Subject: [PATCH 103/139] Further removal of references to 'Admin' from global namespace --- .../controllers/enterprise_relationships_controller.js.coffee | 2 +- .../admin/services/enterprise_relationships.js.coffee | 2 +- app/assets/javascripts/admin/services/enterprises.js.coffee | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee index c66e79c046..665753a522 100644 --- a/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee +++ b/app/assets/javascripts/admin/controllers/enterprise_relationships_controller.js.coffee @@ -1,4 +1,4 @@ -Admin.controller "AdminEnterpriseRelationshipsCtrl", ($scope, EnterpriseRelationships, Enterprises) -> +angular.module("ofn.admin").controller "AdminEnterpriseRelationshipsCtrl", ($scope, EnterpriseRelationships, Enterprises) -> $scope.EnterpriseRelationships = EnterpriseRelationships $scope.Enterprises = Enterprises diff --git a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee index 0469aa5637..e07b992112 100644 --- a/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee +++ b/app/assets/javascripts/admin/services/enterprise_relationships.js.coffee @@ -1,4 +1,4 @@ -Admin.factory 'EnterpriseRelationships', ($http, enterprise_relationships) -> +angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterprise_relationships) -> new class EnterpriseRelationships create_errors: "" diff --git a/app/assets/javascripts/admin/services/enterprises.js.coffee b/app/assets/javascripts/admin/services/enterprises.js.coffee index 778a915c22..5b5fd6a009 100644 --- a/app/assets/javascripts/admin/services/enterprises.js.coffee +++ b/app/assets/javascripts/admin/services/enterprises.js.coffee @@ -1,4 +1,4 @@ -Admin.factory 'Enterprises', (my_enterprises, all_enterprises) -> +angular.module("ofn.admin").factory 'Enterprises', (my_enterprises, all_enterprises) -> new class Enterprises constructor: -> @my_enterprises = my_enterprises From cc2498bb9bae1f514217aa8686b6cc7d02bbb0b4 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 24 May 2014 18:26:02 +1000 Subject: [PATCH 104/139] Fix spec fails - group buy and available on removed from new product form --- spec/features/admin/bulk_product_update_spec.rb | 2 -- spec/features/admin/products_spec.rb | 15 ++++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index 7174da9758..d89280df80 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -236,9 +236,7 @@ feature %q{ fill_in 'product_name', :with => 'Big Bag Of Apples' select(s.name, :from => 'product_supplier_id') - choose('product_group_buy_0') fill_in 'product_price', :with => '10.00' - fill_in 'product_available_on', :with => Date.today.strftime("%Y/%m/%d") click_button 'Create' URI.parse(current_url).path.should == '/admin/products/bulk_edit' diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb index b9f9d7a206..efe531224d 100644 --- a/spec/features/admin/products_spec.rb +++ b/spec/features/admin/products_spec.rb @@ -46,23 +46,20 @@ feature %q{ product.product_distributions.map { |pd| pd.enterprise_fee }.sort.should == [@enterprise_fees[0], @enterprise_fees[2]].sort end + scenario "making a product into a group buy product" do + product = create(:simple_product, name: 'group buy product') - scenario "creating a group buy product" do login_to_admin_section - click_link 'Products' - click_link 'New Product' + visit spree.edit_admin_product_path(product) - fill_in 'product_name', :with => 'A new product !!!' - fill_in 'product_price', :with => '19.99' - select 'New supplier', :from => 'product_supplier_id' choose 'product_group_buy_1' fill_in 'Group buy unit size', :with => '10' - click_button 'Create' + click_button 'Update' - flash_message.should == 'Product "A new product !!!" has been successfully created!' - product = Spree::Product.find_by_name('A new product !!!') + flash_message.should == 'Product "group buy product" has been successfully updated!' + product.reload product.group_buy.should be_true product.group_buy_unit_size.should == 10.0 end From 2130470eafb8d36cf21d1b9b725dddd82a5a4cac Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 27 May 2014 17:11:42 +1000 Subject: [PATCH 105/139] Styling for groups page --- .../stylesheets/darkswarm/groups.css.sass | 39 +++++++++++++++++++ app/views/groups/index.html.haml | 39 ++++++++++++++----- app/views/modals/_groups.html.haml | 4 ++ 3 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 app/assets/stylesheets/darkswarm/groups.css.sass create mode 100644 app/views/modals/_groups.html.haml diff --git a/app/assets/stylesheets/darkswarm/groups.css.sass b/app/assets/stylesheets/darkswarm/groups.css.sass new file mode 100644 index 0000000000..90f4af2a74 --- /dev/null +++ b/app/assets/stylesheets/darkswarm/groups.css.sass @@ -0,0 +1,39 @@ +@import branding +@import mixins + +#groups + background-color: $clr-brick-light + +.group + .group_footer + margin-bottom: 1em + hr + border-bottom: 10px solid white + outline: none + border-top: none + margin-top: none + +.group-hero + position: relative + padding: 0 + border: 10px solid white + background: white + +h3.group-name + margin-top: 0.5em + margin-bottom: 0.15em + +img.group-logo + max-width: 220px + max-height: 86px + float: right + padding-top: 10px + + +img.group-hero-img + background-color: black + width: 100% + height: inherit + max-height: 260px + min-height: 120px + overflow: hidden \ No newline at end of file diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index 552e45fd48..fdbf8c5ee6 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -1,10 +1,15 @@ #groups{"ng-controller" => "GroupsCtrl"} :javascript angular.module('Darkswarm').value('groups', #{render partial: "json/groups", object: @groups}) - .row + .row.pad-top .small-12.columns.text-center %h1 Groups / Regions - %h3 Check out our food groups below + %div + Check out our + %ofn-modal{title: "food groups"} + = render partial: "modals/groups" + below + %p %input{type: :text, "ng-model" => "query", @@ -12,14 +17,28 @@ "ng-debounce" => "150", "ofn-disable-enter" => true} - .row.group_table{bindonce: true} - .small.12.columns - .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} - %h2 {{ group.name }} - %p {{ group.description }} + .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} + + .row.pad-top{bindonce: true} + .small-12.columns + .group-hero + %img.group-hero-img{"bo-src" => "{{group.promo_image}}"} + %img.group-logo{"bo-src" => "group.logo"} + %h3.group-name {{ group.name }} + %h5.group-description {{ group.description }} + / Will - scale large images down to 1200px wide, crop in to img aspect ratio 60W:13H + + .row.pad-top{bindonce: true} + .small-6.columns %p {{ group.long_description }} - %img{"bo-src" => "group.logo"} - - %ul + .small-6.columns + %h5 Our hubs & producers + %ul.small-block-grid-2 %li{"ng-repeat" => "enterprise in group.enterprises"} %a{"bo-href" => "enterprise.path"} {{ enterprise.name }} + + .row.group_footer + .small-12.columns + %hr + += render partial: "shared/footer" diff --git a/app/views/modals/_groups.html.haml b/app/views/modals/_groups.html.haml new file mode 100644 index 0000000000..80e210c98a --- /dev/null +++ b/app/views/modals/_groups.html.haml @@ -0,0 +1,4 @@ +%h2 Groups / Regions +%p These are the organisations and relationships between hubs which make up the Open Food Network. +%p Some groups are clustered by location or council, others by non-geographic similarities. +%a.close-reveal-modal{"ng-click" => "cancel()"} × \ No newline at end of file From 9fe4bef7df91391f25422907eb6a5fecbd210393 Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 27 May 2014 17:55:51 +1000 Subject: [PATCH 106/139] Adding groups icon into background for visual consistency --- app/assets/images/groups.svg | 1565 +++++++++++++++++ .../stylesheets/darkswarm/groups.css.sass | 3 + 2 files changed, 1568 insertions(+) create mode 100644 app/assets/images/groups.svg diff --git a/app/assets/images/groups.svg b/app/assets/images/groups.svg new file mode 100644 index 0000000000..f4ca32ec27 --- /dev/null +++ b/app/assets/images/groups.svg @@ -0,0 +1,1565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/assets/stylesheets/darkswarm/groups.css.sass b/app/assets/stylesheets/darkswarm/groups.css.sass index 90f4af2a74..42ce75ac46 100644 --- a/app/assets/stylesheets/darkswarm/groups.css.sass +++ b/app/assets/stylesheets/darkswarm/groups.css.sass @@ -3,6 +3,9 @@ #groups background-color: $clr-brick-light + background-image: url("/assets/groups.svg") + background-position: center 10px + background-repeat: no-repeat .group .group_footer From 3c3409bc1f908ca6160423dfe5961bbb1a9aa7d1 Mon Sep 17 00:00:00 2001 From: summerscope Date: Tue, 27 May 2014 18:03:12 +1000 Subject: [PATCH 107/139] Tweaks to styling on groups page --- app/assets/stylesheets/darkswarm/groups.css.sass | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/groups.css.sass b/app/assets/stylesheets/darkswarm/groups.css.sass index 42ce75ac46..b859273ab7 100644 --- a/app/assets/stylesheets/darkswarm/groups.css.sass +++ b/app/assets/stylesheets/darkswarm/groups.css.sass @@ -4,17 +4,17 @@ #groups background-color: $clr-brick-light background-image: url("/assets/groups.svg") - background-position: center 10px + background-position: center 15px background-repeat: no-repeat + padding-bottom: 20px .group - .group_footer - margin-bottom: 1em - hr - border-bottom: 10px solid white - outline: none - border-top: none - margin-top: none + padding-bottom: 40px + hr + border-bottom: 10px solid white + outline: 0 + border-top: 0 + margin: 0 .group-hero position: relative From 1a79b966e96bac39c7795139895d4e8e86485f81 Mon Sep 17 00:00:00 2001 From: summerscope Date: Wed, 28 May 2014 12:21:25 +1000 Subject: [PATCH 108/139] Adding in links to homepage buttons for Groups & Producers --- app/assets/stylesheets/darkswarm/mixins.sass | 4 ++-- app/views/home/_groups.html.haml | 2 +- app/views/home/_producers.html.haml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/mixins.sass b/app/assets/stylesheets/darkswarm/mixins.sass index fde601f2d9..fd26cfcae9 100644 --- a/app/assets/stylesheets/darkswarm/mixins.sass +++ b/app/assets/stylesheets/darkswarm/mixins.sass @@ -85,10 +85,10 @@ &, & * color: $clr-turquoise a - color: white + color: $clr-turquoise &:hover text-decoration: none - color: $clr-turquoise-light + color: $clr-turquoise-bright @mixin fullbg background-position: center center diff --git a/app/views/home/_groups.html.haml b/app/views/home/_groups.html.haml index 0e16977f20..dd55a9bcd1 100644 --- a/app/views/home/_groups.html.haml +++ b/app/views/home/_groups.html.haml @@ -5,6 +5,6 @@ %h2 Groups / Regions %h5 See all the groups & regions on the Open Food Network %p - %button.neutral-btn.light + %a.neutral-btn.light{href: "/groups"} %i.fi-torsos-all View groups & regions \ No newline at end of file diff --git a/app/views/home/_producers.html.haml b/app/views/home/_producers.html.haml index c24f170e72..31a573d610 100644 --- a/app/views/home/_producers.html.haml +++ b/app/views/home/_producers.html.haml @@ -5,6 +5,6 @@ %h2 Producers %h5 Looking for a specific producer or farmer? %p - %button.neutral-btn.turquoise + %a.neutral-btn.turquoise{href: "/producers"} %i.fi-trees View all producers \ No newline at end of file From 1af82bd4fb492d5d7b377f26149a11b4f79c1559 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 12:58:06 +1000 Subject: [PATCH 109/139] Forcing scope to parent scope so we don't child our child Conflicts: app/assets/javascripts/darkswarm/directives/modal.js.coffee --- app/assets/javascripts/darkswarm/directives/modal.js.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index f641c29cb5..c1af42b2fc 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -8,14 +8,13 @@ Darkswarm.directive "ofnModal", ($modal)-> link: (scope, elem, attrs, ctrl, transclude)-> scope.title = attrs.title contents = null - # We're using an isolate scope, which is a child of the original scope # We have to compile the transclude against the original scope, not the isolate transclude scope.$parent, (clone)-> contents = clone elem.on "click", => - scope.modalInstance = $modal.open(controller: ctrl, template: contents) + scope.modalInstance = $modal.open(controller: ctrl, template: contents, scope: scope.$parent) # TODO THIS IS TERRIBLE PLEASE FIX NG-BIND-HTML Darkswarm.directive "injectHtml", -> From 576f10dbc39dfee489ab745f7a096e4737da3b9f Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 12:58:23 +1000 Subject: [PATCH 110/139] Adding ng-if checks Conflicts: app/views/modals/_producer.html.haml --- app/views/modals/_producer.html.haml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 6798598f49..51ad2e4852 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -13,24 +13,24 @@ %img.producer-logo{"ng-src" => "{{producer.logo}}"} %h4 Stay in touch with {{ producer.name }} %ul.small-block-grid-1{bindonce: true} - %li{"bo-if" => "producer.website"} - %a{"bo-href" => "{{producer.website}}", target: "_blank" } + %li{"ng-if" => "producer.website"} + %a{"ng-href" => "{{producer.website}}", target: "_blank" } %i.fi-web {{ producer.website }} - %li + %li{"ng-if" => "producer.twitter"} %a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"} %i.fi-social-twitter {{ producer.twitter }} - %li - %a{"bo-href" => "{{producer.facebook}}", target: "_blank"} + %li{"ng-if" => "producer.facebook"} + %a{"ng-href" => "{{producer.facebook}}", target: "_blank"} %i.fi-social-facebook {{ producer.facebook }} - %li - %a{"bo-href" => "{{producer.linkedin}}", target: "_blank"} + %li{"ng-if" => "producer.linkedin"} + %a{"ng-href" => "{{producer.linkedin}}", target: "_blank"} %i.fi-social-linkedin {{ producer.linkedin }} - %li - %a{"bo-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} + %li{"ng-if" => "producer.instagram"} + %a{"ng-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} / Will needs logic to allow user to input @instagramhandle to drive a logical URL %i.fi-social-instagram {{ producer.instagram }} From c26462db5794a5e63485dada840b9172a81a7c9b Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 13:25:45 +1000 Subject: [PATCH 111/139] Addin some URL stripping --- .../darkswarm/filters/strip_url.js.coffee | 6 ++++++ app/views/modals/_producer.html.haml | 7 +++++-- .../darkswarm/filters/strip_url_spec.js.coffee | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/filters/strip_url.js.coffee create mode 100644 spec/javascripts/unit/darkswarm/filters/strip_url_spec.js.coffee diff --git a/app/assets/javascripts/darkswarm/filters/strip_url.js.coffee b/app/assets/javascripts/darkswarm/filters/strip_url.js.coffee new file mode 100644 index 0000000000..dcc86b600a --- /dev/null +++ b/app/assets/javascripts/darkswarm/filters/strip_url.js.coffee @@ -0,0 +1,6 @@ +Darkswarm.filter "stripUrl", -> + stripper = /(https?:\/\/)?(www\.)?(.*)/ + (url) -> + url.match(stripper).pop() + + diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 51ad2e4852..1b976aeece 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -16,22 +16,25 @@ %li{"ng-if" => "producer.website"} %a{"ng-href" => "{{producer.website}}", target: "_blank" } %i.fi-web - {{ producer.website }} + {{ producer.website | stripUrl }} + %li{"ng-if" => "producer.twitter"} %a{"ng-href" => "http://twitter.com/{{producer.twitter}}", target: "_blank"} %i.fi-social-twitter {{ producer.twitter }} + %li{"ng-if" => "producer.facebook"} %a{"ng-href" => "{{producer.facebook}}", target: "_blank"} %i.fi-social-facebook {{ producer.facebook }} + %li{"ng-if" => "producer.linkedin"} %a{"ng-href" => "{{producer.linkedin}}", target: "_blank"} %i.fi-social-linkedin {{ producer.linkedin }} + %li{"ng-if" => "producer.instagram"} %a{"ng-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} - / Will needs logic to allow user to input @instagramhandle to drive a logical URL %i.fi-social-instagram {{ producer.instagram }} diff --git a/spec/javascripts/unit/darkswarm/filters/strip_url_spec.js.coffee b/spec/javascripts/unit/darkswarm/filters/strip_url_spec.js.coffee new file mode 100644 index 0000000000..f34df5cc71 --- /dev/null +++ b/spec/javascripts/unit/darkswarm/filters/strip_url_spec.js.coffee @@ -0,0 +1,16 @@ +describe 'filtering urls', -> + filter = null + + beforeEach -> + module 'Darkswarm' + inject ($filter) -> + filter = $filter('stripUrl') + + it "removes http and www", -> + expect(filter("http://www.footle.com")).toEqual "footle.com" + + it "removes https and www", -> + expect(filter("https://www.footle.com")).toEqual "footle.com" + + it "removes just www", -> + expect(filter("www.footle.com")).toEqual "footle.com" From 0c8ee2488b4cbad84d9765b1d99e40aa8e2e4634 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 14:58:53 +1000 Subject: [PATCH 112/139] Moving back to ng-bind-html --- .../javascripts/darkswarm/directives/modal.js.coffee | 8 -------- app/views/modals/_producer.html.haml | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/darkswarm/directives/modal.js.coffee b/app/assets/javascripts/darkswarm/directives/modal.js.coffee index c1af42b2fc..c8ed5df4af 100644 --- a/app/assets/javascripts/darkswarm/directives/modal.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/modal.js.coffee @@ -15,11 +15,3 @@ Darkswarm.directive "ofnModal", ($modal)-> elem.on "click", => scope.modalInstance = $modal.open(controller: ctrl, template: contents, scope: scope.$parent) - -# TODO THIS IS TERRIBLE PLEASE FIX NG-BIND-HTML -Darkswarm.directive "injectHtml", -> - restrict: 'A' - scope: - injectHtml: "=" - link: (scope, elem, attrs, ctrl)-> - elem.html(scope.injectHtml) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 1b976aeece..35d95bef5e 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -5,7 +5,7 @@ / Will - scale large images down to 1200px wide, crop in to img aspect ratio 60W:13H %h3.producer-name {{ producer.name }} .row - .columns.small-12.large-6{"inject-html" => "producer.long_description"} + .columns.small-12.large-6{"ng-bind-html" => "producer.long_description"} .columns.small-12.large-6 / Will needs logic to add in following only if data is available for each type: / Will needs better formatting of URLs printed on-screen (minus http://www.) @@ -26,12 +26,12 @@ %li{"ng-if" => "producer.facebook"} %a{"ng-href" => "{{producer.facebook}}", target: "_blank"} %i.fi-social-facebook - {{ producer.facebook }} + {{ producer.facebook | stripUrl }} %li{"ng-if" => "producer.linkedin"} %a{"ng-href" => "{{producer.linkedin}}", target: "_blank"} %i.fi-social-linkedin - {{ producer.linkedin }} + {{ producer.linkedin | stripUrl }} %li{"ng-if" => "producer.instagram"} %a{"ng-href" => "http://instagram.com/{{producer.instagram}}", target: "_blank"} From 50c7bd55be9523587992b9b4ae29ee4a7274d3e3 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 15:06:01 +1000 Subject: [PATCH 113/139] Adding url strip and re-construction of http --- app/views/modals/_producer.html.haml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 35d95bef5e..37250176f6 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -7,14 +7,11 @@ .row .columns.small-12.large-6{"ng-bind-html" => "producer.long_description"} .columns.small-12.large-6 - / Will needs logic to add in following only if data is available for each type: - / Will needs better formatting of URLs printed on-screen (minus http://www.) - / Will needs formatting of URLs driving %a regardless of user input (plus http://www.) %img.producer-logo{"ng-src" => "{{producer.logo}}"} %h4 Stay in touch with {{ producer.name }} %ul.small-block-grid-1{bindonce: true} %li{"ng-if" => "producer.website"} - %a{"ng-href" => "{{producer.website}}", target: "_blank" } + %a{"ng-href" => "http://{{producer.website | stripUrl}}", target: "_blank" } %i.fi-web {{ producer.website | stripUrl }} @@ -24,12 +21,12 @@ {{ producer.twitter }} %li{"ng-if" => "producer.facebook"} - %a{"ng-href" => "{{producer.facebook}}", target: "_blank"} + %a{"ng-href" => "http://{{producer.facebook | stripUrl}}", target: "_blank"} %i.fi-social-facebook {{ producer.facebook | stripUrl }} %li{"ng-if" => "producer.linkedin"} - %a{"ng-href" => "{{producer.linkedin}}", target: "_blank"} + %a{"ng-href" => "http://{{producer.linkedin | stripUrl}}", target: "_blank"} %i.fi-social-linkedin {{ producer.linkedin | stripUrl }} From a7105fc3a850efdb68bf8c06815954359540f6bd Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:01:19 +1000 Subject: [PATCH 114/139] Tweaking image sizing on enterprise --- app/models/enterprise.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index a72c6fdbd6..cdb94d74ba 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -18,8 +18,8 @@ class Enterprise < ActiveRecord::Base delegate :latitude, :longitude, :city, :state_name, :to => :address accepts_nested_attributes_for :address - has_attached_file :logo, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png" - has_attached_file :promo_image, :styles => { :large => "570x380>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png" + has_attached_file :logo, :styles => { :medium => "300x300>", :thumb => "100x100>" } + has_attached_file :promo_image, :styles => { :large => "260x1200#", :thumb => "100x100>" } validates_presence_of :name validates_presence_of :address From f65ff5af18d70b2e8bde22cff384c2eebbcb7cb6 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:01:36 +1000 Subject: [PATCH 115/139] Automatically sorting out image rotation --- config/initializers/paperclip.rb | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 config/initializers/paperclip.rb diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb new file mode 100644 index 0000000000..c40b9a4130 --- /dev/null +++ b/config/initializers/paperclip.rb @@ -0,0 +1,3 @@ +Paperclip::Attachment.default_options[:convert_options] = { + all: "-auto-orient" +} From b8cc9d33436a89172d3598ebec713641248b628c Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:02:54 +1000 Subject: [PATCH 116/139] Modding image sizing on groups --- app/models/enterprise_group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/enterprise_group.rb b/app/models/enterprise_group.rb index 6c163b087a..1cea76db72 100644 --- a/app/models/enterprise_group.rb +++ b/app/models/enterprise_group.rb @@ -9,7 +9,7 @@ class EnterpriseGroup < ActiveRecord::Base attr_accessible :name, :description, :long_description, :on_front_page, :enterprise_ids attr_accessible :promo_image - has_attached_file :promo_image, styles: {medium: "800>400"} + has_attached_file :promo_image, styles: {large: "260x1200#"} validates_attachment_content_type :promo_image, :content_type => /\Aimage\/.*\Z/ attr_accessible :logo From 9bb059493e6ae162af7c85ce8bd20957053849ac Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:03:05 +1000 Subject: [PATCH 117/139] Fixing the image render --- app/views/groups/index.html.haml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index fdbf8c5ee6..afa28624f0 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -22,11 +22,10 @@ .row.pad-top{bindonce: true} .small-12.columns .group-hero - %img.group-hero-img{"bo-src" => "{{group.promo_image}}"} + %img.group-hero-img{"bo-src" => "group.promo_image"} %img.group-logo{"bo-src" => "group.logo"} %h3.group-name {{ group.name }} %h5.group-description {{ group.description }} - / Will - scale large images down to 1200px wide, crop in to img aspect ratio 60W:13H .row.pad-top{bindonce: true} .small-6.columns From 33829d90446e141bba33c69bd946208fb3df018d Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:03:21 +1000 Subject: [PATCH 118/139] Only rendering images if they exist --- app/views/json/_groups.rabl | 6 +++++- app/views/shop/products.rabl | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/json/_groups.rabl b/app/views/json/_groups.rabl index 9475b425c4..27325bb850 100644 --- a/app/views/json/_groups.rabl +++ b/app/views/json/_groups.rabl @@ -6,5 +6,9 @@ child enterprises: :enterprises do end node :logo do |group| - group.logo(:original) + group.logo(:medium) if group.logo.exists? +end + +node :promo_image do |group| + group.promo_image(:large) if group.promo_image.exists? end diff --git a/app/views/shop/products.rabl b/app/views/shop/products.rabl index ee5e567285..b1567a311a 100644 --- a/app/views/shop/products.rabl +++ b/app/views/shop/products.rabl @@ -13,10 +13,10 @@ child :supplier => :supplier do attributes :id, :name, :description, :long_description, :website, :instagram, :facebook, :linkedin, :twitter node :logo do |supplier| - supplier.logo.url + supplier.logo(:medium) if supplier.logo.exists? end node :promo_image do |supplier| - supplier.promo_image.url + supplier.promo_image(:large) if supplier.promo_image.exists? end end From fcfda13a73787fb73b7717e9a2de8fd973936d47 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:10:28 +1000 Subject: [PATCH 119/139] Patching a couple of minor regressions --- app/assets/javascripts/darkswarm/all.js.coffee | 2 +- .../controllers/products/product_node_controller.js.coffee | 1 - app/views/modals/_producer.html.haml | 2 +- spec/javascripts/application_spec.js | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index 3a039394ca..2c07d069c4 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -5,8 +5,8 @@ # #= require angular #= require angular-cookies -#= require angular-resource #= require angular-sanitize +#= require angular-resource #= require ../shared/mm-foundation-tpls-0.2.0-SNAPSHOT #= require ../shared/bindonce.min.js #= require ../shared/ng-infinite-scroll.min.js diff --git a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee index fa0daababc..ca29b01449 100644 --- a/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products/product_node_controller.js.coffee @@ -8,7 +8,6 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $sce) -> $scope.product.price $scope.producer = $scope.product.supplier - $scope.producer.twitterific = true $scope.hasVariants = $scope.product.variants.length > 0 Darkswarm.filter "unsafe", ($sce) -> diff --git a/app/views/modals/_producer.html.haml b/app/views/modals/_producer.html.haml index 37250176f6..13f8026195 100644 --- a/app/views/modals/_producer.html.haml +++ b/app/views/modals/_producer.html.haml @@ -7,7 +7,7 @@ .row .columns.small-12.large-6{"ng-bind-html" => "producer.long_description"} .columns.small-12.large-6 - %img.producer-logo{"ng-src" => "{{producer.logo}}"} + %img.producer-logo{"ng-src" => "{{producer.logo}}", "ng-if" => "producer.logo"} %h4 Stay in touch with {{ producer.name }} %ul.small-block-grid-1{bindonce: true} %li{"ng-if" => "producer.website"} diff --git a/spec/javascripts/application_spec.js b/spec/javascripts/application_spec.js index 9e821754de..df629c1c81 100644 --- a/spec/javascripts/application_spec.js +++ b/spec/javascripts/application_spec.js @@ -1,6 +1,7 @@ //= require angular //= require angular-resource //= require angular-animate +//= require angular-sanitize //= require angular-mocks //= require angular-cookies //= require angular-backstretch.js From 98b4fe27f6c11ac0c45b0464fc37fa550f05564e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:12:13 +1000 Subject: [PATCH 120/139] Hiding group logo if not present --- app/views/groups/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index afa28624f0..40b56e2551 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -23,7 +23,7 @@ .small-12.columns .group-hero %img.group-hero-img{"bo-src" => "group.promo_image"} - %img.group-logo{"bo-src" => "group.logo"} + %img.group-logo{"bo-src" => "group.logo", "bo-if" => "group.logo"} %h3.group-name {{ group.name }} %h5.group-description {{ group.description }} From 4b1f409774226ee0d7c57fbd274008833d1dcfd4 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Wed, 28 May 2014 16:19:10 +1000 Subject: [PATCH 121/139] Only rendering images that exist{ --- app/views/modals/_product.html.haml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/modals/_product.html.haml b/app/views/modals/_product.html.haml index 70137ba987..52a7bc7f1f 100644 --- a/app/views/modals/_product.html.haml +++ b/app/views/modals/_product.html.haml @@ -2,13 +2,11 @@ .row .columns.small-12.large-6 - %img.product-img{"ng-src" => "{{product.master.images[0].large_url}}"} + %img.product-img{"ng-src" => "{{product.master.images[0].large_url}}", "ng-if" => "product.master.images[0]"} .columns.small-12.large-6 %h2 %img{"ng-src" => "{{product.primary_taxon.icon}}"} {{product.name}} %p {{product.description}} - / %pre - / {{ product | json }} %a.close-reveal-modal{"ng-click" => "$close()"} × - \ No newline at end of file + From 09ce8697afda30a890323c62a66b8285842c20c0 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 28 May 2014 16:55:04 +1000 Subject: [PATCH 122/139] Only trigger taxon search AJAX when column visible - fixes deadlocks in specs --- app/views/spree/admin/products/bulk_edit.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml index ee74fd9662..fa295adb47 100644 --- a/app/views/spree/admin/products/bulk_edit.html.haml +++ b/app/views/spree/admin/products/bulk_edit.html.haml @@ -132,7 +132,7 @@ %td{ 'ng-show' => 'columns.on_hand.visible' } %span{ 'ng-bind' => 'product.on_hand', :name => 'on_hand', 'ng-show' => '!hasOnDemandVariants(product) && (hasVariants(product) || product.on_demand)' } %input.field{ 'ng-model' => 'product.on_hand', :name => 'on_hand', 'ofn-track-product' => 'on_hand', 'ng-hide' => 'hasVariants(product) || product.on_demand', :type => 'number' } - %td{ 'ng-show' => 'columns.taxons.visible' } + %td{ 'ng-if' => 'columns.taxons.visible' } %input.fullwidth{ :type => 'text', 'ng-model' => 'product.taxon_ids', 'ofn-taxon-autocomplete' => '', 'ofn-track-product' => 'taxon_ids' } %td{ 'ng-show' => 'columns.available_on.visible' } %input{ 'ng-model' => 'product.available_on', :name => 'available_on', 'ofn-track-product' => 'available_on', 'datetimepicker' => 'product.available_on', type: "text" } From 2a630a855acda49a0abd17b1ed29c5ee9006d007 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 29 May 2014 09:28:08 +1000 Subject: [PATCH 123/139] Move primary taxon field into Rob's new product form --- .../add_primary_taxon_field.html.haml.deface | 3 +++ .../new/replace_form.html.haml.deface | 25 ++++++++++++------- .../products/_primary_taxon_form.html.haml | 5 ++++ 3 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 app/overrides/spree/admin/products/_form/add_primary_taxon_field.html.haml.deface create mode 100644 app/views/spree/admin/products/_primary_taxon_form.html.haml diff --git a/app/overrides/spree/admin/products/_form/add_primary_taxon_field.html.haml.deface b/app/overrides/spree/admin/products/_form/add_primary_taxon_field.html.haml.deface new file mode 100644 index 0000000000..efd7ccbfaf --- /dev/null +++ b/app/overrides/spree/admin/products/_form/add_primary_taxon_field.html.haml.deface @@ -0,0 +1,3 @@ +/ insert_top "[data-hook='admin_product_form_right']" + += render 'spree/admin/products/primary_taxon_form', f: f \ No newline at end of file diff --git a/app/overrides/spree/admin/products/new/replace_form.html.haml.deface b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface index c752744ee6..e964e9a704 100644 --- a/app/overrides/spree/admin/products/new/replace_form.html.haml.deface +++ b/app/overrides/spree/admin/products/new/replace_form.html.haml.deface @@ -2,20 +2,25 @@ %fieldset{ id: "new_product" } %legend{align: "center"}= t(:new_product) + .row - = f.field_container :name do - = f.label :name, t(:name) - %span.required * - %br/ - = f.text_field :name, :class => 'fullwidth title' - = f.error_message_on :name - .row - .alpha.six.columns + .alpha.eleven.columns + = f.field_container :name do + = f.label :name, t(:name) + %span.required * + %br/ + = f.text_field :name, :class => 'fullwidth title' + = f.error_message_on :name + .five.columns.omega = f.field_container :supplier do = f.label :supplier %span.required * = f.collection_select(:supplier_id, Enterprise.is_primary_producer.managed_by(spree_current_user).by_name, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) = f.error_message_on :supplier + + .row + .alpha.six.columns + = render 'spree/admin/products/primary_taxon_form', f: f .five.columns = f.field_container :price do = f.label :price, t(:price) @@ -30,6 +35,7 @@ %br/ = f.text_field :on_hand, :class => 'fullwidth' = f.error_message_on :on_hand + .row{ 'ng-controller' => 'unitsCtrl' } .six.columns.alpha = f.label :variant_unit_with_scale, :units @@ -45,6 +51,7 @@ .five.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" } = f.label :product_variant_unit_name, :unit_name %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => 'eg. bunches', :type => 'text' } + #product-from-prototype.clearfix{"data-hook" => "product-from-prototype"} = render :file => 'spree/admin/prototypes/show' if @prototype = render :partial => 'spree/admin/shared/new_resource_links' @@ -53,4 +60,4 @@ :javascript angular.element(document.getElementById("new_product")).ready(function() { angular.bootstrap(document.getElementById("new_product"), ['admin.products']); - }); \ No newline at end of file + }); diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml new file mode 100644 index 0000000000..a844f4f447 --- /dev/null +++ b/app/views/spree/admin/products/_primary_taxon_form.html.haml @@ -0,0 +1,5 @@ += f.field_container :primary_taxon_id do + = f.label :primary_taxon_id + %br + = f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"}) + = f.error_message_on :primary_taxon_id From fdff442ec66e814a2fdae0973a212a099f5d28f5 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 29 May 2014 10:54:08 +1000 Subject: [PATCH 124/139] Do not fetch products JSON on every shopping page --- .../order_cycle_controller.js.coffee | 14 ++++++++------ .../darkswarm/services/order.js.coffee | 2 +- .../darkswarm/services/order_cycle.js.coffee | 6 +++--- .../darkswarm/services/product.js.coffee | 2 +- app/views/shop/show.html.haml | 19 ++++++++++--------- .../shopping_shared/_order_cycles.html.haml | 2 -- 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee index 29e81ae861..555e49c539 100644 --- a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee @@ -1,15 +1,17 @@ -Darkswarm.controller "OrderCycleCtrl", ($scope, $rootScope, OrderCycle, $timeout) -> +Darkswarm.controller "OrderCycleCtrl", ($scope, OrderCycle, $timeout) -> $scope.order_cycle = OrderCycle.order_cycle $scope.OrderCycle = OrderCycle - $scope.changeOrderCycle = -> - OrderCycle.push_order_cycle() - $timeout -> - $("#order_cycle_id").trigger("closeTrigger") - # Timeout forces this to be evaluated after everything is loaded # This is a hack. We should probably write our own "popover" directive # That takes an expression instead of a trigger, and binds to that $timeout => if !$scope.OrderCycle.selected() $("#order_cycle_id").trigger("openTrigger") + + +Darkswarm.controller "OrderCycleChangeCtrl", ($scope, OrderCycle, Product, $timeout) -> + $scope.changeOrderCycle = -> + OrderCycle.push_order_cycle Product.update + $timeout -> + $("#order_cycle_id").trigger("closeTrigger") diff --git a/app/assets/javascripts/darkswarm/services/order.js.coffee b/app/assets/javascripts/darkswarm/services/order.js.coffee index 2357fd42da..8078cf8fc3 100644 --- a/app/assets/javascripts/darkswarm/services/order.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory 'Order', ($resource, Product, order, $http, CheckoutFormState, flash, Navigation)-> +Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, Navigation)-> new class Order errors: {} diff --git a/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee b/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee index 1bb23446a2..0c5176328b 100644 --- a/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee @@ -1,10 +1,10 @@ -Darkswarm.factory 'OrderCycle', ($resource, Product, orderCycleData) -> +Darkswarm.factory 'OrderCycle', ($resource, orderCycleData) -> class OrderCycle @order_cycle = orderCycleData # Object or {} due to RABL - @push_order_cycle: -> + @push_order_cycle: (callback) -> new $resource("/shop/order_cycle").save {order_cycle_id: @order_cycle.order_cycle_id}, (order_data)-> OrderCycle.order_cycle.orders_close_at = order_data.orders_close_at - Product.update() + callback() @orders_close_at: -> @order_cycle.orders_close_at if @selected() diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index e58b83bacc..406e122de1 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -9,7 +9,7 @@ Darkswarm.factory 'Product', ($resource) -> products: null loading: true - update: -> + update: => @data.products = $resource("/shop/products").query => @data.loading = false @data diff --git a/app/views/shop/show.html.haml b/app/views/shop/show.html.haml index b94bd59bf9..d4b36a5e29 100644 --- a/app/views/shop/show.html.haml +++ b/app/views/shop/show.html.haml @@ -1,19 +1,20 @@ %shop.darkswarm - content_for :order_cycle_form do - %strong.avenir Ready for - %select.avenir#order_cycle_id{"ng-model" => "order_cycle.order_cycle_id", - "ng-change" => "changeOrderCycle()", - "ng-options" => "oc.id as oc.time for oc in #{@order_cycles.map {|oc| {time: pickup_time(oc), id: oc.id}}.to_json}", - "popover-placement" => "bottom", "popover" => "When do you want to get your order?", "popover-trigger" => "openTrigger"} + %div{"ng-controller" => "OrderCycleChangeCtrl"} + %strong.avenir Ready for + %select.avenir#order_cycle_id{"ng-model" => "order_cycle.order_cycle_id", + "ng-change" => "changeOrderCycle()", + "ng-options" => "oc.id as oc.time for oc in #{@order_cycles.map {|oc| {time: pickup_time(oc), id: oc.id}}.to_json}", + "popover-placement" => "bottom", "popover" => "When do you want to get your order?", "popover-trigger" => "openTrigger"} - %closing{"ng-if" => "OrderCycle.selected()"} - Orders close - %strong {{ OrderCycle.orders_close_at() | date_in_words }} + %closing{"ng-if" => "OrderCycle.selected()"} + Orders close + %strong {{ OrderCycle.orders_close_at() | date_in_words }} = render partial: "shopping_shared/details" .row = render partial: "shop/products/form" -= render partial: "shared/footer" \ No newline at end of file += render partial: "shared/footer" diff --git a/app/views/shopping_shared/_order_cycles.html.haml b/app/views/shopping_shared/_order_cycles.html.haml index 91517e0c1c..195389df91 100644 --- a/app/views/shopping_shared/_order_cycles.html.haml +++ b/app/views/shopping_shared/_order_cycles.html.haml @@ -14,5 +14,3 @@ - else %form.custom = yield :order_cycle_form - - From b757629bfa80ce3ad7fa38aa2ae92e9b9e5154e7 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 11:52:46 +1000 Subject: [PATCH 125/139] Minor test tweaks --- spec/features/admin/bulk_order_management_spec.rb | 2 +- spec/javascripts/unit/darkswarm/services/order_spec.js.coffee | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 79981bbd16..963cd04f8d 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -206,7 +206,7 @@ feature %q{ page.should have_selector "tr#li_#{li2.id}", visible: true select2_select s1.name, from: "supplier_filter" page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + page.should_not have_selector "tr#li_#{li2.id}" end it "displays all line items when 'All' is selected from supplier filter" do diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index fedcf23629..c5df602b3a 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -77,7 +77,6 @@ describe 'Order service', -> $httpBackend.flush() expect(Order.errors).toEqual {error: "frogs"} - it "Munges the order attributes to add _attributes as Rails needs", -> expect(Order.preprocess().bill_address_attributes).not.toBe(undefined) expect(Order.preprocess().bill_address).toBe(undefined) From 65d11ce552b5312a51649fa0a913c91891a40d01 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 15:41:27 +1000 Subject: [PATCH 126/139] Removing some unnecessary --- app/views/spree/shared/_order_details.html.haml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 559a0227f1..b6ff00925d 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -16,8 +16,6 @@ .columns.large-2 %h6 = t(:shipping_method) - \: - = link_to "(#{t(:edit)})", checkout_state_path(:delivery) unless @order.completed? .delivery = order.shipping_method.name .columns.large-4 From 06bac3de850b279c22fd40b2f4138d9b1cc0878c Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 15:45:56 +1000 Subject: [PATCH 127/139] Fixing an incorrect sentence case --- app/views/producers/_fat.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/producers/_fat.html.haml b/app/views/producers/_fat.html.haml index 45b3bf8dd0..3313db6552 100644 --- a/app/views/producers/_fat.html.haml +++ b/app/views/producers/_fat.html.haml @@ -5,7 +5,7 @@ {{ producer.taxons | printArrayOfObjects }} .columns.small-8 %strong About us - %p.trans-sentence + %p {{ producer.description }} .row.active_table_row.link{"ng-show" => "open()", "ng-repeat" => "hub in producer.distributors"} From e44853346ec7bc997746358766048a2a6f493977 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:12:58 +1000 Subject: [PATCH 128/139] Dropping current producers, switching to suppliers and using Angular --- .../tabs/producers_controller.js.coffee | 2 ++ app/helpers/shared_helper.rb | 10 ------ app/views/json/_current_hub.rabl | 4 +++ app/views/json/_hubs.rabl | 6 +--- app/views/json/_producer.rabl | 5 +++ app/views/shopping_shared/_modals.html.haml | 19 ----------- .../shopping_shared/_producers.html.haml | 8 ++--- spec/helpers/shared_helper_spec.rb | 33 ------------------- 8 files changed, 15 insertions(+), 72 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/tabs/producers_controller.js.coffee create mode 100644 app/views/json/_producer.rabl diff --git a/app/assets/javascripts/darkswarm/controllers/tabs/producers_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/tabs/producers_controller.js.coffee new file mode 100644 index 0000000000..92cf8dedfc --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/tabs/producers_controller.js.coffee @@ -0,0 +1,2 @@ +Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub) -> + $scope.CurrentHub = CurrentHub diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb index 828277cb57..f856a088d1 100644 --- a/app/helpers/shared_helper.rb +++ b/app/helpers/shared_helper.rb @@ -14,16 +14,6 @@ module SharedHelper klass end - # all suppliers of current distributor's products - def current_producers - if current_distributor && current_order_cycle - variants = current_order_cycle.variants_distributed_by(current_distributor) - Enterprise.supplying_variant_in(variants) - else - [] - end - end - def enterprise_user? spree_current_user.andand.enterprises.andand.count.to_i > 0 end diff --git a/app/views/json/_current_hub.rabl b/app/views/json/_current_hub.rabl index ab67cce3cc..57731d9599 100644 --- a/app/views/json/_current_hub.rabl +++ b/app/views/json/_current_hub.rabl @@ -1,2 +1,6 @@ object current_distributor attributes :name, :id + +child suppliers: :producers do + extends "json/producer" +end diff --git a/app/views/json/_hubs.rabl b/app/views/json/_hubs.rabl index dc589b878b..c118b4504f 100644 --- a/app/views/json/_hubs.rabl +++ b/app/views/json/_hubs.rabl @@ -6,11 +6,7 @@ child distributed_taxons: :taxons do end child suppliers: :producers do - attributes :name, :id, :description, :long_description - - node :promo_image do |producer| - producer.promo_image.url - end + extends "json/producer" end node :pickup do |hub| diff --git a/app/views/json/_producer.rabl b/app/views/json/_producer.rabl new file mode 100644 index 0000000000..4c0efae8e1 --- /dev/null +++ b/app/views/json/_producer.rabl @@ -0,0 +1,5 @@ +attributes :name, :id, :description, :long_description + +node :promo_image do |producer| + producer.promo_image.url +end diff --git a/app/views/shopping_shared/_modals.html.haml b/app/views/shopping_shared/_modals.html.haml index ad92f1957f..83a162a470 100644 --- a/app/views/shopping_shared/_modals.html.haml +++ b/app/views/shopping_shared/_modals.html.haml @@ -1,22 +1,3 @@ -- for producer in current_producers - .reveal-modal{id: "producer_details_#{producer.id}", "data-reveal" => ""} - .row - - if producer.logo.exists? - .large-1.columns - %img.left{src: producer.logo.url(:thumb)} - .large-11.columns - %h2 - = producer.name - .row - .large-8.columns - = producer.long_description.andand.html_safe - - - if producer.promo_image.exists? - .large-4.columns - %img.about.right{src: producer.promo_image.url(:large)} - %a.close-reveal-modal × - - - for group in current_distributor.groups - for sibling in group.enterprises.except(current_distributor) .reveal-modal{id: "sibling_details_#{sibling.id}", "data-reveal" => ""} diff --git a/app/views/shopping_shared/_producers.html.haml b/app/views/shopping_shared/_producers.html.haml index 32f09869e8..584d75ff35 100644 --- a/app/views/shopping_shared/_producers.html.haml +++ b/app/views/shopping_shared/_producers.html.haml @@ -1,6 +1,4 @@ -.content#producers +.content#producers{"ng-controller" => "ProducersTabCtrl"} %ul - - for producer in current_producers - %li - %a{"data-reveal-id" => "producer_details_#{producer.id}", "data-reveal" => ""} - = producer.name + %li{"ng-repeat" => "producer in CurrentHub.producers"} + = render partial: "modals/producer" diff --git a/spec/helpers/shared_helper_spec.rb b/spec/helpers/shared_helper_spec.rb index d28a6eb7b3..92c688d1ae 100644 --- a/spec/helpers/shared_helper_spec.rb +++ b/spec/helpers/shared_helper_spec.rb @@ -23,37 +23,4 @@ describe SharedHelper do helper.stub(:current_order) { order } helper.distributor_link_class(d1).should =~ /empties-cart/ end - - describe "finding current producers" do - it "finds producers for the current distribution" do - s = create(:supplier_enterprise) - d = create(:distributor_enterprise) - p = create(:simple_product) - oc = create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.master]) - - helper.stub(:current_order_cycle) { oc } - helper.stub(:current_distributor) { d } - - helper.current_producers.should == [s] - end - - it "returns [] when no order cycle set" do - d = double(:distributor) - - helper.stub(:current_order_cycle) { nil } - helper.stub(:current_distributor) { d } - - helper.current_producers.should == [] - end - - it "returns [] when no distributor set" do - oc = double(:order_cycle) - - helper.stub(:current_order_cycle) { oc } - helper.stub(:current_distributor) { nil } - - helper.current_producers.should == [] - - end - end end From f28fe34958314dc8f25e386ea5c19f648fc2c5d7 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:15:39 +1000 Subject: [PATCH 129/139] Removing groups modals --- app/views/shopping_shared/_groups.html.haml | 8 ++------ app/views/shopping_shared/_modals.html.haml | 17 ----------------- 2 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 app/views/shopping_shared/_modals.html.haml diff --git a/app/views/shopping_shared/_groups.html.haml b/app/views/shopping_shared/_groups.html.haml index a218d6aeb5..815cf4ec67 100644 --- a/app/views/shopping_shared/_groups.html.haml +++ b/app/views/shopping_shared/_groups.html.haml @@ -2,9 +2,5 @@ %ul - for group in current_distributor.groups %li - %h4= group.name - %ul - - for sibling in group.enterprises.except(current_distributor) - %li - %a{"data-reveal-id" => "sibling_details_#{sibling.id}", "data-reveal" => ""} - = sibling.name + %h4 + %a= group.name diff --git a/app/views/shopping_shared/_modals.html.haml b/app/views/shopping_shared/_modals.html.haml deleted file mode 100644 index 83a162a470..0000000000 --- a/app/views/shopping_shared/_modals.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- for group in current_distributor.groups - - for sibling in group.enterprises.except(current_distributor) - .reveal-modal{id: "sibling_details_#{sibling.id}", "data-reveal" => ""} - .row - - if sibling.logo.exists? - .large-1.columns - %img.left{src: sibling.logo.url(:thumb)} - .large-11.columns - %h2 - = sibling.name - .row - .large-8.columns - = sibling.long_description.andand.html_safe - - if sibling.promo_image.exists? - .large-4.columns - %img.about.right{src: sibling.promo_image.url(:large)} - %a.close-reveal-modal × From c49d9d838cfad679b7ce06a942246b02c71e0665 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:19:20 +1000 Subject: [PATCH 130/139] Removing reference to modals and unnecessary ID --- app/views/shopping_shared/_details.html.haml | 2 -- app/views/shopping_shared/_groups.html.haml | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/views/shopping_shared/_details.html.haml b/app/views/shopping_shared/_details.html.haml index 37edfa3c16..e152be43c0 100644 --- a/app/views/shopping_shared/_details.html.haml +++ b/app/views/shopping_shared/_details.html.haml @@ -1,5 +1,3 @@ -= render partial: "shopping_shared/modals" - %navigation %distributor.details.row #distributor_title diff --git a/app/views/shopping_shared/_groups.html.haml b/app/views/shopping_shared/_groups.html.haml index 815cf4ec67..cc7e4ff369 100644 --- a/app/views/shopping_shared/_groups.html.haml +++ b/app/views/shopping_shared/_groups.html.haml @@ -1,6 +1,5 @@ -.content#groups +.content %ul - for group in current_distributor.groups %li - %h4 - %a= group.name + %a{href: main_app.groups_path}= group.name From d5a652182e72bf6b3abd196a7e3ed69f21a86028 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:31:12 +1000 Subject: [PATCH 131/139] Scrolling to groups when hotlinked --- .../darkswarm/controllers/groups_controller.js.coffee | 5 ++++- app/views/groups/index.html.haml | 5 +++-- app/views/shopping_shared/_groups.html.haml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee index 8fd47c49f8..850f58b33e 100644 --- a/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/groups_controller.js.coffee @@ -1,3 +1,6 @@ -Darkswarm.controller "GroupsCtrl", ($scope, Groups) -> +Darkswarm.controller "GroupsCtrl", ($scope, Groups, $anchorScroll, $rootScope) -> $scope.Groups = Groups $scope.order = 'position' + + $rootScope.$on "$locationChangeSuccess", (newRoute, oldRoute) -> + $anchorScroll() diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml index 40b56e2551..c1fd5ccf8e 100644 --- a/app/views/groups/index.html.haml +++ b/app/views/groups/index.html.haml @@ -17,8 +17,9 @@ "ng-debounce" => "150", "ofn-disable-enter" => true} - .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order"} - + .group{"ng-repeat" => "group in Groups.groups | filter:query | orderBy:order", + name: "group{{group.id}}", + id: "group{{group.id}}"} .row.pad-top{bindonce: true} .small-12.columns .group-hero diff --git a/app/views/shopping_shared/_groups.html.haml b/app/views/shopping_shared/_groups.html.haml index cc7e4ff369..e9ebb219b3 100644 --- a/app/views/shopping_shared/_groups.html.haml +++ b/app/views/shopping_shared/_groups.html.haml @@ -2,4 +2,4 @@ %ul - for group in current_distributor.groups %li - %a{href: main_app.groups_path}= group.name + %a{href: main_app.groups_path(anchor: "#/#group#{group.id}")}= group.name From aaf9b765077b7ef20e27eaafe081cdc8d2ae85bd Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:38:01 +1000 Subject: [PATCH 132/139] Making toggling of fat nodes work --- .../darkswarm/controllers/producer_node_controller.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee index 2f3bf1ce00..d46106a830 100644 --- a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee @@ -1,6 +1,6 @@ Darkswarm.controller "ProducerNodeCtrl", ($scope, HashNavigation, $anchorScroll) -> $scope.toggle = -> - HashNavigation.navigate $scope.producer.hash + HashNavigation.toggle $scope.producer.hash $scope.open = -> HashNavigation.active($scope.producer.hash) From e26a61c31fb3ec1966f7835cf47674bb4b9fa8d0 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:49:20 +1000 Subject: [PATCH 133/139] Adding back sanitize --- app/assets/javascripts/darkswarm/darkswarm.js.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index fe128b963a..8d26384c14 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -5,6 +5,7 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource", 'infinite-scroll', 'angular-flash.service', 'templates', + 'ngSanitize', 'backstretch']).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) -> $httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') $httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content') From 3ae2dc34e88f86ed0628cf52bb8a2b6c8d1affa2 Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Thu, 29 May 2014 16:50:41 +1000 Subject: [PATCH 134/139] Preventing rabl from dying if no current hub --- app/views/json/_current_hub.rabl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/json/_current_hub.rabl b/app/views/json/_current_hub.rabl index 57731d9599..7f615bb07a 100644 --- a/app/views/json/_current_hub.rabl +++ b/app/views/json/_current_hub.rabl @@ -1,6 +1,8 @@ object current_distributor attributes :name, :id -child suppliers: :producers do - extends "json/producer" +if current_distributor + child suppliers: :producers do + extends "json/producer" + end end From 7d73f7d7f2371d1623d1215c95cd0108f0a1b221 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 29 May 2014 16:00:39 +1000 Subject: [PATCH 135/139] Fix reversed checkbox value for select all variants on order cycle admin page --- .../order_cycles/_exchange_distributed_products_form.html.haml | 2 +- .../order_cycles/_exchange_supplied_products_form.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/order_cycles/_exchange_distributed_products_form.html.haml b/app/views/admin/order_cycles/_exchange_distributed_products_form.html.haml index 3f7d7ba578..ae0b9b7349 100644 --- a/app/views/admin/order_cycles/_exchange_distributed_products_form.html.haml +++ b/app/views/admin/order_cycles/_exchange_distributed_products_form.html.haml @@ -1,7 +1,7 @@ %td{:colspan => 3} .exchange-select-all-variants %label - = check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-click' => 'setExchangeVariants(exchange, incomingExchangesVariants(), exchange.select_all_variants)', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants' + = check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-change' => 'setExchangeVariants(exchange, incomingExchangesVariants(), exchange.select_all_variants)', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants' Select all .exchange-product{'ng-repeat' => 'product in supplied_products | filter:productSuppliedToOrderCycle'} diff --git a/app/views/admin/order_cycles/_exchange_supplied_products_form.html.haml b/app/views/admin/order_cycles/_exchange_supplied_products_form.html.haml index 6ad13a88a6..ac791d7fd2 100644 --- a/app/views/admin/order_cycles/_exchange_supplied_products_form.html.haml +++ b/app/views/admin/order_cycles/_exchange_supplied_products_form.html.haml @@ -2,7 +2,7 @@ %td{:colspan => 3} .exchange-select-all-variants %label - = check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-click' => 'setExchangeVariants(exchange, suppliedVariants(exchange.enterprise_id), exchange.select_all_variants)', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants' + = check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-change' => 'setExchangeVariants(exchange, suppliedVariants(exchange.enterprise_id), exchange.select_all_variants)', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants' Select all .exchange-product{'ng-repeat' => 'product in enterprises[exchange.enterprise_id].supplied_products'} From 4c6a7622eb6d35458198de27ff5fd76e2227bb35 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 29 May 2014 17:18:27 +1000 Subject: [PATCH 136/139] Convert rep template to rabl --- app/views/admin/enterprises/index.rabl | 14 ++++++++++++++ app/views/admin/enterprises/index.rep | 15 --------------- 2 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 app/views/admin/enterprises/index.rabl delete mode 100644 app/views/admin/enterprises/index.rep diff --git a/app/views/admin/enterprises/index.rabl b/app/views/admin/enterprises/index.rabl new file mode 100644 index 0000000000..9e1ee893d1 --- /dev/null +++ b/app/views/admin/enterprises/index.rabl @@ -0,0 +1,14 @@ +collection @collection + +attributes :id, :name + +child supplied_products: :supplied_products do |product| + attributes :name + node(:supplier_name) { |p| p.supplier.andand.name } + node(:image_url) { |p| p.images.present? ? p.images.first.attachment.url(:mini) : nil } + node(:master_id) { |p| p.master.id } + child variants: :variants do |variant| + attributes :id + node(:label) { |v| v.options_text } + end +end diff --git a/app/views/admin/enterprises/index.rep b/app/views/admin/enterprises/index.rep deleted file mode 100644 index beaceef8a4..0000000000 --- a/app/views/admin/enterprises/index.rep +++ /dev/null @@ -1,15 +0,0 @@ -r.list_of :enterprises, @collection do - r.element :id - r.element :name - - r.list_of :supplied_products do |product| - r.element :name - r.element :supplier_name, product.supplier.andand.name - r.element :image_url, product.images.present? ? product.images.first.attachment.url(:mini) : nil - r.element :master_id, product.master.id - r.list_of :variants do |variant| - r.element :id - r.element :label, variant.options_text - end - end -end From 5b58bf2c71ee39c18aedf215c24d761f058e002e Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 30 May 2014 10:43:16 +1000 Subject: [PATCH 137/139] Adding our own custom unauthorized page --- .../spree/store_controller_decorator.rb | 7 +++++++ app/views/shared/unauthorized.html.haml | 1 + spec/controllers/spree/store_controller_spec.rb | 14 ++++++++++++++ .../darkswarm/services/order_cycle_spec.js.coffee | 4 ++-- .../unit/darkswarm/services/order_spec.js.coffee | 1 - 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 app/controllers/spree/store_controller_decorator.rb create mode 100644 app/views/shared/unauthorized.html.haml create mode 100644 spec/controllers/spree/store_controller_spec.rb diff --git a/app/controllers/spree/store_controller_decorator.rb b/app/controllers/spree/store_controller_decorator.rb new file mode 100644 index 0000000000..09c2efc7b4 --- /dev/null +++ b/app/controllers/spree/store_controller_decorator.rb @@ -0,0 +1,7 @@ +class Spree::StoreController + layout 'darkswarm' + + def unauthorized + render 'shared/unauthorized', :status => 401 + end +end diff --git a/app/views/shared/unauthorized.html.haml b/app/views/shared/unauthorized.html.haml new file mode 100644 index 0000000000..fcf3f3bf27 --- /dev/null +++ b/app/views/shared/unauthorized.html.haml @@ -0,0 +1 @@ +Unauthorized diff --git a/spec/controllers/spree/store_controller_spec.rb b/spec/controllers/spree/store_controller_spec.rb new file mode 100644 index 0000000000..e1b94de185 --- /dev/null +++ b/spec/controllers/spree/store_controller_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Spree::StoreController do + controller(Spree::StoreController) do + before_filter :unauthorized + def index + render text: "" + end + end + it "redirects to home when unauthorized" do + get :index + response.should render_template("shared/unauthorized", layout: 'darkswarm') + end +end diff --git a/spec/javascripts/unit/darkswarm/services/order_cycle_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_cycle_spec.js.coffee index f7a65867e8..93dd7de79c 100644 --- a/spec/javascripts/unit/darkswarm/services/order_cycle_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_cycle_spec.js.coffee @@ -21,14 +21,14 @@ describe 'OrderCycle service', -> $httpBackend.expectPOST("/shop/order_cycle", {"order_cycle_id" : 10}).respond(200) spyOn(mockProduct, "update") OrderCycle.order_cycle.order_cycle_id = 10 - OrderCycle.push_order_cycle() + OrderCycle.push_order_cycle mockProduct.update $httpBackend.flush() expect(mockProduct.update).toHaveBeenCalled() it "updates the orders_close_at attr after update", -> datestring = "2013-12-20T00:00:00+11:00" $httpBackend.expectPOST("/shop/order_cycle").respond({orders_close_at: datestring}) - OrderCycle.push_order_cycle() + OrderCycle.push_order_cycle mockProduct.update $httpBackend.flush() expect(OrderCycle.order_cycle.orders_close_at).toEqual(datestring) diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index c5df602b3a..4f6c711f99 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -29,7 +29,6 @@ describe 'Order service', -> inject ($injector, _$httpBackend_)-> $httpBackend = _$httpBackend_ - $httpBackend.expectGET("/shop/products").respond 200, [] Order = $injector.get("Order") Navigation = $injector.get("Navigation") flash = $injector.get("flash") From dd0907addda37ad94f1a62dd06b68a8fd4d8f30b Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Fri, 30 May 2014 11:24:16 +1000 Subject: [PATCH 138/139] Adding back the primary taxon migration --- db/migrate/20140522044009_add_primary_taxon_to_products.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb new file mode 100644 index 0000000000..f6ff3cfe96 --- /dev/null +++ b/db/migrate/20140522044009_add_primary_taxon_to_products.rb @@ -0,0 +1,7 @@ +class AddPrimaryTaxonToProducts < ActiveRecord::Migration + def change + add_column :spree_products, :primary_taxon_id, :integer + add_index :spree_products, :primary_taxon_id + add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id + end +end From c9acb14809cec966c86db98c1a1f2c3bc2eb6507 Mon Sep 17 00:00:00 2001 From: Rob H Date: Fri, 30 May 2014 11:30:00 +1000 Subject: [PATCH 139/139] Adding primary taxon migration to schema --- db/schema.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 77df8baf75..6005fd7cb5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140522015012) do +ActiveRecord::Schema.define(:version => 20140522044009) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -681,6 +681,7 @@ ActiveRecord::Schema.define(:version => 20140522015012) do t.float "variant_unit_scale" t.string "variant_unit_name" t.text "notes" + t.integer "primary_taxon_id" end add_index "spree_products", ["available_on"], :name => "index_products_on_available_on" @@ -688,6 +689,7 @@ ActiveRecord::Schema.define(:version => 20140522015012) do add_index "spree_products", ["name"], :name => "index_products_on_name" add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true + add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" @@ -1092,6 +1094,7 @@ ActiveRecord::Schema.define(:version => 20140522015012) do add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" + add_foreign_key "spree_products", "spree_taxons", name: "spree_products_primary_taxon_id_fk", column: "primary_taxon_id" add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id"