office_clerk 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ddc45855a851af3f02607825a7d2fd94ed802c9
4
- data.tar.gz: ddfab4362620b9043574d8eb7d97793b8a49132b
3
+ metadata.gz: c64817a8d69623b98ac71359f18f3b2d47683bd2
4
+ data.tar.gz: dcfe694a0ed59c10487658e77090d224676c4d39
5
5
  SHA512:
6
- metadata.gz: 51b6b48dfcabe21eef92716f31fe282d571b440ce453ebd73a77e7995c8e15c7b2bdfdad080d0497b6df434fcd70efe5604a90df40897dda1b994cbdb9fe55a2
7
- data.tar.gz: bdf6744c2b0c661b66ce56d04e6f1f4dc2ff3109d7dafc1fc1f4d71c3f76c4900628ec5e66da41828501cc63d72328611952feee2e93b06ece5765ee09d1236b
6
+ metadata.gz: b9f11aa0e76f6d1683da1e324cf8a8b65bba947adaa6455ec97d5049c2494376cca854a8654b046653a89b20101837e041ea9d5a4629816d3c222d150673023d
7
+ data.tar.gz: 0bc48769c8e8d8492e1a9914e92d3c2df7b4fd37f4b8402c0167fadf1507071eb84369bef281c1eff540c247a308a1a4e979f14b7a06cf11db69a8c4d68308c2
data/.travis.yml CHANGED
@@ -1,4 +1,6 @@
1
1
  language: ruby
2
+ sudo: false
3
+ cache: bundler
2
4
  script:
3
5
  - RAILS_ENV=test bundle exec rake db:migrate
4
6
  - CODECLIMATE_REPO_TOKEN=3f97bb5305cd65f6683587a32b4b3eae42cfec26d3de56374b10b3efb78ccf6a bundle exec rspec
data/ChangeLog.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.7
2
+
3
+ - Order search improvements, added a private Note too
4
+ - Tax improvements: lots of tests to eradicate the bug our accountant found
5
+ - in place editing, for the note and some product features
6
+
1
7
  ### 0.6
2
8
 
3
9
  - Remove simpleform
@@ -11,5 +17,5 @@
11
17
 
12
18
  ### prior 0.5
13
19
 
14
- Basic core has been stable and in produciton for 9 months.
20
+ Basic core has been stable and in production for 9 months.
15
21
  Since no gem realease were done before production versions go quite quickly towards 1
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- office_clerk (0.5)
4
+ office_clerk (0.6)
5
5
  bcrypt-ruby (~> 3.1)
6
+ best_in_place
6
7
  bootstrap-sass (~> 3.1)
7
8
  bootstrap_form (~> 2.2)
8
9
  coffee-rails
@@ -53,6 +54,9 @@ GEM
53
54
  bcrypt (3.1.9)
54
55
  bcrypt-ruby (3.1.5)
55
56
  bcrypt (>= 3.1.3)
57
+ best_in_place (3.0.0)
58
+ actionpack (>= 3.2)
59
+ railties (>= 3.2)
56
60
  better_errors (2.0.0)
57
61
  coderay (>= 1.0.0)
58
62
  erubis (>= 2.6.6)
@@ -122,7 +126,7 @@ GEM
122
126
  guard-rspec (4.3.1)
123
127
  guard (~> 2.1)
124
128
  rspec (>= 2.14, < 4.0)
125
- haml (4.0.5)
129
+ haml (4.0.6)
126
130
  tilt
127
131
  hike (1.2.3)
128
132
  hitimes (1.2.2)
@@ -134,7 +138,7 @@ GEM
134
138
  jquery-rails (3.1.2)
135
139
  railties (>= 3.0, < 5.0)
136
140
  thor (>= 0.14, < 2.0)
137
- jquery-ui-rails (5.0.2)
141
+ jquery-ui-rails (5.0.3)
138
142
  railties (>= 3.2.16)
139
143
  json (1.8.1)
140
144
  kramdown (1.5.0)
@@ -223,10 +227,10 @@ GEM
223
227
  rspec-support (~> 3.1.0)
224
228
  rspec-support (3.1.2)
225
229
  sass (3.2.19)
226
- sass-rails (4.0.4)
230
+ sass-rails (4.0.5)
227
231
  railties (>= 4.0.0, < 5.0)
228
232
  sass (~> 3.2.2)
229
- sprockets (~> 2.8, < 2.12)
233
+ sprockets (~> 2.8, < 3.0)
230
234
  sprockets-rails (~> 2.0)
231
235
  simplecov (0.9.1)
232
236
  docile (~> 1.1.0)
@@ -234,12 +238,12 @@ GEM
234
238
  simplecov-html (~> 0.8.0)
235
239
  simplecov-html (0.8.0)
236
240
  slop (3.6.0)
237
- sprockets (2.11.3)
241
+ sprockets (2.12.3)
238
242
  hike (~> 1.2)
239
243
  multi_json (~> 1.0)
240
244
  rack (~> 1.0)
241
245
  tilt (~> 1.1, != 1.3.0)
242
- sprockets-rails (2.2.1)
246
+ sprockets-rails (2.2.2)
243
247
  actionpack (>= 3.0)
244
248
  activesupport (>= 3.0)
245
249
  sprockets (>= 2.8, < 4.0)
data/README.md CHANGED
@@ -8,11 +8,7 @@ Office Clerk is the back office helper, your accountant, storage manager, secret
8
8
 
9
9
  #### Status
10
10
 
11
- The clerks are under heavy development in public beta one could say.
12
-
13
- A first push of development resulted in a system that has been used for backend office work since 2/2014
14
-
15
- Currenly refinements and front end work is underway and scheduled for x-mas.
11
+ In production for 2 sites. Work continues on refinements. That could qualify for 1.0 but i'll wait a few months.
16
12
 
17
13
  ### Other clerks
18
14
 
@@ -24,17 +20,32 @@ This currenly does graphical sales reports. Purchase order creation is planned.
24
20
 
25
21
  ### Print Clerk
26
22
 
27
- A invoice generator
23
+ A invoice generator. Also barcode generation and receipt printing (for POS use).
28
24
 
29
25
  ### Sales Clerk
30
26
 
31
- Work is underway to make the front end work. ie your standard e-commerce front end.
27
+ We have a shop [online](http://auringostaitaan.fi/), the best way to get started is to clone [it](https://github.com/rubyclerks/sales_clerk).
32
28
 
33
29
  ### Getting Started
34
30
 
35
- Clone the office clerk, migrate, and click around. Fork and help.
31
+ The easy way (tryout or new project):
32
+
33
+ - clone sales_clerk
34
+ - bundle and migrate it
35
+ - change the git/config
36
+ - start editing
37
+
38
+ The longer route, adding to existing project
39
+
40
+ - add office_clerk to Gemfile (gem or git)
41
+ - build your public pages
42
+ - may use ShopController which is included in office
43
+
44
+ ### Further
45
+
46
+ If you got this far and still have question , mail me, or mail the [list](https://groups.google.com/forum/#!forum/rubyclerks)
36
47
 
37
- THe final version wil work by cloning the sales clerk, OR adding the officeclerk engine into your existing app. Docs follow.
48
+ I will start writing User/Developer guides soon, your question will help. Off course your help will help even more :-)
38
49
 
39
50
  ### Similar Projects
40
51
 
@@ -1,6 +1,10 @@
1
1
  //= require jquery
2
+ //= require best_in_place
3
+
2
4
  //= require jquery-ui
3
5
  //= require jquery-ui/datepicker-fi
6
+ //= require best_in_place.jquery-ui
7
+
4
8
  //= require bootstrap
5
9
  //= require_self
6
10
 
@@ -19,4 +23,9 @@ function initPage(){
19
23
 
20
24
  $(window).bind('page:change', function() {
21
25
  initPage();
22
- });
26
+ });
27
+
28
+ $(document).ready(function() {
29
+ /* Activating Best In Place */
30
+ jQuery(".best_in_place").best_in_place();
31
+ });
@@ -27,7 +27,7 @@ $table-border-color: scale-color($primary-color, $lightness: 85%);
27
27
 
28
28
  $tausta-bg: scale-color($primary-color, $lightness: 95%);
29
29
 
30
-
30
+ @import "bootstrap-sprockets";
31
31
  @import "bootstrap";
32
32
 
33
33
  .container-fluid{
@@ -49,7 +49,7 @@ class OrdersController < AdminController
49
49
  end
50
50
 
51
51
  def create
52
- @order = Order.create(params_for_model)
52
+ @order = Order.create(params_for_order)
53
53
  @order.build_basket() unless @order.basket
54
54
  if @order.save
55
55
  redirect_to order_path(@order), :notice => t(:create_success, :model => "order")
@@ -60,10 +60,14 @@ class OrdersController < AdminController
60
60
 
61
61
  def update
62
62
  @order.build_basket unless @order.basket
63
- if @order.update_attributes(params_for_model)
64
- redirect_to order_path(@order), :notice => t(:update_success, :model => "order")
65
- else
66
- render :action => :edit
63
+ respond_to do |format|
64
+ if @order.update_attributes(params_for_order)
65
+ format.html { redirect_to(@order, :notice => t(:update_success, :model => "order")) }
66
+ format.json { respond_with_bip(@order) }
67
+ else
68
+ format.html { render :action => :edit }
69
+ format.json { respond_with_bip(@order) }
70
+ end
67
71
  end
68
72
  end
69
73
 
@@ -73,8 +77,8 @@ class OrdersController < AdminController
73
77
  @order = Order.find(params[:id])
74
78
  end
75
79
 
76
- def params_for_model
77
- params.require(:order).permit(:ordered_on,:shipment_price,:shipment_tax,:basket_id,:email,:paid_on,:shipped_on,:paid_on,:canceled_on,:shipment_type)
80
+ def params_for_order
81
+ params.require(:order).permit(:shipment_price,:shipment_tax,:shipment_type, :note)
78
82
  end
79
83
  end
80
84
 
@@ -44,11 +44,14 @@ class ProductsController < AdminController
44
44
  end
45
45
 
46
46
  def update
47
- if @product.update_attributes(params_for_model)
48
- flash.notice = t(:update_success, :model => "product")
49
- redirect_to product_path(@product)
50
- else
51
- render :action => :edit
47
+ respond_to do |format|
48
+ if @product.update_attributes(params_for_model)
49
+ format.html { redirect_to(@product, :notice => t(:update_success, :model => "product")) }
50
+ format.json { respond_with_bip(@product) }
51
+ else
52
+ format.html { render :action => :edit }
53
+ format.json { respond_with_bip(@product) }
54
+ end
52
55
  end
53
56
  end
54
57
 
@@ -1,6 +1,6 @@
1
1
  # encoding : utf-8
2
2
  module AdminHelper
3
-
3
+
4
4
  def basket_edit_link basket , options = {}
5
5
  return "---" unless basket
6
6
  return "" unless request.url.include?("basket")
@@ -23,4 +23,18 @@ module AdminHelper
23
23
  return "" unless params[:q]
24
24
  params[:q][key] || ""
25
25
  end
26
+
27
+ # define a bunch of defaults for the best_in_place call
28
+ # save and cancel buttons with internationlized texts
29
+ # bootstrap form class
30
+ # a default note
31
+ # same signature as best_in_place, ie object, field symbol , hash
32
+ def in_place object , field , attributes ={}
33
+ defaults = { :ok_button => I18n.t(:edit), :ok_button_class => "btn btn-success" ,
34
+ :cancel_button => I18n.t(:cancel) , :cancel_button_class => "btn btn-warning",
35
+ :place_holder => I18n.t(:edit) , :inner_class => "form-control" }
36
+ attributes.reverse_merge! defaults
37
+ best_in_place(object , field , attributes)
38
+ end
39
+ BestInPlace::ViewHelpers.extend OfficeHelper
26
40
  end
data/app/models/item.rb CHANGED
@@ -15,7 +15,7 @@ class Item < ActiveRecord::Base
15
15
 
16
16
  # tax included in the total
17
17
  def tax_amount
18
- ((self.total * self.tax ) / 100.0).round(2)
18
+ self.quantity * single_item_tax
19
19
  end
20
20
 
21
21
  #relation of price to product price down from 100 %
@@ -23,4 +23,8 @@ class Item < ActiveRecord::Base
23
23
  return 0 unless product.price and product.price != 0
24
24
  (100 - (price/product.price)*100).round(0)
25
25
  end
26
+
27
+ def single_item_tax
28
+ (self.price * self.tax / ( 100.0 + self.tax)).round(4)
29
+ end
26
30
  end
data/app/models/order.rb CHANGED
@@ -32,16 +32,15 @@ class Order < ActiveRecord::Base
32
32
  # total tax is for when the rates don't matter, usually to cutomers.
33
33
  # only on bills or invoices do we need the detailed list you get from the taxes function
34
34
  def total_tax
35
- basket.total_tax + (shipment_tax*shipment_price / 100.0).round(2)
35
+ basket.total_tax + shipment_tax_value
36
36
  end
37
37
 
38
38
  # return a hash of rate => amount , because products may have different taxes,
39
39
  # the items in an order may have a collection of tax rates.
40
40
  def taxes
41
41
  cart = basket.taxes
42
- s_tax = self.shipment_price * shipment_tax
43
42
  #relies on basket creating a default value of 0
44
- cart[self.shipment_tax] += s_tax if self.shipment_tax and self.shipment_tax != 0
43
+ cart[self.shipment_tax] += shipment_tax_value if self.shipment_tax and self.shipment_tax != 0
45
44
  cart
46
45
  end
47
46
 
@@ -69,4 +68,7 @@ class Order < ActiveRecord::Base
69
68
  return false unless shipment_type
70
69
  return shipment_type != "pickup"
71
70
  end
71
+ def shipment_tax_value
72
+ (self.shipment_tax * self.shipment_price / ( 100.0 + self.shipment_tax)).round(4)
73
+ end
72
74
  end
@@ -1,5 +1,9 @@
1
- <% [:number , :ordered_on ,:total_price , :tax , :paid_on ].collect{|i| I18n.t(i)}.join("") %>
1
+ <%= [:order_number , :ordered_on ,:total_price , :vat , :vat , :paid_on ].collect{|i| I18n.t(i)}.join(";") %>
2
2
  <% @orders.each do |order| %>
3
- <%=[ order.number.to_s , date(order.ordered_on) , order.total_price.round(2),
4
- order.total_tax.round(2) , date(order.paid_on) ].join(",") %>
5
- <%end%>
3
+ <% values = [ order.number.to_s , date(order.ordered_on) , order.total_price.round(2)] %>
4
+ <% taxes = order.taxes %>
5
+ <% values << taxes[14.0].round(2) %>
6
+ <% values << taxes[24.0].round(2) %>
7
+ <% values << date(order.paid_on) %>
8
+ <%= values.join(";") %>
9
+ <%end%>
@@ -13,15 +13,17 @@
13
13
  %th= sort_link @q, :number
14
14
  %th= sort_link @q, :ordered_on
15
15
  %th= t(:items)
16
- %th= sort_link @q, :total_price
16
+ %th= sort_link @q, :basket_total_price
17
17
  %th= sort_link @q, :email
18
- %th= t(:paid_on)
19
- %th= t(:shipped_on)
18
+ %th= sort_link @q, :paid_on
19
+ %th= sort_link @q, :shipped_on
20
20
  %tbody
21
21
  - @orders.each do |order|
22
22
  %tr{:class => "line-#{cycle("1","2")}"}
23
23
  %td
24
24
  = link_to order.number.to_s , order_path(order), :title => t(:show)
25
+ -unless order.note.blank?
26
+ %span.glyphicon.glyphicon-flag
25
27
  %td= date(order.ordered_on)
26
28
  %td= order.basket.items.length
27
29
  %td= link_to euros(order.total_price), basket_path(order.basket)
@@ -37,7 +39,10 @@
37
39
  .col-md-3
38
40
  = search_form_for @q, :url => search_orders_path, :html => { :class => "form-horizontal" , :role => "form"}, :method => :get do |f|
39
41
  .form-group
40
- = f.text_field :number_cont ,:class => "form-control" , :placeholder => t(:order_number)
42
+ .input-group
43
+ = f.text_field :number_cont ,:class => "form-control" , :placeholder => t(:order_number)
44
+ %span.input-group-addon
45
+ = f.radio_button :note_present , true
41
46
  .form-group
42
47
  = f.text_field(:email , :class => "form-control" , :placeholder => t(:email))
43
48
  .form-group
@@ -51,7 +56,6 @@
51
56
  .col-md-3
52
57
  = f.label(:ordered_on)
53
58
  .col-sm-1.radio
54
- = f.radio_button :ordered_on_blank , true
55
59
  .form-group.col-md-6
56
60
  = f.search_field :ordered_on_gteq , :class => "form-control datepicker" , :value => sort_date(:ordered_on_gteq)
57
61
  .form-group.col-md-4
@@ -3,16 +3,22 @@
3
3
  = t(:order) + " : " + @order.number.to_s
4
4
  .row
5
5
  .col-md-4
6
+ %p
7
+ %b
8
+ = t(:email) + " : " + @order.email.to_s
9
+ %p
10
+ %b
11
+ = t(:phone) + " : " + @order.phone.to_s
6
12
  %p
7
13
  %b
8
14
  = t(:ordered_on) + " : " + date(@order.ordered_on)
9
15
  %p
10
16
  %b
11
- = t(:email) + " : " + @order.email.to_s
17
+ = t(:canceled_on) + " : " + date(@order.canceled_on)
18
+ .col-md-4
12
19
  %p
13
20
  %b
14
21
  = t(:shipment_type) + " : " + @order.shipment_type.to_s
15
- .col-md-4
16
22
  %p
17
23
  %b
18
24
  -if @order.paid_on
@@ -26,24 +32,30 @@
26
32
  = t(:shipped_on) + " : " + date(@order.shipped_on)
27
33
  -else
28
34
  = link_to t(:ship), ship_order_path(@order), :class => "btn btn-info ship_now"
35
+ .col-md-4
29
36
  %p
30
- %b
31
- = t(:canceled_on) + " : " + date(@order.canceled_on)
37
+ %b= t(:note)
38
+ %p
39
+ = in_place @order , :note, :as => :textarea
40
+
32
41
  -content_for :basket do
33
42
  %tr
34
- %td{:colspan => 2}
43
+ %td= t(:name)
44
+ %td=@order.name
35
45
  %td
36
46
  %b= t(:total_tax) + " : "
37
47
  %td
38
48
  %b= euros(@order.total_tax)
39
49
  %tr
40
- %td{:colspan => 2}
50
+ %td= t(:street)
51
+ %td= @order.street
41
52
  %td
42
53
  %b= t(:shipment_price) + " : "
43
54
  %td
44
55
  %b= euros(@order.shipment_price)
45
56
  %tr
46
- %td{:colspan => 2}
57
+ %td= t(:city)
58
+ %td=@order.city
47
59
  %td
48
60
  %b= t(:total_price) + " : "
49
61
  %td
@@ -21,10 +21,10 @@
21
21
  .col-md-6
22
22
  %p
23
23
  %b= t(:price) + " : "
24
- = euros(@product.price)
24
+ = in_place @product , :price , :display_with => :euros
25
25
  %p
26
26
  %b= t(:cost) + " : "
27
- = euros(@product.cost)
27
+ = in_place @product , :cost , :display_with => :euros
28
28
  %p
29
29
  %b= t(:category) + " : "
30
30
  = link_to @product.category.name ,category_path(@product.category) if @product.category
@@ -33,11 +33,11 @@
33
33
  = @product.link
34
34
  %p
35
35
  %b= t(:ean) + " : "
36
- = @product.ean
36
+ = in_place @product , :ean
37
37
  .col-md-6
38
38
  %p
39
39
  %b= t(:weight) + " : "
40
- = @product.weight
40
+ = in_place @product , :weight
41
41
  %p
42
42
  %b= t(:inventory) + " : "
43
43
  = @product.inventory
@@ -46,19 +46,20 @@
46
46
  = link_to @product.supplier.supplier_name ,supplier_path(@product.supplier) if @product.supplier
47
47
  %p
48
48
  %b= t(:scode) + " : "
49
- = @product.scode
49
+ = in_place @product , :scode
50
50
  %p
51
51
  %b= t(:tax_percent) + " : "
52
- = @product.tax
52
+ = in_place @product , :tax
53
53
  .col-md-4
54
54
  %p
55
55
  %b= t(:summary) + " : "
56
- = markdown @product.summary
56
+ = in_place @product , :summary
57
57
  %p
58
58
  %b= t(:description) + " : "
59
- = markdown @product.description
59
+ = in_place @product , :description , :as => :textarea
60
60
  .col-md-4
61
61
  =render :partial => "shop/product_box" , :locals => {:product => @product}
62
+ = markdown @product.description
62
63
  %br
63
64
  .row.product_show_row_buttons
64
65
  .col-md-2
@@ -0,0 +1,8 @@
1
+ # poor mans migration.
2
+ # Trying to keep the schema clean until version 1
3
+
4
+ unless Rails.env.test?
5
+ unless Order.columns_hash["note"]
6
+ ActiveRecord::Base.connection.add_column :orders, :note, :string , :default => ""
7
+ end
8
+ end
@@ -73,6 +73,7 @@ en:
73
73
  new_item: New product item
74
74
  next: Next
75
75
  not_online: not online
76
+ note: Note
76
77
  notice: Notice
77
78
  online: Online
78
79
  order: Order
@@ -161,6 +162,7 @@ en:
161
162
  activerecord:
162
163
  attributes:
163
164
  basket:
165
+ type: Type
164
166
  created_at: Created
165
167
  total_price: Price
166
168
  clerk:
@@ -180,6 +182,11 @@ en:
180
182
  description: Description
181
183
  summary: Summary
182
184
  order:
185
+ total: Total
186
+ paid_on: Paid on
187
+ shipped_on: Shipped on
188
+ canceled_on: Canceled on
189
+ note: Note
183
190
  email: Email
184
191
  ordered_on: Ordered on
185
192
  purchase:
@@ -73,6 +73,7 @@ fi:
73
73
  next: seuraava
74
74
  notice: Huom
75
75
  not_online: ei netissä
76
+ note: Muistiinpano
76
77
  online: Netissä
77
78
  online_eq: Online?
78
79
  order: Tilaus
@@ -161,6 +162,7 @@ fi:
161
162
  activerecord:
162
163
  attributes:
163
164
  basket:
165
+ type: Laji
164
166
  created_at: Luotu
165
167
  total_price: Hinta
166
168
  clerk:
@@ -180,6 +182,11 @@ fi:
180
182
  position: Järjetysnummero
181
183
  description: Kuvaus
182
184
  order:
185
+ total: Yhteensä
186
+ paid_on: Maksettu
187
+ shipped_on: Lähetetty
188
+ canceled_on: Peruttu
189
+ note: Muisti
183
190
  email: S-posti
184
191
  ordered_on: Tilattu
185
192
  product:
@@ -2,6 +2,7 @@ class Orders < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :orders do |t|
4
4
  t.string :number
5
+ t.string :note, :default => ""
5
6
  t.string :email
6
7
  t.date :ordered_on
7
8
  t.date :paid_on
data/lib/office_clerk.rb CHANGED
@@ -14,6 +14,7 @@ require "jquery-rails"
14
14
  require "gon"
15
15
  require "bcrypt"
16
16
  require "valid_email"
17
+ require "best_in_place"
17
18
  require "ransack"
18
19
 
19
20
  require "office_clerk/shipping_method"
@@ -1,3 +1,3 @@
1
1
  module OfficeClerk
2
- VERSION = "0.6"
2
+ VERSION = "0.7"
3
3
  end
data/office_clerk.gemspec CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_runtime_dependency 'gon'
34
34
  s.add_runtime_dependency 'jquery-ui-rails' , '~> 5.0'
35
35
  s.add_runtime_dependency "kramdown" , '~> 1.5'
36
+ s.add_runtime_dependency "best_in_place"
36
37
 
37
38
  s.add_runtime_dependency 'will_paginate-bootstrap' , '~> 1.0'
38
39
  s.add_runtime_dependency 'bootstrap-sass', '~> 3.1'
@@ -47,24 +47,6 @@ describe OrdersController do
47
47
  end
48
48
 
49
49
  describe "POST create" do
50
- describe "with valid params" do
51
- it "creates a new Order" do
52
- expect {
53
- post :create, {:order => attributes_for(:order)}, valid_session
54
- }.to change(Order, :count).by(1)
55
- end
56
-
57
- it "assigns a newly created order as @order" do
58
- post :create, {:order => attributes_for(:order)}, valid_session
59
- expect(assigns(:order)).to be_kind_of(Order)
60
- expect(assigns(:order)).to be_persisted
61
- end
62
-
63
- it "redirects to the created order" do
64
- post :create, {:order => attributes_for(:order)}, valid_session
65
- expect(response).to redirect_to(Order.first)
66
- end
67
- end
68
50
 
69
51
  describe "with invalid params" do
70
52
  it "assigns a newly created but unsaved order as @order" do
@@ -2,10 +2,10 @@
2
2
 
3
3
  FactoryGirl.define do
4
4
  factory :address do
5
- first_name "Torsten"
6
- last_name "Ruger"
7
- street1 "Fiskarsintie 513"
5
+ name "Torsten Ruger"
6
+ street "Fiskarsintie 513"
8
7
  city "10480 antskog"
9
8
  country "Suomi"
9
+ phone "0407308052"
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ FactoryGirl.define do
5
5
  product
6
6
  quantity 1
7
7
  price {product.price}
8
- tax 10
8
+ tax { product.tax }
9
9
  sequence( :name) { |n| "product #{n}" }
10
10
  factory :item_quantity do
11
11
  quantity 1
@@ -10,6 +10,11 @@ FactoryGirl.define do
10
10
  factory :order_paid do
11
11
  paid_on "2013-12-26"
12
12
  end
13
+ factory :order_shippped do
14
+ shipped_on "2013-12-26"
15
+ shipment_price 10.0
16
+ shipment_tax 20.0
17
+ end
13
18
  end
14
19
  end
15
20
  end
@@ -4,7 +4,8 @@ FactoryGirl.define do
4
4
  #minimal product
5
5
  factory :product do
6
6
  sequence( :name) { |n| "product #{n}" }
7
- sequence :price , 10
7
+ price 10
8
+ tax 10.0
8
9
  inventory 5
9
10
  factory :shop_product do
10
11
  online true
@@ -1,35 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Basket totals" do
4
+ let(:basket) { create :basket_2_items }
5
+
4
6
  it "creates proper quantities" do
5
7
  basket = create :basket_3_items
6
8
  end
7
-
8
- it "calculates tax for 2" do
9
- basket = create :basket_2_items
10
- expect(basket.items.length).to be 2
11
- taxes = basket.taxes
12
- expect(taxes.values.first.round(2)).to eq basket.total_tax.to_f.round(2)
13
- end
14
9
  it "updates total on add" do
15
- basket = create :basket_2_items
16
10
  items = basket.items
17
11
  total = items.first.price * items.first.quantity + items.last.price * items.last.quantity
18
12
  expect(basket.total_price).to eq total
19
13
  # assume the same tax (as per factory)
20
- expect(basket.total_tax.to_f).to eq total * items.first.tax / 100
14
+ tax = (total * basket.items.first.tax / ( 100.0 + basket.items.first.tax)).round(2)
15
+ expect(basket.total_tax.to_f).to eq tax
21
16
  end
22
17
  it "updates total on destroy" do
23
- basket = create :basket_2_items
24
18
  total = basket.items.first.price
25
- tax = total * basket.items.first.tax / 100
26
19
  basket.items.delete basket.items.last
27
20
  basket.save!
28
21
  expect(basket.total_price).to eq total
29
- expect(basket.total_tax.to_f).to eq tax.to_f
30
22
  end
31
23
  it "destroys" do
32
- basket = create :basket_2_items
33
24
  basket.items.delete basket.items.last
34
25
  basket.save!
35
26
  expect(basket.items.length).to be 1
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Basket totals" do
4
+ let(:basket) { create :basket_2_items }
5
+
6
+ it "calculates tax for 2" do
7
+ expect(basket.items.length).to be 2
8
+ taxes = basket.taxes
9
+ expect(taxes.values.first.round(2)).to eq basket.total_tax.to_f.round(2)
10
+ expect(taxes.values.length).to eq 1
11
+ end
12
+ it "calculates total tax right" do
13
+ expect(basket.items.first.product.price).to eq 10.0
14
+ expect(basket.items.first.product.tax).to eq 10.0
15
+ expect(basket.total_tax).to eq 2.73
16
+ end
17
+ it "calculates tax hash" do
18
+ expect(basket.taxes.length).to eq 1
19
+ expect(basket.taxes.keys.first).to eq 10.0
20
+ expect(basket.taxes.values.first).to eq 2.7273
21
+ end
22
+ end
@@ -14,8 +14,11 @@ describe Item do
14
14
  end
15
15
 
16
16
  it "calcualtes taxes" do
17
+ expect(create(:item).price).to eq 10.0
18
+ expect(create(:item).tax).to eq 10.0
19
+ expect(create(:item).tax_amount).to eq 0.9091
17
20
  [create(:item) , create(:item2) , create(:item22)].each do |c|
18
- expect(c.tax_amount).to eq ((c.tax * c.price*c.quantity) / 100.0).round(2)
21
+ expect(c.tax_amount).to eq ((c.price * c.tax / (100 + c.tax ) ) ).round(4) * c.quantity
19
22
  end
20
23
  end
21
24
  it "calcualtes total" do
@@ -1,6 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Order do
4
+ let(:order) { create :order }
5
+ let(:shipped_order) { create :order_shippped }
6
+
4
7
  it "factory is ok" do
5
8
  o = build :order
6
9
  ok = o.save
@@ -14,6 +17,26 @@ describe Order do
14
17
  end
15
18
 
16
19
  it "creates ok" do
17
- o1 = create :order
20
+ order
21
+ end
22
+
23
+ it "calculates total tax" do
24
+ expect(order.basket.items.length).to eq 1
25
+ expect(order.total_tax).to eq 0.91
26
+ end
27
+
28
+ it "calculates tax per rate" do
29
+ expect(order.taxes.length).to eq 1
30
+ expect(order.taxes.first).to eq [10.0 , 0.9091]
31
+ end
32
+
33
+ it "adds shipping tax to taxes" do
34
+ expect(shipped_order.taxes.length).to eq 2
35
+ expect(shipped_order.taxes.first).to eq [10.0 , 0.9091]
36
+ expect(shipped_order.taxes[20.0]).to eq 1.6667
37
+ end
38
+
39
+ it "calculates total tax with shipping" do
40
+ expect(shipped_order.total_tax).to eq 2.5767
18
41
  end
19
42
  end
@@ -3,6 +3,7 @@ class Orders < ActiveRecord::Migration
3
3
  def change
4
4
  create_table :orders do |t|
5
5
  t.string :number
6
+ t.string :note, :default => ""
6
7
  t.string :email
7
8
  t.date :ordered_on
8
9
  t.date :paid_on
@@ -70,6 +70,7 @@ ActiveRecord::Schema.define(version: 20141114205532) do
70
70
 
71
71
  create_table "orders", force: true do |t|
72
72
  t.string "number"
73
+ t.string "note", default: ""
73
74
  t.string "email"
74
75
  t.date "ordered_on"
75
76
  t.date "paid_on"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: office_clerk
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: '0.7'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Torsten Rüger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-05 00:00:00.000000000 Z
11
+ date: 2014-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -156,6 +156,20 @@ dependencies:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
158
  version: '1.5'
159
+ - !ruby/object:Gem::Dependency
160
+ name: best_in_place
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
159
173
  - !ruby/object:Gem::Dependency
160
174
  name: will_paginate-bootstrap
161
175
  requirement: !ruby/object:Gem::Requirement
@@ -373,6 +387,7 @@ files:
373
387
  - config/initializers/backtrace_silencers.rb
374
388
  - config/initializers/filter_parameter_logging.rb
375
389
  - config/initializers/inflections.rb
390
+ - config/initializers/migrate.rb
376
391
  - config/initializers/mime_types.rb
377
392
  - config/initializers/session_store.rb
378
393
  - config/initializers/wrap_parameters.rb
@@ -440,6 +455,7 @@ files:
440
455
  - spec/models/baskets/inventory_spec.rb
441
456
  - spec/models/baskets/items_spec.rb
442
457
  - spec/models/baskets/products_spec.rb
458
+ - spec/models/baskets/taxes_spec.rb
443
459
  - spec/models/category_spec.rb
444
460
  - spec/models/clerk/email_spec.rb
445
461
  - spec/models/clerk/password_spec.rb
@@ -569,6 +585,7 @@ test_files:
569
585
  - spec/models/baskets/inventory_spec.rb
570
586
  - spec/models/baskets/items_spec.rb
571
587
  - spec/models/baskets/products_spec.rb
588
+ - spec/models/baskets/taxes_spec.rb
572
589
  - spec/models/category_spec.rb
573
590
  - spec/models/clerk/email_spec.rb
574
591
  - spec/models/clerk/password_spec.rb