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.
- data/CHANGELOG +21 -0
- data/README.md +163 -0
- data/Rakefile +4 -14
- data/app/assets/images/rightnow_oms/cart.png +0 -0
- data/app/assets/javascripts/rightnow_oms/app/app.js.coffee +1 -1
- data/app/assets/javascripts/rightnow_oms/app/controllers/cart.js.coffee +14 -5
- data/app/assets/javascripts/rightnow_oms/app/models/cart.js.coffee +1 -2
- data/app/assets/javascripts/rightnow_oms/app/models/cart_item.js.coffee +15 -2
- data/app/assets/javascripts/rightnow_oms/app/templates/cart_items/show.hjs +3 -3
- data/app/assets/javascripts/rightnow_oms/app/templates/cart_items/show_in_detail.hjs +11 -7
- data/app/assets/javascripts/rightnow_oms/app/templates/carts/show.hjs +7 -7
- data/app/assets/javascripts/rightnow_oms/app/templates/carts/show_cartable_count.hjs +1 -0
- data/app/assets/javascripts/rightnow_oms/app/templates/carts/show_in_detail.hjs +29 -20
- data/app/assets/javascripts/rightnow_oms/app/views/cart_items/show.js.coffee +1 -1
- data/app/assets/javascripts/rightnow_oms/app/views/carts/show.js.coffee +4 -0
- data/app/assets/javascripts/rightnow_oms/app/views/carts/show_cartable_count.js.coffee +6 -0
- data/app/assets/javascripts/rightnow_oms/app/views/carts/show_in_detail.js.coffee +0 -1
- data/app/assets/stylesheets/rightnow_oms/carts.css.scss +136 -13
- data/app/controllers/rightnow_oms/application_controller.rb +0 -13
- data/app/controllers/rightnow_oms/cart_items_controller.rb +4 -3
- data/app/controllers/rightnow_oms/carts_controller.rb +4 -3
- data/app/models/rightnow_oms/cart.rb +7 -3
- data/app/models/rightnow_oms/cart_item.rb +5 -0
- data/app/views/rightnow_oms/carts/show.html.haml +1 -1
- data/lib/rightnow_oms.rb +5 -2
- data/lib/rightnow_oms/acts_as_cartable.rb +36 -0
- data/lib/rightnow_oms/cartable_validator.rb +5 -0
- data/lib/rightnow_oms/controller_helpers.rb +28 -0
- data/lib/rightnow_oms/version.rb +1 -1
- metadata +27 -34
- data/README.rdoc +0 -84
- data/app/assets/stylesheets/rightnow_oms/cart_items.css +0 -12
- data/app/helpers/rightnow_oms/application_helper.rb +0 -4
- data/app/helpers/rightnow_oms/cart_items_helper.rb +0 -4
- 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
|
-
|
16
|
-
|
17
|
-
|
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
|
|
Binary file
|
@@ -20,9 +20,18 @@ RightnowOms.cartController = Ember.Object.create
|
|
20
20
|
@store.commit()
|
21
21
|
|
22
22
|
decreaseCartItem: (id) ->
|
23
|
-
|
24
|
-
@store.commit()
|
23
|
+
cartItem = RightnowOms.CartItem.findById(id)
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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.
|
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
|
-
|
60
|
-
@all().
|
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=
|
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
|
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
|
-
|
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
|
-
<
|
3
|
-
<
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
<
|
21
|
-
<
|
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>
|
@@ -1,21 +1,144 @@
|
|
1
|
-
.
|
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
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
82
|
+
|
83
|
+
th, td {
|
84
|
+
padding: 8px;
|
85
|
+
line-height: 18px;
|
86
|
+
text-align: left;
|
87
|
+
display: table-cell;
|
10
88
|
}
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
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 :
|
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.
|
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 :
|
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.
|
32
|
-
price: cartable.
|
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
|
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
|
-
|
6
|
-
|
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,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
|
data/lib/rightnow_oms/version.rb
CHANGED
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.
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *10801820
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jquery-rails
|
27
|
-
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: *
|
35
|
+
version_requirements: *10800840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: coffee-rails
|
38
|
-
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: *
|
46
|
+
version_requirements: *10799660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sass-rails
|
49
|
-
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: *
|
57
|
+
version_requirements: *10813400
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: acts_as_api
|
60
|
-
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: *
|
68
|
+
version_requirements: *10811620
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ember-rails
|
71
|
-
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: *
|
79
|
+
version_requirements: *10810480
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: haml-rails
|
82
|
-
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: *
|
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.
|
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:
|
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:
|
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.
|