rawbotz 0.1.5 → 0.2.0

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