rightnow_oms 0.0.4 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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