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.
- 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.
|