rawbotz 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -5
  3. data/Gemfile +2 -0
  4. data/README.md +60 -6
  5. data/Rakefile +3 -2
  6. data/agpl-3.0.txt +661 -0
  7. data/exe/bcrypt_pw +10 -0
  8. data/exe/rawbotz_abort_orders +28 -0
  9. data/exe/rawbotz_process_order_queue +12 -8
  10. data/exe/rawbotz_stock_update +10 -1
  11. data/exe/rawbotz_update_local_products +11 -3
  12. data/exe/rawbotz_update_remote_products +27 -4
  13. data/lib/rawbotz.rb +13 -5
  14. data/lib/rawbotz/app.rb +36 -2
  15. data/lib/rawbotz/cli/order_result_table.rb +13 -0
  16. data/lib/rawbotz/helpers/format_helper.rb +14 -0
  17. data/lib/rawbotz/helpers/icon_helper.rb +108 -22
  18. data/lib/rawbotz/helpers/order_item_color_helper.rb +17 -0
  19. data/lib/rawbotz/helpers/resource_link_helper.rb +3 -0
  20. data/lib/rawbotz/mail_template.rb +42 -7
  21. data/lib/rawbotz/models/sales.rb +21 -0
  22. data/lib/rawbotz/models/stock.rb +25 -0
  23. data/lib/rawbotz/models/stock_product.rb +146 -0
  24. data/lib/rawbotz/models/stock_product_factory.rb +64 -0
  25. data/lib/rawbotz/processors/order_linker.rb +50 -0
  26. data/lib/rawbotz/{order_processor.rb → processors/order_processor.rb} +14 -3
  27. data/lib/rawbotz/processors/organic_product_deliveries_csv.rb +47 -0
  28. data/lib/rawbotz/{product_updater.rb → processors/product_updater.rb} +71 -6
  29. data/lib/rawbotz/processors/stock_processor.rb +67 -0
  30. data/lib/rawbotz/public/rawbotz.css +35 -1
  31. data/lib/rawbotz/public/rawbotz.js +0 -1
  32. data/lib/rawbotz/remote_shop.rb +3 -0
  33. data/lib/rawbotz/routes.rb +3 -0
  34. data/lib/rawbotz/routes/non_remote_orders.rb +129 -29
  35. data/lib/rawbotz/routes/orders.rb +55 -4
  36. data/lib/rawbotz/routes/orders/stock.rb +75 -0
  37. data/lib/rawbotz/routes/product_links.rb +1 -1
  38. data/lib/rawbotz/routes/products.rb +19 -22
  39. data/lib/rawbotz/routes/remote_shop.rb +1 -1
  40. data/lib/rawbotz/routes/stock.rb +58 -0
  41. data/lib/rawbotz/routes/suppliers.rb +9 -4
  42. data/lib/rawbotz/sales_data.rb +13 -0
  43. data/lib/rawbotz/version.rb +1 -1
  44. data/lib/rawbotz/views/_hide_unhide_button.haml +1 -1
  45. data/lib/rawbotz/views/_menu.haml +9 -0
  46. data/lib/rawbotz/views/index.haml +1 -1
  47. data/lib/rawbotz/views/layout.haml +0 -1
  48. data/lib/rawbotz/views/order/_head.haml +64 -19
  49. data/lib/rawbotz/views/order/_item_table.haml +19 -3
  50. data/lib/rawbotz/views/order/_order_actions.haml +26 -0
  51. data/lib/rawbotz/views/order/link_to_remote.haml +30 -0
  52. data/lib/rawbotz/views/order/non_remote.haml +120 -26
  53. data/lib/rawbotz/views/order/packlist.haml +62 -5
  54. data/lib/rawbotz/views/order/packlist.pdf.haml +35 -0
  55. data/lib/rawbotz/views/order/stock.haml +116 -0
  56. data/lib/rawbotz/views/order/view.haml +41 -21
  57. data/lib/rawbotz/views/orders/_order_table.haml +82 -0
  58. data/lib/rawbotz/views/orders/index.haml +41 -28
  59. data/lib/rawbotz/views/orders/menu.haml +2 -2
  60. data/lib/rawbotz/views/orders/non_remotes.haml +14 -3
  61. data/lib/rawbotz/views/pdf_layout.haml +44 -0
  62. data/lib/rawbotz/views/product/view.haml +64 -11
  63. data/lib/rawbotz/views/products/index.haml +1 -1
  64. data/lib/rawbotz/views/products/table.haml +5 -1
  65. data/lib/rawbotz/views/remote_cart/index.haml +10 -0
  66. data/lib/rawbotz/views/remote_order/view.haml +6 -4
  67. data/lib/rawbotz/views/remote_orders/index.haml +16 -13
  68. data/lib/rawbotz/views/stock/index.haml +119 -0
  69. data/lib/rawbotz/views/stock/menu.haml +20 -0
  70. data/lib/rawbotz/views/stock_product/_value_table_line.haml +22 -0
  71. data/lib/rawbotz/views/stock_product/value_table.haml +28 -0
  72. data/lib/rawbotz/views/stockexplorer/stockexplorer.haml +157 -0
  73. data/lib/rawbotz/views/supplier/orders/table.haml +26 -0
  74. data/lib/rawbotz/views/supplier/view.haml +56 -10
  75. data/rawbotz.gemspec +13 -9
  76. metadata +86 -17
  77. data/lib/rawbotz/views/order/new.haml +0 -22
@@ -0,0 +1,47 @@
1
+ require 'csv'
2
+
3
+ module Rawbotz
4
+ class OrganicProductDeliveriesCSV
5
+ include RawgentoModels
6
+
7
+ def self.generate
8
+ CSV.generate do |csv|
9
+ csv << headings
10
+ Supplier.find_each do |supplier|
11
+ supplier_lines supplier, csv
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def self.headings
19
+ ["product", "qty stocked", "stock date", "order date", "order nr", "supplier"]
20
+ end
21
+
22
+ def self.supplier_lines supplier, csv
23
+ supplier.orders.find_each do |order|
24
+ if order.order_items.where("num_stocked > 0").present?
25
+ order_lines order, csv
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.order_lines order, csv
31
+ csv << ["Order #{order.remote_order_id} from #{order.supplier.name}"]
32
+ order.order_items.where("num_stocked > 0").each do |item|
33
+ csv << order_item_line(item)
34
+ end
35
+ end
36
+
37
+ def self.order_item_line item
38
+ [item.local_product.name,
39
+ item.num_stocked,
40
+ item.order.stocked_at,
41
+ item.order.ordered_at,
42
+ item.order.remote_order_id,
43
+ item.order.supplier.name]
44
+ end
45
+
46
+ end
47
+ end
@@ -4,7 +4,10 @@ module Rawbotz
4
4
  attr_accessor :logger
5
5
  attr_accessor :name_attribute_id, :supplier_attribute_id,
6
6
  :shelve_attribute_id, :packsize_attribute_id,
7
- :supplier_sku_attribute_id, :supplier_prod_name_attribute_id
7
+ :supplier_sku_attribute_id, :supplier_prod_name_attribute_id,
8
+ :order_info_attribute_id, :purchase_price_attribute_id,
9
+ :active_attribute_id, :organic_attribute_id
10
+ attr_accessor :change_text
8
11
 
9
12
  def initialize logger
10
13
  @local_products = {}
@@ -14,22 +17,31 @@ module Rawbotz
14
17
  @supplier_attribute_id = Rawbotz.attribute_ids["supplier_name"]
15
18
  @shelve_attribute_id = Rawbotz.attribute_ids["shelve_nr"]
16
19
  @packsize_attribute_id = Rawbotz.attribute_ids["packsize"]
20
+ @order_info_attribute_id = Rawbotz.attribute_ids["order_info"]
17
21
  @supplier_sku_attribute_id = Rawbotz.attribute_ids["supplier_sku"]
22
+ @purchase_price_attribute_id = Rawbotz.attribute_ids["purchase_price"]
18
23
  @supplier_prod_name_attribute_id = Rawbotz.attribute_ids["supplier_prod_name"]
24
+ @active_attribute_id = Rawbotz.attribute_ids["active_attribute_id"]
25
+ @organic_attribute_id = Rawbotz.attribute_ids["organic"]
19
26
  @logger.debug "Attribute-ids: Name: #{@name_attribute_id}, "\
20
27
  "Supplier: #{@supplier_attribute_id}, "\
21
28
  "Shelve-Nr: #{@shelve_attribute_id}, "\
22
29
  "Packsize: #{@packsize_attribute_id}"\
30
+ "Order Info: #{@order_info_attribute_id}"\
31
+ "Purchase Price: #{@purchase_price_attribute_id}"\
32
+ "Active: #{@active_attribute_id}"\
23
33
  "Supplier-SKU: #{@supplier_sku_attribute_id}"\
24
- "Supplier-Prod-Name: #{@supplier_prod_name_attribute_id}"
34
+ "Supplier-Prod-Name: #{@supplier_prod_name_attribute_id}"\
35
+ "Organic: #{@organic_attribute_id}"
25
36
  end
26
37
 
27
- def sync
38
+ def sync(dry_run=false)
28
39
  ensure_existence
29
40
 
30
41
  @logger.info "#{@local_products.count} products"
31
42
  # Name
32
- update_attribute(@name_attribute_id, :name)
43
+ #update_attribute(@name_attribute_id, :name)
44
+ update_names
33
45
  # Supplier
34
46
  update_supplier_from_option(@supplier_attribute_id)
35
47
  # Shelve
@@ -40,10 +52,22 @@ module Rawbotz
40
52
  update_attribute(@supplier_sku_attribute_id, :supplier_sku)
41
53
  # Supplier Product name
42
54
  update_attribute(@supplier_prod_name_attribute_id, :supplier_prod_name)
55
+ # Order Info
56
+ update_attribute(@order_info_attribute_id, :order_info)
57
+ # Purchase Price
58
+ update_attribute(@purchase_price_attribute_id, :purchase_price)
59
+ # Active?
60
+ update_attribute_int_bool(@active_attribute_id, :active)
61
+ # Organic?
62
+ update_attribute_int_bool(@organic_attribute_id, :organic)
63
+
64
+ unhide_if_reactivated
43
65
 
44
66
  log_changes
45
67
 
46
- save_changes
68
+ @change_text = changes
69
+
70
+ save_changes if !dry_run
47
71
  end
48
72
 
49
73
  private
@@ -60,11 +84,26 @@ module Rawbotz
60
84
  @logger.info "something changed"
61
85
  end
62
86
  if p.changed?
63
- @logger.info("Changes for #{p.product_id} (#{p.name}): #{p.changes}")
87
+ @logger.info(product_change_line p)
64
88
  end
65
89
  end
66
90
  end
67
91
 
92
+ def unhide_if_reactivated
93
+ @local_products.values.each do |p|
94
+ if p.changed? && p.active_was == false
95
+ p.hidden = false
96
+ end
97
+ end
98
+ end
99
+
100
+ def changes
101
+ local_changed_products = @local_products.values.select {|p| p.changed? }
102
+ changes_string = local_changed_products.map do |p|
103
+ product_change_line p
104
+ end.join("\n")
105
+ end
106
+
68
107
  def ensure_existence
69
108
  RawgentoDB::Query.products.each do |p|
70
109
  #@logger.info("Ensuring product #{p.product_id} exists")
@@ -73,6 +112,17 @@ module Rawbotz
73
112
  end
74
113
  end
75
114
 
115
+ # This works at least for magento 1.7, later versions might require
116
+ # attribute name update
117
+ def update_names
118
+ RawgentoDB::Query.product_names().each do |product_id, name|
119
+ p = @local_products[product_id]
120
+ if p
121
+ p.assign_attributes(name: name)
122
+ end
123
+ end
124
+ end
125
+
76
126
  # Fetches magento attribute and sets corresponding values
77
127
  def update_attribute attribute_id, attribute_sym, type=:varchar
78
128
  RawgentoDB::Query.attribute_varchar(attribute_id).each do |product_id, value|
@@ -86,6 +136,17 @@ module Rawbotz
86
136
  end
87
137
  end
88
138
 
139
+ # Fetches magento attribute and sets corresponding value with a weird bool mapping
140
+ def update_attribute_int_bool attribute_id, attribute_sym
141
+ # need to unhide re-activated products!
142
+ RawgentoDB::Query.attribute_int(attribute_id).each do |product_id, value|
143
+ p = @local_products[product_id]
144
+ if !value.nil? && value.to_s != ""
145
+ p.assign_attributes(attribute_sym => (value.to_i == 1))
146
+ end
147
+ end
148
+ end
149
+
89
150
  def update_supplier_from_option attribute_id
90
151
  RawgentoDB::Query.attribute_option(attribute_id).each do |product_id, value|
91
152
  p = @local_products[product_id]
@@ -94,5 +155,9 @@ module Rawbotz
94
155
  #logger.info "Updating supplier of #{product_id}: #{value}"
95
156
  end
96
157
  end
158
+
159
+ def product_change_line product
160
+ "Changes for #{product.product_id} (#{product.name}): #{product.changes}"
161
+ end
97
162
  end
98
163
  end
@@ -0,0 +1,67 @@
1
+ require 'date'
2
+
3
+ module Rawbotz
4
+ class StockProcessor
5
+ include RawgentoModels
6
+
7
+ attr_accessor :errors
8
+ attr_accessor :magento_shell_path
9
+
10
+ def initialize(order, params)
11
+ @order = order
12
+ @params = params
13
+ @errors = []
14
+ @magento_shell_path = YAML.load_file(Rawbotz.conf_file_path)["local_shop"]["magento_shell_path"]
15
+ end
16
+
17
+ # Add items to stock, setting them available if they were not before (and
18
+ # stock is positive).
19
+ #
20
+ # Returns and sets @error array which is empty if everything went smooth.
21
+ def process!
22
+ num_stocked = 0
23
+
24
+ @params.each do |param_name, param_value|
25
+ if param_name.to_s.start_with?("qty_delivered_") && param_value != ""
26
+ stock! param_name[14..-1], param_value
27
+ num_stocked += 1
28
+ end
29
+ end
30
+
31
+ if @order.order_items.processible.where("num_stocked IS NULL").count == 0
32
+ @order.update(state: 'stocked', stocked_at: DateTime.now)
33
+ else
34
+ @errors << "Not all items stocked"
35
+ end
36
+
37
+ if num_stocked > 0 && num_stocked >= @errors.length && !magento_shell_path.nil?
38
+ reindex_status = system("php #{@magento_shell_path} --reindex cataloginventory_stock")
39
+ if reindex_status.nil?
40
+ @errors << "Magento database reindexing failed"
41
+ end
42
+ end
43
+
44
+ @errors
45
+ end
46
+
47
+ private
48
+
49
+ def stock! order_item_id, qty
50
+ order_item = @order.order_items.find(order_item_id)
51
+ # This should be logged
52
+ return if order_item.blank? || order_item.stocked?
53
+
54
+ begin
55
+ RawgentoDB::Query.update_stock order_item.local_product.product_id, qty.to_i
56
+ RawgentoDB::Query.set_available_on_stock order_item.local_product.product_id
57
+ # Would be good to log that
58
+ order_item.update(num_stocked: qty.to_i, state: :stocked)
59
+ order_item.save
60
+ rescue Exception => e
61
+ STDERR.puts e.message.to_s
62
+ STDERR.puts e.backtrace
63
+ @errors << e.message
64
+ end
65
+ end
66
+ end
67
+ end
@@ -16,6 +16,10 @@ h3 {
16
16
  font-weight: 300;
17
17
  text-align: center;
18
18
  }
19
+ h4 {
20
+ font-weight: 300;
21
+ text-align: center;
22
+ }
19
23
  #menu {
20
24
  background-color: rgb(230,230,210);
21
25
  }
@@ -57,7 +61,7 @@ th {
57
61
  .float_ul li a {
58
62
  width: 10em;
59
63
  float: left;
60
- }
64
+ }
61
65
  .center {
62
66
  text-align: center;
63
67
  }
@@ -91,3 +95,33 @@ th {
91
95
  .wished_qty_input .order-none {
92
96
  display: table-cell;
93
97
  }
98
+ .pure-control-group .hint {
99
+ font-size: 80%;
100
+ color: grey;
101
+ display: inline-block;
102
+ }
103
+
104
+ .perfect_order {
105
+ background-color: #99ff99;
106
+ }
107
+ .out_of_stock {
108
+ background-color: #ffb3b3;
109
+ }
110
+ .partly_available {
111
+ background-color: #ffdd99;
112
+ }
113
+ #flash {
114
+ padding-left: 0.5em;
115
+ }
116
+ .pure-table > tbody > tr > td.left-bordered {
117
+ border-left: 2px solid;
118
+ }
119
+ .pure-table > thead > tr > th.left-bordered {
120
+ border-left: 2px solid;
121
+ }
122
+
123
+ .state-label {
124
+ border-radius: 4px;
125
+ background-color: #bbb;
126
+ padding: .5em 1em;
127
+ }
@@ -105,6 +105,5 @@ $(document).ready(function() {
105
105
  var num_wished = $(e.target).data('num_wished');
106
106
  $("#item_" + order_item_id).val(num_wished);
107
107
  });
108
-
109
108
  });
110
109
 
@@ -17,5 +17,8 @@ module Rawbotz
17
17
  # settings could be memoized
18
18
  "#{settings['remote_shop']['base_uri']}catalog/product/view/id/#{product.product_id}"
19
19
  end
20
+ def self.cart_page_url(settings)
21
+ "#{settings['remote_shop']['base_uri']}checkout/cart/"
22
+ end
20
23
  end
21
24
  end
@@ -4,6 +4,9 @@ module Rawbotz; module RawbotzApp ; module Routing ; end ; end ; end
4
4
  require 'rawbotz/routes/product_links'
5
5
  require 'rawbotz/routes/products'
6
6
  require 'rawbotz/routes/orders'
7
+ require 'rawbotz/routes/orders/stock'
7
8
  require 'rawbotz/routes/remote_shop'
9
+ require 'rawbotz/routes/stock'
8
10
  require 'rawbotz/routes/suppliers'
11
+ require 'rawbotz/routes/suppliers/orders'
9
12
  require 'rawbotz/routes/non_remote_orders'
@@ -1,4 +1,5 @@
1
1
  require 'rawbotz/routes'
2
+ require 'date'
2
3
 
3
4
  module Rawbotz::RawbotzApp::Routing::NonRemoteOrders
4
5
  include RawgentoModels
@@ -6,69 +7,168 @@ module Rawbotz::RawbotzApp::Routing::NonRemoteOrders
6
7
  def self.registered(app)
7
8
  # app.get '/orders/non_remote', &show_suppliers_orders
8
9
  show_suppliers_orders = lambda do
10
+ @suppliers = Supplier.order(:name)
9
11
  haml "orders/non_remotes".to_sym
10
12
  end
11
13
 
12
- # app.get '/order/non_remote/:supplier_id', &show_supplier_order
13
- show_supplier_order = lambda do
14
+ # app.get '/order/non_remote/:supplier_id/new', &create_supplier_order
15
+ create_supplier_order = lambda do
14
16
  @supplier = Supplier.find(params[:supplier_id])
15
17
  if @supplier.order_template.to_s == ""
16
18
  add_flash :warning, "You need to set the mailer template to order from this supplier"
17
- redirect "/supplier/#{@supplier.id}"
19
+ redirect "/supplier/#{@supplier.id}#tab_order_settings"
18
20
  else
21
+ @order = Order.create(state: :new, supplier: @supplier, order_method: @supplier.order_method)
19
22
  @products = LocalProduct.supplied_by(@supplier)
23
+ @stock = {}
24
+ begin
25
+ @monthly_sales = Rawbotz::SalesData.sales_since(Date.today - 31 * 4, @products)
26
+ RawgentoDB::Query.stock.each {|s| @stock[s.product_id] = s.qty}
27
+ rescue Exception => e
28
+ @monthly_sales = {}
29
+ add_flash :error, "Cannot connect to MySQL database (#{e.message})"
30
+ end
31
+
32
+ # Get the current stock value
33
+ @products.find_each do |product|
34
+ @order.order_items.create(local_product: product,
35
+ current_stock: @stock[product.product_id],
36
+ min_stock: nil)
37
+ end
20
38
 
39
+ @order.save
40
+ add_flash :success, "New Order created"
41
+
42
+ redirect "/order/non_remote/#{@order.id}".to_sym
43
+ end
44
+ end
45
+
46
+ # app.get '/order/non_remote/:order_id', &show_supplier_order
47
+ show_supplier_order = lambda do
48
+ @order = Order.find(params[:order_id])
49
+ @supplier = @order.supplier
50
+ if @supplier.order_template.to_s == ""
51
+ add_flash :warning, "You need to set the mailer template to order from this supplier"
52
+ redirect "/supplier/#{@supplier.id}#tab_order_settings"
53
+ else
54
+ @stock = {}
21
55
  begin
22
- db = RawgentoDB::Query
23
- @monthly_sales = @products.map{|p| [p.product_id,
24
- db.sales_monthly_between(p.product_id,
25
- Date.today,
26
- Date.today - 31 * 4)]}.to_h
27
- @monthly_sales.each{|k,v| @monthly_sales[k] = v.inject(0){|a,s| a + s[1].to_i}/v.length rescue 0}
28
- @stock = {}
29
- db.stock.each {|s| @stock[s.product_id] = s.qty}
56
+ @products = @order.order_items.map{|oi| oi.local_product}
57
+ @monthly_sales = Rawbotz::SalesData.sales_since(Date.today - 31 * 4, @products)
58
+ RawgentoDB::Query.stock.each {|s| @stock[s.product_id] = s.qty}
30
59
  rescue Exception => e
31
60
  @monthly_sales = {}
32
- @stock = {}
33
61
  add_flash :error, "Cannot connect to MySQL database (#{e.message})"
34
62
  end
63
+ @mail_preview_subject = Rawbotz::MailTemplate.extract_subject(
64
+ @supplier.order_template, @order)
65
+ @mail_preview_text = Rawbotz::MailTemplate.consume(
66
+ @supplier.order_template, @order)
67
+ @mailto_url = Rawbotz::MailTemplate.create_mailto_url(
68
+ @supplier, @order)
35
69
  haml "order/non_remote".to_sym
36
70
  end
37
71
  end
38
72
 
39
- # app.post '/order/non_remote/:supplier_id', &show_supplier_order_preview
73
+ # app.post '/order/non_remote/:order_id', &show_supplier_order_preview
40
74
  show_supplier_order_preview = lambda do
41
75
  @supplier = Supplier.find(params[:supplier_id])
42
76
  @products = @supplier.local_products
77
+ @order = Order.find(params[:order_id])
78
+ @stock = {}
79
+
80
+ # Certain orders should not be changed
81
+ if @order.state != 'new'
82
+ add_flash :error, "Orders in state #{@order.state} cannot be changed!"
83
+ redirect "order/non_remote/#{@order.id}"
84
+ end
43
85
 
44
86
  begin
45
- db = RawgentoDB::Query
46
- @monthly_sales = @products.map{|p| [p.product_id,
47
- db.sales_monthly_between(p.product_id,
48
- Date.today,
49
- Date.today - 31 * 4)]}.to_h
50
- # this is not avg
51
- @monthly_sales.each{|k,v| @monthly_sales[k] = v.inject(0){|a,s| a + s[1].to_i}/v.length rescue 0}
52
- @stock = {}
53
- db.stock.each {|s| @stock[s.product_id] = s.qty}
87
+ @monthly_sales = Rawbotz::SalesData.sales_since(Date.today - 31 * 4, @products)
88
+ RawgentoDB::Query.stock.each {|s| @stock[s.product_id] = s.qty}
54
89
  rescue Exception => e
55
- @stock = {}
90
+ @monthly_sales = {}
91
+ add_flash :error, "Cannot connect to MySQL database (#{e.message})"
56
92
  end
57
93
 
58
- order = {supplier: @supplier, order_items: []}
59
94
  params.select{|p| p.start_with?("item_")}.each do |p, val|
95
+ # why > 0 ?
60
96
  if val && val.to_i > 0
61
97
  qty = val.to_i
62
- product = LocalProduct.find(p[5..-1])
63
- order[:order_items] << {num_wished: qty, local_product: product}
98
+ oi = @order.order_items.where(local_product_id: p[5..-1]).first_or_create
99
+ oi.update(num_wished: qty)
100
+ end
101
+ end
102
+ @order.public_comment = params[:public_comment]
103
+ @order.internal_comment = params[:internal_comment]
104
+
105
+ @mail_preview_subject = Rawbotz::MailTemplate.extract_subject(
106
+ @supplier.order_template, @order)
107
+ @mail_preview_text = Rawbotz::MailTemplate.consume(
108
+ @supplier.order_template, @order)
109
+ @mailto_url = Rawbotz::MailTemplate.create_mailto_url(
110
+ @supplier, @order)
111
+
112
+ @order.order_result = @mail_preview_text
113
+ @order.ordered_at = DateTime.now
114
+ @order.save
115
+ if params['action'] == 'fix'
116
+ @order.order_items.find_each do |oi|
117
+ oi.num_ordered = oi.num_wished
118
+ oi.current_stock = @stock[oi.local_product.product_id]
119
+ oi.save
64
120
  end
121
+ @order.update(state: :mailed)
122
+ add_flash :success, "Order marked as mailed"
123
+ redirect '/orders'
124
+ elsif params['action'] == "delete"
125
+ @order.update(state: :deleted)
126
+ add_flash :success, 'Order marked deleted'
127
+ redirect '/orders'
128
+ else
129
+ add_flash :success, "Order saved"
65
130
  end
66
- @mail_preview = Rawbotz::MailTemplate.consume @supplier.order_template, order
131
+
67
132
  haml "order/non_remote".to_sym
68
133
  end
69
134
 
135
+ # app.get '/stockexplorer/:supplier_id', &show_stock_explorer
136
+ show_stock_explorer = lambda do
137
+ @supplier = Supplier.find(params[:supplier_id])
138
+ @stock = {}
139
+ #begin
140
+ #@monthly_sales = Rawbotz::SalesData.sales_since(Date.today - 31 * 4, @products)
141
+ RawgentoDB::Query.stock.each {|s| @stock[s.product_id] = s.qty}
142
+ #rescue Exception => e
143
+ # @monthly_sales = {}
144
+ # add_flash :error, "Cannot connect to MySQL database (#{e.message})"
145
+ #end
146
+
147
+ #-> db query num_sales_since
148
+ days_ago_30 = Date.today - 30
149
+ days_ago_60 = Date.today - 60
150
+ days_ago_90 = Date.today - 90
151
+ days_ago_356 = Date.today - 356
152
+
153
+ # TODO 30 90 356
154
+ product_ids = @supplier.local_products.map &:product_id
155
+ @sales_30 = RawgentoDB::Query.num_sales_since(days_ago_30, product_ids)
156
+ @sales_60 = RawgentoDB::Query.num_sales_since(days_ago_60, product_ids)
157
+ @sales_90 = RawgentoDB::Query.num_sales_since(days_ago_90, product_ids)
158
+ @sales_356 = RawgentoDB::Query.num_sales_since(days_ago_356, product_ids)
159
+
160
+ @out_of_stock_days_30 = @supplier.local_products.map{|l| [l.product_id, l.stock_items.where("qty <= ? AND date >= ?", 0, days_ago_30).count]}.to_h
161
+ @out_of_stock_days_60 = @supplier.local_products.map{|l| [l.product_id, l.stock_items.where("qty <= ? AND date >= ?", 0, days_ago_60).count]}.to_h
162
+ @out_of_stock_days_90 = @supplier.local_products.map{|l| [l.product_id, l.stock_items.where("qty <= ? AND date >= ?", 0, days_ago_90).count]}.to_h
163
+ @out_of_stock_days_356 = @supplier.local_products.map{|l| [l.product_id, l.stock_items.where("qty <= ? AND date >= ?", 0, days_ago_356).count]}.to_h
164
+ haml 'stockexplorer/stockexplorer'.to_sym, layout: !request.xhr?
165
+ end
166
+
167
+ # routes
70
168
  app.get '/orders/non_remote', &show_suppliers_orders
71
- app.get '/order/non_remote/:supplier_id', &show_supplier_order
72
- app.post '/order/non_remote/:supplier_id', &show_supplier_order_preview
169
+ app.get '/order/non_remote/:order_id', &show_supplier_order
170
+ app.post '/order/non_remote/:order_id', &show_supplier_order_preview
171
+ app.get '/order/non_remote/:supplier_id/new', &create_supplier_order
172
+ app.get '/stockexplorer/:supplier_id', &show_stock_explorer
73
173
  end
74
174
  end