rightnow_oms 0.0.4 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. data/CHANGELOG +21 -0
  2. data/README.md +163 -0
  3. data/Rakefile +4 -14
  4. data/app/assets/images/rightnow_oms/cart.png +0 -0
  5. data/app/assets/javascripts/rightnow_oms/app/app.js.coffee +1 -1
  6. data/app/assets/javascripts/rightnow_oms/app/controllers/cart.js.coffee +14 -5
  7. data/app/assets/javascripts/rightnow_oms/app/models/cart.js.coffee +1 -2
  8. data/app/assets/javascripts/rightnow_oms/app/models/cart_item.js.coffee +15 -2
  9. data/app/assets/javascripts/rightnow_oms/app/templates/cart_items/show.hjs +3 -3
  10. data/app/assets/javascripts/rightnow_oms/app/templates/cart_items/show_in_detail.hjs +11 -7
  11. data/app/assets/javascripts/rightnow_oms/app/templates/carts/show.hjs +7 -7
  12. data/app/assets/javascripts/rightnow_oms/app/templates/carts/show_cartable_count.hjs +1 -0
  13. data/app/assets/javascripts/rightnow_oms/app/templates/carts/show_in_detail.hjs +29 -20
  14. data/app/assets/javascripts/rightnow_oms/app/views/cart_items/show.js.coffee +1 -1
  15. data/app/assets/javascripts/rightnow_oms/app/views/carts/show.js.coffee +4 -0
  16. data/app/assets/javascripts/rightnow_oms/app/views/carts/show_cartable_count.js.coffee +6 -0
  17. data/app/assets/javascripts/rightnow_oms/app/views/carts/show_in_detail.js.coffee +0 -1
  18. data/app/assets/stylesheets/rightnow_oms/carts.css.scss +136 -13
  19. data/app/controllers/rightnow_oms/application_controller.rb +0 -13
  20. data/app/controllers/rightnow_oms/cart_items_controller.rb +4 -3
  21. data/app/controllers/rightnow_oms/carts_controller.rb +4 -3
  22. data/app/models/rightnow_oms/cart.rb +7 -3
  23. data/app/models/rightnow_oms/cart_item.rb +5 -0
  24. data/app/views/rightnow_oms/carts/show.html.haml +1 -1
  25. data/lib/rightnow_oms.rb +5 -2
  26. data/lib/rightnow_oms/acts_as_cartable.rb +36 -0
  27. data/lib/rightnow_oms/cartable_validator.rb +5 -0
  28. data/lib/rightnow_oms/controller_helpers.rb +28 -0
  29. data/lib/rightnow_oms/version.rb +1 -1
  30. metadata +27 -34
  31. data/README.rdoc +0 -84
  32. data/app/assets/stylesheets/rightnow_oms/cart_items.css +0 -12
  33. data/app/helpers/rightnow_oms/application_helper.rb +0 -4
  34. data/app/helpers/rightnow_oms/cart_items_helper.rb +0 -4
  35. data/app/helpers/rightnow_oms/carts_helper.rb +0 -4
data/CHANGELOG ADDED
@@ -0,0 +1,21 @@
1
+ *Rightnow OMS 0.1.1 (Mon 18:35, Feb 13, 2012)*
2
+
3
+ * Validate that cart items are cartable
4
+ * Migrate the database to PostgreSQL
5
+
6
+ *Rightnow OMS 0.1.0 (Mon 11:31, Feb 13, 2012)*
7
+
8
+ * Provide a helper method to load the cart in controllers
9
+ * Return the cartable_id and cartable_type of cart items
10
+ * Distinguish cart items by cartable and parent_id
11
+ * Create an acts_as_cartable method to provide the features of a cartable model.
12
+
13
+ *Rightnow OMS 0.0.4 (Thu 14:29, Feb 9, 2012)*
14
+
15
+ * Factory not registered error fixed
16
+
17
+ *Rightnow OMS 0.0.3 (Thu 11:16, Feb 9, 2012)*
18
+
19
+ * Can't add items with children bug fixed
20
+ * Reorder the architecture
21
+ * Add more tips in README
data/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # RightnowOms
2
+
3
+ ## Description
4
+
5
+ A common gem for managing your carts and orders. RightnowOms is a rails mountable engine. It gets a lot of benifits from [Ember.JS](http://emberjs.com)
6
+
7
+ ## Requirements
8
+
9
+ Add the following gems to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'jquery-rails'
13
+ gem 'ember-rails'
14
+ gem 'acts_as_api'
15
+ gem 'haml-rails'
16
+
17
+ group :assets do
18
+ gem 'uglifier'
19
+ gem 'coffee-rails'
20
+ gem 'sass-rails'
21
+ end
22
+ ```
23
+
24
+ ## Installation
25
+
26
+ Make sure that all requirements are met and add RightnowOms to your Gemfile.
27
+
28
+ ```ruby
29
+ gem 'rightnow_oms'
30
+ ```
31
+
32
+ and run `bundle install`
33
+
34
+ ## Usage
35
+
36
+ Mount RightnowOms to your application.
37
+
38
+ ```ruby
39
+ # config/routes.rb
40
+ mount RightnowOms::Engine => "rightnow_oms"
41
+ ```
42
+
43
+ Create the migrations with:
44
+
45
+ ```bash
46
+ rake rightnow_oms:install:migrations
47
+ rake db:migrate
48
+ ```
49
+
50
+ Run `bundle install` and require ember and ember-data in your `app/assets/javascripts/application.js`:
51
+
52
+ ```
53
+ = require rightnow_oms/vendor/ember
54
+ = require rightnow_oms/vendor/ember-data
55
+ ```
56
+
57
+ Add the following line to your `app/assets/javascripts/application.js`:
58
+
59
+ ```
60
+ = require rightnow_oms/application
61
+ ```
62
+
63
+ Add the stylesheets to your `app/assets/stylesheets/application.css`:
64
+
65
+ ```
66
+ = require rightnow_oms/application
67
+ ```
68
+
69
+ Create a layout for your detailed cart view like:
70
+
71
+ ```haml
72
+ # app/views/layouts/rightnow_oms/cart.html.haml
73
+ !!!
74
+ %html
75
+ %head
76
+ %title RightnowOms
77
+ = stylesheet_link_tag "application"
78
+ = javascript_include_tag "application"
79
+ = csrf_meta_tags
80
+
81
+ %body
82
+ = yield
83
+ ```
84
+
85
+ Add before filters to your controllers which need to use the cart:
86
+
87
+ ```ruby
88
+ # This before filter will create an instance variable @cart
89
+ before_filter :load_or_create_cart
90
+ ```
91
+
92
+ Create cartable models in your application:
93
+
94
+ ```ruby
95
+ class Product < ActiveRecord::Base
96
+ acts_as_cartable
97
+ end
98
+ ```
99
+
100
+ By default, Cart loads the name and price of cartable models by
101
+ attributes named name and price. You can customize these attributes:
102
+
103
+ ```ruby
104
+ acts_as_cartable { name: :your_name_attr, price: :your_price_attr }
105
+ ```
106
+
107
+ Add a place holder for your cart in your views:
108
+
109
+ ```html
110
+ <div id="rightnow-oms">
111
+ <script type="text/x-handlebars">
112
+ {{ view RightnowOms.ShowCartView }}
113
+ </script>
114
+ </div>
115
+ ```
116
+
117
+ and load your cart in the view:
118
+
119
+ ```javascript
120
+ $(function() {
121
+ RightnowOms.cartController.load(#{@cart.as_api_response(:default).to_json.html_safe});
122
+ });
123
+ ```
124
+
125
+ You can add cartables to the cart by:
126
+
127
+ ```javascript
128
+ RightnowOms.cartController.addCartItem({
129
+ cartable_id: 1,
130
+ cartable_type: 'Product'
131
+
132
+ // if the item is a child, you need to set the parent id.
133
+ // parent_id: 2
134
+ })
135
+ ```
136
+
137
+ Now you have all things done. Wish you have a good day.
138
+
139
+ ## Development
140
+
141
+ RightnowOms is developed with Ruby 1.9.3-p0 and Rails 3.1.3
142
+
143
+ First of all, you need to create a database config for RightnowOms.
144
+ There are already some useful templates for you under
145
+ `spec/dummy/config/`. RightnowOms use PostgreSQL by default. If you want
146
+ to setup other databases, for example mysql, you need to modify the
147
+ Gemfile by yourself.
148
+
149
+ ```bash
150
+ bundle install
151
+ bundle exec rake app:db:migrate
152
+ bundle exec rake app:db:seed
153
+
154
+ # Run the tests. Please make sure you have firefox installed
155
+ bundle exec rake app:db:test:prepare
156
+ rspec
157
+
158
+ # Start the dummy application
159
+ rails s
160
+ ```
161
+
162
+ ## Copyright
163
+ Copyright 2011-2012 Beijing Menglifang Network Technology and Science Co.,Ltd. All rights reserved.
data/Rakefile CHANGED
@@ -4,23 +4,13 @@ begin
4
4
  rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
- begin
8
- require 'rdoc/task'
9
- rescue LoadError
10
- require 'rdoc/rdoc'
11
- require 'rake/rdoctask'
12
- RDoc::Task = Rake::RDocTask
13
- end
14
7
 
15
- RDoc::Task.new(:rdoc) do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'RightnowOms'
18
- rdoc.options << '--line-numbers'
19
- rdoc.rdoc_files.include('README.rdoc')
20
- rdoc.rdoc_files.include('lib/**/*.rb')
21
- rdoc.rdoc_files.include('app/**/*.rb')
8
+ require 'yard'
9
+ YARD::Rake::YardocTask.new do |t|
10
+ t.options = ['--markup', 'markdown'] # optional
22
11
  end
23
12
 
13
+
24
14
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
25
15
  load 'rails/tasks/engine.rake'
26
16
 
@@ -1,5 +1,5 @@
1
1
  window.RightnowOms = Ember.Application.create
2
- rootElement: '#cart-wrapper'
2
+ rootElement: '#rightnow-oms'
3
3
 
4
4
  window.RightnowOms.store = DS.Store.create
5
5
  adapter:
@@ -20,9 +20,18 @@ RightnowOms.cartController = Ember.Object.create
20
20
  @store.commit()
21
21
 
22
22
  decreaseCartItem: (id) ->
23
- @get('content').decreaseCartItem(id)
24
- @store.commit()
23
+ cartItem = RightnowOms.CartItem.findById(id)
25
24
 
26
- removeCartItem: (id) ->
27
- @get('content').removeCartItem(id)
28
- @store.commit()
25
+ if cartItem.get('isDecreasable')
26
+ @get('content').decreaseCartItem(id)
27
+ @store.commit()
28
+ else
29
+ @removeCartItem(id)
30
+
31
+ removeCartItem: (id, silent) ->
32
+ remove = true
33
+ remove = confirm('您确定要删除该商品吗?') unless silent
34
+
35
+ if remove
36
+ @get('content').removeCartItem(id)
37
+ @store.commit()
@@ -20,7 +20,7 @@ RightnowOms.Cart = DS.Model.extend
20
20
  ).property("cartableCount")
21
21
 
22
22
  addCartItem: (item) ->
23
- cartItem = RightnowOms.CartItem.findByName(item.name)
23
+ cartItem = RightnowOms.CartItem.findByCartableAndParentId(item.cartable_id, item.cartable_type, item.parent_id)
24
24
 
25
25
  if cartItem?
26
26
  cartItem.increase() unless cartItem.get('parent')?
@@ -46,7 +46,6 @@ RightnowOms.Cart = DS.Model.extend
46
46
  cartItem = RightnowOms.CartItem.findById(id)
47
47
 
48
48
  cartItem.decrease()
49
- #removeCartItem(id) if cartItem.get('quantity') <= 0
50
49
  cartItem
51
50
 
52
51
  RightnowOms.Cart.reopenClass
@@ -28,6 +28,10 @@ RightnowOms.CartItem = DS.Model.extend
28
28
  @get('parent_id')?
29
29
  ).property('parent_id')
30
30
 
31
+ isDecreasable: (->
32
+ @get('quantity') > 1
33
+ ).property('quantity')
34
+
31
35
  increase: ->
32
36
  @get('children').forEach((child) ->
33
37
  child.increase()
@@ -53,8 +57,17 @@ RightnowOms.CartItem.reopenClass
53
57
  all: ->
54
58
  RightnowOms.store.findAll(RightnowOms.CartItem)
55
59
 
60
+ findById: (id) ->
61
+ @all().filterProperty('id', id).get('firstObject')
62
+
56
63
  findByName: (name) ->
57
64
  @all().filterProperty('name', name).get('firstObject')
58
65
 
59
- findById: (id) ->
60
- @all().filterProperty('id', id).get('firstObject')
66
+ findByCartableAndParentId: (cartableId, cartableType, parentId) ->
67
+ @all().filter((item) ->
68
+ if item.get('cartable_id') == cartableId && item.get('cartable_type') == cartableType
69
+ if parentId?
70
+ return true if item.get('parent_id') == parentId
71
+ else
72
+ return true
73
+ ).get('firstObject')
@@ -1,7 +1,7 @@
1
1
  {{#with cartItem }}
2
- <td>{{ name }}</td>
3
- <td class='price'>{{ price }}x{{ quantity }}</td>
4
- <td>
2
+ <td class="name">{{ name }}</td>
3
+ <td class="price r-money">¥{{ price }}x{{ quantity }}</td>
4
+ <td class="delete">
5
5
  {{#unless hasParent }}
6
6
  <a href="#" {{ action "deleteRecord" }}>删除</a>
7
7
  {{/unless}}
@@ -1,15 +1,19 @@
1
1
  {{#with cartItem}}
2
- <td>{{ name }}</td>
2
+ <td class="name">{{ name }}</td>
3
3
  <td class="price">¥{{ price }}</td>
4
4
  <td class="quantity">
5
5
  {{#if hasParent }}
6
- {{ quantity }}
6
+ <span class="quantity-only">{{ quantity }}</span>
7
7
  {{else}}
8
- <a href="#" {{ action "decrease" }}>-</a>
9
- <span> {{ quantity }} </span>
10
- <a href="#" {{ action "increase" }}>+</a>
8
+ <span class="decrease"><a href="#" {{ action "decrease" }}>-</a></span>
9
+ <span class="quantity"> {{ quantity }} </span>
10
+ <span class="increase"><a href="#" {{ action "increase" }}>+</a></span>
11
11
  {{/if}}
12
12
  </td>
13
- <td class="subtotal">¥{{ subtotal }}</td>
14
- <td><a href="#" {{ action "deleteRecord" }}>删除</a></td>
13
+ <td class="subtotal r-money">¥{{ subtotal }}</td>
14
+ <td class="delete">
15
+ {{#unless hasParent }}
16
+ <a href="#" {{ action "deleteRecord" }}>删除</a>
17
+ {{/unless}}
18
+ </td>
15
19
  {{/with}}
@@ -1,14 +1,14 @@
1
- <div class="cart-bar">
2
- <span>购物车 {{ cart.cartableCount }} 件</span>
3
- <span><a href='/rightnow_oms/cart'>去结算 >></a></span>
1
+ <div class="r-cart-bar">
2
+ {{ view RightnowOms.ShowCartableCountView cartableCountBinding="cart.cartableCount" }}
4
3
  </div>
5
-
6
- <div class="cart-items">
4
+ <div class="r-cart-items">
7
5
  <table>
8
6
  {{#each cart.cartItems}}
9
7
  {{ view RightnowOms.ShowCartItemView cartItemBinding="this" }}
10
8
  {{/each}}
11
- <tr><td colspan="3">总计:¥{{ cart.total }}</td></tr>
12
9
  </table>
10
+ <div class="r-bottom-bar">
11
+ <span>总计:<span class="r-money">¥{{ cart.total }}</span></span>
12
+ <span><a href="/rightnow_oms/cart">查看我的购物车</a></span>
13
+ </div>
13
14
  </div>
14
-
@@ -0,0 +1 @@
1
+ <a href="/rightnow_oms/cart">购物车 {{ cartableCount }} 件</a>
@@ -1,21 +1,30 @@
1
1
  <h2>我的购物车</h2>
2
- <table>
3
- <tr>
4
- <td>商品名称</td>
5
- <td>商品价格</td>
6
- <td>商品数量</td>
7
- <td>商品总价</td>
8
- <td>删除商品</td>
9
- </tr>
10
- </tr>
11
- {{#each cart.cartItems}}
12
- {{ view RightnowOms.ShowCartItemInDetailView cartItemBinding="this" }}
13
- {{/each}}
14
- <tr>
15
- <td colspan="4">总价:<span class="total-price">¥{{ cart.total }}</span></td>
16
- <td></td>
17
- </tr>
18
- </table>
19
-
20
- <a href="/"><< 继续购物</a>
21
- <a href="#">去结算 >></a>
2
+ <div class="r-cart-items">
3
+ <table>
4
+ <thead>
5
+ <tr>
6
+ <th>名称</th>
7
+ <th>价格</th>
8
+ <th>数量</th>
9
+ <th>总价</th>
10
+ <th></th>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ {{#each cart.cartItems}}
15
+ {{ view RightnowOms.ShowCartItemInDetailView cartItemBinding="this" }}
16
+ {{/each}}
17
+ </tbody>
18
+ <tfoot>
19
+ <tr>
20
+ <td colspan="4"></td>
21
+ <td></td>
22
+ </tr>
23
+ </tfoot>
24
+ </table>
25
+ </div>
26
+ <div class="r-bottom-bar">
27
+ <span>总价:<span class="r-money">¥{{ cart.total }}</span></span>
28
+ <span><a href="/"><< 继续购物</a></span>
29
+ <span><a href="#">去结算 >></a></span>
30
+ </div>
@@ -4,4 +4,4 @@ RightnowOms.ShowCartItemView = Ember.View.extend
4
4
 
5
5
  deleteRecord: ->
6
6
  item = this.get('cartItem')
7
- RightnowOms.cartController.removeCartItem(item.get('id'))
7
+ RightnowOms.cartController.removeCartItem(item.get('id'), true)
@@ -1,4 +1,8 @@
1
1
  RightnowOms.ShowCartView = Ember.View.extend
2
+ classNames: ['r-mini-cart']
2
3
  templateName: 'rightnow_oms/app/templates/carts/show'
3
4
 
4
5
  cartBinding: 'RightnowOms.cartController.content'
6
+
7
+ mouseLeave: (e) ->
8
+ $('.r-cart-items').hide()
@@ -0,0 +1,6 @@
1
+ RightnowOms.ShowCartableCountView = Ember.View.extend
2
+ classNames: ['r-cart-cartable-count']
3
+ templateName: 'rightnow_oms/app/templates/carts/show_cartable_count'
4
+
5
+ mouseEnter: (e) ->
6
+ $('.r-cart-items').show()
@@ -1,5 +1,4 @@
1
1
  RightnowOms.ShowCartInDetailView = Ember.View.extend
2
- classNames: ["detailed-cart"]
3
2
  templateName: 'rightnow_oms/app/templates/carts/show_in_detail'
4
3
 
5
4
  cartBinding: 'RightnowOms.cartController.content'
@@ -1,21 +1,144 @@
1
- .detailed-cart {
1
+ .r-links {
2
+ a {
3
+ color: black;
4
+ text-decoration: none;
5
+ &:hover { text-decoration: underline; }
6
+ }
7
+ }
8
+ .r-clear { clear: both; }
9
+ .r-money { color: red; }
10
+ .r-mini-cart {
11
+ @extend .r-links;
12
+ position: relative;
13
+ color: black;
14
+ font-size: 12px;
15
+ .r-cart-cartable-count {
16
+ a {
17
+ background: url('cart.png') no-repeat left center;
18
+ padding-left: 20px;
19
+ line-height: 16px;
20
+ }
21
+ padding: 5px 10px;
22
+ width: 100px;
23
+ text-align: center;
24
+ border: 1px solid #ccc;
25
+ }
26
+ .r-cart-items {
27
+ position: absolute;
28
+ top: 28px;
29
+ right: 0px;
30
+ float: left;
31
+ width: 285px;
32
+ margin-top: -1px;
33
+ border: 1px solid #ccc;
34
+ background-color: white;
35
+ display: none;
36
+ table {
37
+ td {
38
+ padding: 5px;
39
+ text-align: right;
40
+ }
41
+ td.name {
42
+ width: 175px;
43
+ text-align: left;
44
+ overflow: hidden;
45
+ }
46
+ td.money { @extend .money }
47
+ td.delete {
48
+ a {
49
+ color: #BF0000;
50
+ }
51
+ }
52
+ }
53
+ }
54
+ .r-bottom-bar {
55
+ float: right;
56
+ padding: 5px 10px;
57
+ span { margin: 2px; }
58
+ }
59
+ }
60
+ .r-detailed-cart {
61
+ @extend .r-links;
62
+ position: relative;
63
+ width: 100%;
64
+ max-width: 940px;
65
+ margin: 0 auto;
66
+ font-size: 12px;
67
+ background-color: white;
68
+ h2 {
69
+ font-size: 24px;
70
+ line-height: 36px;
71
+ }
2
72
  table {
3
- .subtotal {
4
- text-align: right;
5
- color: red;
73
+ display: table;
74
+ width: 100%;
75
+ margin-bottom: 18px;
76
+ border-collapse: collapse;
77
+ border-spacing: 0;
78
+ vertical-align: middle;
79
+ tr:nth-child(odd) {
80
+ td { background-color: #F9F9F9; }
6
81
  }
7
- .total-price {
8
- text-align: right;
9
- color: red;
82
+
83
+ th, td {
84
+ padding: 8px;
85
+ line-height: 18px;
86
+ text-align: left;
87
+ display: table-cell;
10
88
  }
11
- .price {
12
- color: red;
89
+ thead {
90
+ display: table-header-group;
91
+ tr {
92
+ display: table-row;
93
+ th {
94
+ border-top: 0;
95
+ font-weight: bold;
96
+ vertical-align: bottom;
97
+ }
98
+ }
13
99
  }
14
- .quantity {
15
- text-align: center;
100
+ tbody {
101
+ display: table-row-group;
102
+ tr {
103
+ display: table-row;
104
+ td {
105
+ border-top: 1px solid #DDD;
106
+ vertical-align: top;
107
+ }
108
+ td.price { width: 80px; }
109
+ td.quantity {
110
+ width: 100px;
111
+ span {
112
+ float: left;
113
+ text-align: center;
114
+ min-width: 12px;
115
+ border: 1px solid #CCC;
116
+ background-color: white;
117
+ }
118
+ span.quantity-only { width: 56px; }
119
+ span.quantity { width: 30px; }
120
+ span.increase {
121
+ margin-left: -1px;
122
+ a { text-decoration: none }
123
+ }
124
+ span.decrease {
125
+ margin-right: -1px;
126
+ a { text-decoration: none }
127
+ }
128
+ }
129
+ td.subtotal { width: 80px; }
130
+ td.delete { width: 50px; }
131
+ }
16
132
  }
17
- a {
18
- text-decoration: none;
133
+ tfoot { display: none; }
134
+ }
135
+ .r-bottom-bar {
136
+ position: relative;
137
+ float: right;
138
+ font-size: 20px;
139
+ line-height: 36px;
140
+ span {
141
+ padding: 8px;
19
142
  }
20
143
  }
21
144
  }
@@ -1,17 +1,4 @@
1
1
  module RightnowOms
2
2
  class ApplicationController < ActionController::Base
3
- before_filter :set_null_to_nil
4
-
5
- protected
6
- def load_cart
7
- @cart = Cart.find_by_id(session[:cart_id]) || Cart.new
8
- end
9
-
10
- def set_null_to_nil(data = params)
11
- data.each do |k, v|
12
- set_null_to_nil(v) if v.is_a? Hash
13
- data[k] = nil if v == 'null'
14
- end
15
- end
16
3
  end
17
4
  end
@@ -1,6 +1,7 @@
1
1
  module RightnowOms
2
2
  class CartItemsController < ApplicationController
3
- before_filter :load_cart, only: [:index, :create]
3
+ before_filter :remove_null_params
4
+ before_filter :load_or_create_cart, only: [:index, :create]
4
5
  before_filter :load_cart_item, only: [:update, :destroy]
5
6
 
6
7
  # TODO Unit test needed
@@ -18,7 +19,7 @@ module RightnowOms
18
19
  cart_item = @cart.add_item(find_cartable, params[:cart_item])
19
20
 
20
21
  respond_to do |format|
21
- if cart_item.save
22
+ if cart_item.valid?
22
23
  format.json { render_for_api :default, json: cart_item, root: :cart_item, status: :created }
23
24
  else
24
25
  format.json { render json: cart_item.errors, status: :unprocessable_entity }
@@ -53,7 +54,7 @@ module RightnowOms
53
54
  end
54
55
 
55
56
  def load_cart_item
56
- @cart_item = CartItem.find(params[:id])
57
+ @cart_item = RightnowOms::CartItem.find(params[:id])
57
58
  end
58
59
  end
59
60
  end
@@ -1,16 +1,17 @@
1
1
  module RightnowOms
2
2
  class CartsController < ApplicationController
3
- before_filter :load_cart, only: [:show, :destroy]
3
+ before_filter :load_or_create_cart, only: :show
4
+ before_filter :load_cart, only: :destroy
4
5
 
5
6
  def show
6
7
  respond_to do |format|
7
- format.html
8
+ format.html { render :show, layout: 'rightnow_oms/cart' }
8
9
  format.json { render_for_api :default, json: @cart, root: :cart, status: :ok }
9
10
  end
10
11
  end
11
12
 
12
13
  def destroy
13
- @cart.destroy
14
+ @cart.destroy if has_cart?
14
15
 
15
16
  head :ok
16
17
  end
@@ -14,6 +14,10 @@ module RightnowOms
14
14
  cart_items.map.sum(&:total_price) || 0
15
15
  end
16
16
 
17
+ def cartable_count
18
+ cart_items.map.sum(&:quantity)
19
+ end
20
+
17
21
  def add_item(cartable, opts = { quantity: 1 })
18
22
  quantity = opts[:quantity]
19
23
  group = opts[:group]
@@ -26,10 +30,10 @@ module RightnowOms
26
30
  quantity: cart_item.quantity + quantity.to_i
27
31
  )
28
32
  else
29
- cart_item = cart_items.create!(
33
+ cart_item = cart_items.create(
30
34
  cartable: cartable,
31
- name: cartable.name,
32
- price: cartable.price,
35
+ name: cartable.cartable_name,
36
+ price: cartable.cartable_price,
33
37
  quantity: quantity,
34
38
  group: group,
35
39
  parent_id: parent_id
@@ -7,6 +7,7 @@ module RightnowOms
7
7
  belongs_to :parent, class_name: 'RightnowOms::CartItem', foreign_key: :parent_id
8
8
  has_many :children, class_name: 'RightnowOms::CartItem', foreign_key: :parent_id, dependent: :destroy
9
9
 
10
+ validates :cartable, presence: true, cartable: true
10
11
  validates :cart, presence: true
11
12
  validates :name, presence: true
12
13
  validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 }
@@ -15,12 +16,16 @@ module RightnowOms
15
16
  api_accessible :default do |t|
16
17
  t.add :id
17
18
  t.add :parent_id
19
+ t.add :cartable_id
20
+ t.add :cartable_type
18
21
  t.add :name
19
22
  t.add :price
20
23
  t.add :quantity
21
24
  t.add :group
22
25
  end
23
26
 
27
+ default_scope order("id ASC")
28
+
24
29
  def total_price
25
30
  price * quantity
26
31
  end
@@ -1,4 +1,4 @@
1
- #cart-wrapper
1
+ #rightnow-oms{ class: 'r-detailed-cart' }
2
2
  %script{ type: 'text/x-handlebars'}
3
3
  {{ view RightnowOms.ShowCartInDetailView }}
4
4
 
data/lib/rightnow_oms.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require "acts_as_api"
2
2
 
3
3
  require "rightnow_oms/engine"
4
+ require "rightnow_oms/cartable_validator"
5
+ require "rightnow_oms/acts_as_cartable"
6
+ require "rightnow_oms/controller_helpers"
4
7
 
5
- module RightnowOms
6
- end
8
+ ActiveRecord::Base.extend(RightnowOms::ActsAsCartable)
9
+ ActionController::Base.send(:include, RightnowOms::ControllerHelpers)
@@ -0,0 +1,36 @@
1
+ module RightnowOms
2
+ module ActsAsCartable
3
+ def acts_as_cartable?
4
+ false
5
+ end
6
+
7
+ def acts_as_cartable(opts = { name: :name, price: :price })
8
+ cartable_config.update(opts) if opts.is_a? Hash
9
+
10
+ class_eval do
11
+ include RightnowOms::ActsAsCartable::InstanceMethods
12
+ extend RightnowOms::ActsAsCartable::ClassMethods
13
+ end
14
+ end
15
+
16
+ def cartable_config
17
+ @cartable_config ||= { name: :name, price: :price }
18
+ end
19
+
20
+ module ClassMethods
21
+ def acts_as_cartable?
22
+ self.included_modules.include?(InstanceMethods)
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+ def cartable_name
28
+ self.send(self.class.cartable_config[:name])
29
+ end
30
+
31
+ def cartable_price
32
+ self.send(self.class.cartable_config[:price])
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ class CartableValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ record.errors[attribute] << "must act as cartable" unless value && value.class.acts_as_cartable?
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ module RightnowOms
2
+ module ControllerHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ def has_cart?
6
+ !@cart.nil?
7
+ end
8
+
9
+ def load_or_create_cart
10
+ load_cart
11
+
12
+ unless has_cart?
13
+ @cart = RightnowOms::Cart.create! and session[:cart_id] = @cart.id
14
+ end
15
+ end
16
+
17
+ def load_cart
18
+ @cart = RightnowOms::Cart.find_by_id(session[:cart_id])
19
+ end
20
+
21
+ def remove_null_params(data = params)
22
+ data.each do |k, v|
23
+ remove_null_params(v) if v.is_a? Hash
24
+ data.delete(k) if v == 'null'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module RightnowOms
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rightnow_oms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-09 00:00:00.000000000 Z
12
+ date: 2012-02-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &17425100 !ruby/object:Gem::Requirement
16
+ requirement: &10801820 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *17425100
24
+ version_requirements: *10801820
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: jquery-rails
27
- requirement: &17423860 !ruby/object:Gem::Requirement
27
+ requirement: &10800840 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *17423860
35
+ version_requirements: *10800840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: coffee-rails
38
- requirement: &17422380 !ruby/object:Gem::Requirement
38
+ requirement: &10799660 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *17422380
46
+ version_requirements: *10799660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sass-rails
49
- requirement: &17456900 !ruby/object:Gem::Requirement
49
+ requirement: &10813400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *17456900
57
+ version_requirements: *10813400
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: acts_as_api
60
- requirement: &17454900 !ruby/object:Gem::Requirement
60
+ requirement: &10811620 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *17454900
68
+ version_requirements: *10811620
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ember-rails
71
- requirement: &17454240 !ruby/object:Gem::Requirement
71
+ requirement: &10810480 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *17454240
79
+ version_requirements: *10810480
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: haml-rails
82
- requirement: &17453040 !ruby/object:Gem::Requirement
82
+ requirement: &10809240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,18 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *17453040
91
- - !ruby/object:Gem::Dependency
92
- name: factory_girl_rails
93
- requirement: &17450640 !ruby/object:Gem::Requirement
94
- none: false
95
- requirements:
96
- - - ! '>='
97
- - !ruby/object:Gem::Version
98
- version: '0'
99
- type: :development
100
- prerelease: false
101
- version_requirements: *17450640
90
+ version_requirements: *10809240
102
91
  description: A common mountable engine can be used to manage the orders.
103
92
  email:
104
93
  - towerhe@gmail.com
@@ -111,12 +100,9 @@ files:
111
100
  - app/controllers/rightnow_oms/application_controller.rb
112
101
  - app/models/rightnow_oms/cart.rb
113
102
  - app/models/rightnow_oms/cart_item.rb
114
- - app/helpers/rightnow_oms/carts_helper.rb
115
- - app/helpers/rightnow_oms/application_helper.rb
116
- - app/helpers/rightnow_oms/cart_items_helper.rb
117
103
  - app/assets/stylesheets/rightnow_oms/carts.css.scss
118
- - app/assets/stylesheets/rightnow_oms/cart_items.css
119
104
  - app/assets/stylesheets/rightnow_oms/application.css
105
+ - app/assets/images/rightnow_oms/cart.png
120
106
  - app/assets/javascripts/rightnow_oms/application.js
121
107
  - app/assets/javascripts/rightnow_oms/vendor/ember-data.min.js
122
108
  - app/assets/javascripts/rightnow_oms/vendor/ember-data.js
@@ -128,6 +114,7 @@ files:
128
114
  - app/assets/javascripts/rightnow_oms/app/templates/cart_items/show.hjs
129
115
  - app/assets/javascripts/rightnow_oms/app/templates/cart_items/show_in_detail.hjs
130
116
  - app/assets/javascripts/rightnow_oms/app/templates/carts/show.hjs
117
+ - app/assets/javascripts/rightnow_oms/app/templates/carts/show_cartable_count.hjs
131
118
  - app/assets/javascripts/rightnow_oms/app/templates/carts/show_in_detail.hjs
132
119
  - app/assets/javascripts/rightnow_oms/app/app.js.coffee
133
120
  - app/assets/javascripts/rightnow_oms/app/controllers/cart.js.coffee
@@ -137,6 +124,7 @@ files:
137
124
  - app/assets/javascripts/rightnow_oms/app/views/cart_items/show.js.coffee
138
125
  - app/assets/javascripts/rightnow_oms/app/views/carts/show_in_detail.js.coffee
139
126
  - app/assets/javascripts/rightnow_oms/app/views/carts/show.js.coffee
127
+ - app/assets/javascripts/rightnow_oms/app/views/carts/show_cartable_count.js.coffee
140
128
  - app/views/rightnow_oms/carts/show.html.haml
141
129
  - config/routes.rb
142
130
  - db/migrate/20120202104431_create_rightnow_oms_carts.rb
@@ -144,11 +132,15 @@ files:
144
132
  - db/migrate/20120207095146_add_parent_id_to_rightnow_oms_cart_items.rb
145
133
  - db/migrate/20120203045059_create_rightnow_oms_cart_items.rb
146
134
  - lib/rightnow_oms.rb
135
+ - lib/rightnow_oms/controller_helpers.rb
136
+ - lib/rightnow_oms/acts_as_cartable.rb
147
137
  - lib/rightnow_oms/engine.rb
148
138
  - lib/rightnow_oms/version.rb
139
+ - lib/rightnow_oms/cartable_validator.rb
149
140
  - lib/tasks/rightnow_oms_tasks.rake
150
141
  - Rakefile
151
- - README.rdoc
142
+ - README.md
143
+ - CHANGELOG
152
144
  homepage: http://hetao.im
153
145
  licenses: []
154
146
  post_install_message:
@@ -163,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
155
  version: '0'
164
156
  segments:
165
157
  - 0
166
- hash: 4343013466019004784
158
+ hash: -375847056207753837
167
159
  required_rubygems_version: !ruby/object:Gem::Requirement
168
160
  none: false
169
161
  requirements:
@@ -172,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
164
  version: '0'
173
165
  segments:
174
166
  - 0
175
- hash: 4343013466019004784
167
+ hash: -375847056207753837
176
168
  requirements: []
177
169
  rubyforge_project:
178
170
  rubygems_version: 1.8.10
@@ -180,3 +172,4 @@ signing_key:
180
172
  specification_version: 3
181
173
  summary: Manage the orders.
182
174
  test_files: []
175
+ has_rdoc:
data/README.rdoc DELETED
@@ -1,84 +0,0 @@
1
- = RightnowOms
2
-
3
- == Description
4
-
5
- A common gem for managing your carts and orders. RightnowOms is a rails mountable engine. It gets a lot of benifits from Ember.JS[http://emberjs.com]
6
-
7
- == Requirements
8
-
9
- Add the following gems to your Gemfile:
10
-
11
- * jquery-rails
12
- * ember-rails
13
- * haml-rails
14
- * coffee-rails
15
- * sass-rails
16
- * acts_as_api
17
-
18
- == Installation
19
-
20
- Make sure that all requirements are met and add RightnowOms to your Gemfile.
21
-
22
- gem 'rightnow_oms'
23
-
24
- Mount RightnowOms to your application.
25
-
26
- # config/routes.rb
27
- mount RightnowOms::Engine => "rightnow_oms"
28
-
29
- Create the migrations with:
30
-
31
- rake rightnow_oms:install:migrations
32
- rake db:migrate
33
-
34
- Run +bundle install+ and require ember and ember-data in your +app/assets/javascripts/application.js+:
35
-
36
- = require rightnow_oms/vendor/ember
37
- = require rightnow_oms/vendor/ember-data
38
-
39
- Add the following line to your +app/assets/javascripts/application.js+:
40
-
41
- = require rightnow_oms/application
42
-
43
- Add the stylesheets to your +app/assets/stylesheets/application.css+:
44
-
45
- = require rightnow_oms/application
46
-
47
- Create a layout for your detailed cart view:
48
-
49
- # app/views/layouts/rightnow_oms/application.html.haml
50
- !!!
51
- %html
52
- %head
53
- %title Dummy
54
- = stylesheet_link_tag "application"
55
- = javascript_include_tag "application"
56
- = csrf_meta_tags
57
-
58
- %body
59
- = yield
60
-
61
- Add a place holder for your cart in your views:
62
-
63
- <div id="cart-wrapper">
64
- <script type="text/x-handlebars">
65
- {{ view RightnowOms.ShowCartView }}
66
- </script>
67
- </div>
68
-
69
- == Development
70
-
71
- RightnowOms is developed with Ruby 1.9.3-p0 and Rails 3.1.3
72
-
73
- bundle install
74
- bundle exec rake app:db:migrate
75
- bundle exec rake app:db:seed
76
-
77
- # Run the tests
78
- bundle exec rake app:db:test:prepare
79
- rspec
80
-
81
- # Start the dummy application
82
- rails s
83
-
84
- Copyright 2011-2012 Beijing Menglifang Network Technology and Science Co.,Ltd. All rights reserved.
@@ -1,12 +0,0 @@
1
- .cart-items {
2
- text-align: right;
3
- overflow: auto;
4
- }
5
-
6
- .cart-items table {
7
- float: right;
8
- }
9
-
10
- .cart-items table .price {
11
- color: red;
12
- }
@@ -1,4 +0,0 @@
1
- module RightnowOms
2
- module ApplicationHelper
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module RightnowOms
2
- module CartItemsHelper
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module RightnowOms
2
- module CartsHelper
3
- end
4
- end