rawbotz 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -5
- data/Gemfile +2 -0
- data/README.md +60 -6
- data/Rakefile +3 -2
- data/agpl-3.0.txt +661 -0
- data/exe/bcrypt_pw +10 -0
- data/exe/rawbotz_abort_orders +28 -0
- data/exe/rawbotz_process_order_queue +12 -8
- data/exe/rawbotz_stock_update +10 -1
- data/exe/rawbotz_update_local_products +11 -3
- data/exe/rawbotz_update_remote_products +27 -4
- data/lib/rawbotz.rb +13 -5
- data/lib/rawbotz/app.rb +36 -2
- data/lib/rawbotz/cli/order_result_table.rb +13 -0
- data/lib/rawbotz/helpers/format_helper.rb +14 -0
- data/lib/rawbotz/helpers/icon_helper.rb +108 -22
- data/lib/rawbotz/helpers/order_item_color_helper.rb +17 -0
- data/lib/rawbotz/helpers/resource_link_helper.rb +3 -0
- data/lib/rawbotz/mail_template.rb +42 -7
- data/lib/rawbotz/models/sales.rb +21 -0
- data/lib/rawbotz/models/stock.rb +25 -0
- data/lib/rawbotz/models/stock_product.rb +146 -0
- data/lib/rawbotz/models/stock_product_factory.rb +64 -0
- data/lib/rawbotz/processors/order_linker.rb +50 -0
- data/lib/rawbotz/{order_processor.rb → processors/order_processor.rb} +14 -3
- data/lib/rawbotz/processors/organic_product_deliveries_csv.rb +47 -0
- data/lib/rawbotz/{product_updater.rb → processors/product_updater.rb} +71 -6
- data/lib/rawbotz/processors/stock_processor.rb +67 -0
- data/lib/rawbotz/public/rawbotz.css +35 -1
- data/lib/rawbotz/public/rawbotz.js +0 -1
- data/lib/rawbotz/remote_shop.rb +3 -0
- data/lib/rawbotz/routes.rb +3 -0
- data/lib/rawbotz/routes/non_remote_orders.rb +129 -29
- data/lib/rawbotz/routes/orders.rb +55 -4
- data/lib/rawbotz/routes/orders/stock.rb +75 -0
- data/lib/rawbotz/routes/product_links.rb +1 -1
- data/lib/rawbotz/routes/products.rb +19 -22
- data/lib/rawbotz/routes/remote_shop.rb +1 -1
- data/lib/rawbotz/routes/stock.rb +58 -0
- data/lib/rawbotz/routes/suppliers.rb +9 -4
- data/lib/rawbotz/sales_data.rb +13 -0
- data/lib/rawbotz/version.rb +1 -1
- data/lib/rawbotz/views/_hide_unhide_button.haml +1 -1
- data/lib/rawbotz/views/_menu.haml +9 -0
- data/lib/rawbotz/views/index.haml +1 -1
- data/lib/rawbotz/views/layout.haml +0 -1
- data/lib/rawbotz/views/order/_head.haml +64 -19
- data/lib/rawbotz/views/order/_item_table.haml +19 -3
- data/lib/rawbotz/views/order/_order_actions.haml +26 -0
- data/lib/rawbotz/views/order/link_to_remote.haml +30 -0
- data/lib/rawbotz/views/order/non_remote.haml +120 -26
- data/lib/rawbotz/views/order/packlist.haml +62 -5
- data/lib/rawbotz/views/order/packlist.pdf.haml +35 -0
- data/lib/rawbotz/views/order/stock.haml +116 -0
- data/lib/rawbotz/views/order/view.haml +41 -21
- data/lib/rawbotz/views/orders/_order_table.haml +82 -0
- data/lib/rawbotz/views/orders/index.haml +41 -28
- data/lib/rawbotz/views/orders/menu.haml +2 -2
- data/lib/rawbotz/views/orders/non_remotes.haml +14 -3
- data/lib/rawbotz/views/pdf_layout.haml +44 -0
- data/lib/rawbotz/views/product/view.haml +64 -11
- data/lib/rawbotz/views/products/index.haml +1 -1
- data/lib/rawbotz/views/products/table.haml +5 -1
- data/lib/rawbotz/views/remote_cart/index.haml +10 -0
- data/lib/rawbotz/views/remote_order/view.haml +6 -4
- data/lib/rawbotz/views/remote_orders/index.haml +16 -13
- data/lib/rawbotz/views/stock/index.haml +119 -0
- data/lib/rawbotz/views/stock/menu.haml +20 -0
- data/lib/rawbotz/views/stock_product/_value_table_line.haml +22 -0
- data/lib/rawbotz/views/stock_product/value_table.haml +28 -0
- data/lib/rawbotz/views/stockexplorer/stockexplorer.haml +157 -0
- data/lib/rawbotz/views/supplier/orders/table.haml +26 -0
- data/lib/rawbotz/views/supplier/view.haml +56 -10
- data/rawbotz.gemspec +13 -9
- metadata +86 -17
- 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
|
-
|
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(
|
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
|
+
}
|
data/lib/rawbotz/remote_shop.rb
CHANGED
data/lib/rawbotz/routes.rb
CHANGED
@@ -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', &
|
13
|
-
|
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
|
-
|
23
|
-
@monthly_sales =
|
24
|
-
|
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/:
|
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
|
-
|
46
|
-
|
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
|
-
@
|
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
|
-
|
63
|
-
|
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
|
-
|
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/:
|
72
|
-
app.post '/order/non_remote/:
|
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
|