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.
- 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,17 @@
|
|
1
|
+
module Rawbotz
|
2
|
+
module Helpers
|
3
|
+
module OrderItemColorHelper
|
4
|
+
def order_item_class order_item
|
5
|
+
if order_item.ordered? && order_item.all_ordered?
|
6
|
+
"perfect_order"
|
7
|
+
elsif order_item.out_of_stock?
|
8
|
+
"out_of_stock"
|
9
|
+
elsif order_item.not_ordered?
|
10
|
+
"not_ordered"
|
11
|
+
else
|
12
|
+
"partly_available"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -3,27 +3,62 @@ module Rawbotz
|
|
3
3
|
# Substitute certain patterns in template
|
4
4
|
def self.consume template, order
|
5
5
|
result = ""
|
6
|
-
result = template.gsub(/SUPPLIERNAME/, order
|
6
|
+
result = template.gsub(/SUPPLIERNAME/, order.supplier[:name])
|
7
|
+
result = result.gsub(/PUBLIC_COMMENT/, order.public_comment || "")
|
7
8
|
|
8
9
|
lines = result.split("\n")
|
9
10
|
subject, lines = lines.partition{|l| l.start_with?("SUBJECT=")}
|
10
11
|
product_line = lines.detect{|l| l.start_with?("* ")}
|
11
|
-
order_lines = order
|
12
|
+
order_lines = order.order_items.select{|o|o.num_wished.to_i != 0}.map do |oi|
|
12
13
|
next if product_line.nil?
|
13
14
|
order_item_line = product_line[2..-1]
|
14
|
-
order_item_line.gsub!(/SUPPLIERSKU/, oi
|
15
|
+
order_item_line.gsub!(/SUPPLIERSKU/, oi.local_product[:supplier_sku].to_s)
|
15
16
|
order_item_line.gsub!(/QTY/, oi[:num_wished].to_s)
|
16
|
-
if oi
|
17
|
-
order_item_line.gsub!(/NUM_PACKS/, (oi[:num_wished] / oi
|
17
|
+
if oi.local_product[:packsize].to_s != ""
|
18
|
+
order_item_line.gsub!(/NUM_PACKS/, "%g" % (oi[:num_wished] / oi.local_product[:packsize].to_f))
|
18
19
|
else
|
19
20
|
order_item_line.gsub!(/NUM_PACKS/, '')
|
20
21
|
end
|
21
|
-
order_item_line.gsub!(/PACKSIZE/, oi
|
22
|
-
|
22
|
+
order_item_line.gsub!(/PACKSIZE/, oi.local_product[:packsize].to_s)
|
23
|
+
if oi.local_product[:supplier_prod_name].to_s != ""
|
24
|
+
order_item_line.gsub!(/PRODUCTNAME/, oi.local_product[:supplier_prod_name])
|
25
|
+
else
|
26
|
+
order_item_line.gsub!(/PRODUCTNAME/, oi.local_product[:name].to_s)
|
27
|
+
end
|
23
28
|
order_item_line
|
29
|
+
#SUPPLIERSKU
|
30
|
+
#SUPPLIERPRODUCTNAME
|
24
31
|
end
|
25
32
|
lines[lines.find_index(product_line)] = order_lines if product_line
|
26
33
|
lines.flatten.join("\n")
|
27
34
|
end
|
35
|
+
|
36
|
+
def self.extract_subject template, order
|
37
|
+
result = ""
|
38
|
+
result = template.gsub(/SUPPLIERNAME/, order.supplier[:name])
|
39
|
+
|
40
|
+
lines = result.split("\n")
|
41
|
+
subject, lines = lines.partition{|l| l.start_with?("SUBJECT=")}
|
42
|
+
if !subject.empty?
|
43
|
+
subject[0][8..-1]
|
44
|
+
else
|
45
|
+
"Order"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.create_mailto_url supplier, order
|
50
|
+
mail_preview = self.consume supplier[:order_template], order
|
51
|
+
subject = self.extract_subject supplier[:order_template], order
|
52
|
+
to_mail = (supplier[:email] || "").split[0]
|
53
|
+
if supplier[:email].to_s == ""
|
54
|
+
cc_mail = ""
|
55
|
+
else
|
56
|
+
cc_mail = supplier[:email].split[1..-1].map{|m| "cc=#{m}"}.join("&")
|
57
|
+
end
|
58
|
+
if cc_mail.to_s != ""
|
59
|
+
cc_mail += "&"
|
60
|
+
end
|
61
|
+
"mailto:#{to_mail}?#{cc_mail}Subject=#{subject}&body=%s" % URI::escape(mail_preview).gsub(/&/,'%26')
|
62
|
+
end
|
28
63
|
end
|
29
64
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Rawbotz
|
5
|
+
module Models
|
6
|
+
class Sales
|
7
|
+
include ActiveModel::Model # convenience
|
8
|
+
|
9
|
+
def self.daily_since product_id, num_days=30
|
10
|
+
RawgentoDB::Query.sales_daily_between(product_id,
|
11
|
+
Date.today, Date.today - num_days)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.monthly_since product_id, num_months=12
|
15
|
+
# Todo create a date num_month month ago (vs x*30)
|
16
|
+
RawgentoDB::Query.sales_monthly_between(product_id,
|
17
|
+
Date.today, Date.today - (num_months * 30)).uniq
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Rawbotz
|
4
|
+
module Models
|
5
|
+
class Stock
|
6
|
+
include ActiveModel::Model # convenience
|
7
|
+
|
8
|
+
def self.all_stock
|
9
|
+
stock = {}
|
10
|
+
RawgentoDB::Query.stock.each {|s| stock[s.product_id] = s.qty}
|
11
|
+
stock
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a map of product_id to RawgentoDB::ProductQty .
|
15
|
+
def self.stock_for product_ids
|
16
|
+
stock = {}
|
17
|
+
# Find ruby idiomatic way to do that (probably map{}.to_h)
|
18
|
+
RawgentoDB::Query.stock_for(product_ids).each do |s|
|
19
|
+
stock[s.product_id] = s.qty
|
20
|
+
end
|
21
|
+
stock
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Rawbotz
|
4
|
+
module Models
|
5
|
+
class UnsupportedNumberOfDaysError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class StockProduct
|
9
|
+
include ActiveModel::Model # convenience
|
10
|
+
|
11
|
+
attr_accessor :product, :current_stock,
|
12
|
+
:sales_last_30, :sales_last_60, :sales_last_90, :sales_last_365,
|
13
|
+
:num_days_first_sale, :mem_corrected_sales
|
14
|
+
|
15
|
+
delegate :name, to: :product
|
16
|
+
|
17
|
+
def expected_stock_lifetime
|
18
|
+
if @current_stock.to_i == 0 || sales_per_day.nil? || sales_per_day == 0.0
|
19
|
+
return 0.0
|
20
|
+
end
|
21
|
+
@current_stock / sales_per_day
|
22
|
+
end
|
23
|
+
|
24
|
+
def real_sales num_days
|
25
|
+
if num_days == 30
|
26
|
+
@sales_last_30
|
27
|
+
elsif num_days == 60
|
28
|
+
@sales_last_60
|
29
|
+
elsif num_days == 90
|
30
|
+
@sales_last_90
|
31
|
+
elsif num_days == 365
|
32
|
+
@sales_last_365
|
33
|
+
else
|
34
|
+
raise UnsupportedNumberOfDaysError
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def corrected_sales num_days, per_days: num_days
|
39
|
+
factor = num_days.to_f / per_days
|
40
|
+
sales = nil
|
41
|
+
if num_days == 30
|
42
|
+
sales = corrected_sales_last_30
|
43
|
+
elsif num_days == 60
|
44
|
+
sales = corrected_sales_last_60
|
45
|
+
elsif num_days == 90
|
46
|
+
sales = corrected_sales_last_90
|
47
|
+
elsif num_days == 365
|
48
|
+
sales = corrected_sales_last_365
|
49
|
+
else
|
50
|
+
raise UnsupportedNumberOfDaysError
|
51
|
+
end
|
52
|
+
return nil if sales.nil?
|
53
|
+
sales / factor
|
54
|
+
end
|
55
|
+
|
56
|
+
# We should also extrapolate (out of-) stock days!
|
57
|
+
|
58
|
+
def corrected_sales_last_30
|
59
|
+
@mem_corrected_sales ||= {}
|
60
|
+
@mem_corrected_sales[30] ||= calculate_corrected_sales(30)
|
61
|
+
end
|
62
|
+
|
63
|
+
def corrected_sales_last_60
|
64
|
+
@mem_corrected_sales ||= {}
|
65
|
+
@mem_corrected_sales[60] ||= calculate_corrected_sales(60)
|
66
|
+
end
|
67
|
+
|
68
|
+
def corrected_sales_last_90
|
69
|
+
@mem_corrected_sales ||= {}
|
70
|
+
@mem_corrected_sales[90] ||= calculate_corrected_sales(90)
|
71
|
+
end
|
72
|
+
|
73
|
+
def corrected_sales_last_365
|
74
|
+
@mem_corrected_sales ||= {}
|
75
|
+
@mem_corrected_sales[365] ||= calculate_corrected_sales(365)
|
76
|
+
end
|
77
|
+
|
78
|
+
def days_since_first_stock_date
|
79
|
+
#@mem_days_since_first_stock_date ||=
|
80
|
+
return 0 if !@product.first_stock_record.present?
|
81
|
+
first_stock_date = @product.first_stock_record.created_at.to_date
|
82
|
+
Date.today - first_stock_date
|
83
|
+
end
|
84
|
+
|
85
|
+
def out_of_stock_days num_days
|
86
|
+
@product.out_of_stock_days_since(Date.today - num_days)
|
87
|
+
end
|
88
|
+
|
89
|
+
def sales_per_day
|
90
|
+
case sales_per_day_base
|
91
|
+
when 365
|
92
|
+
@sales_last_365 / days_in_stock(365).to_f
|
93
|
+
when 90
|
94
|
+
@sales_last_90 / days_in_stock(90).to_f
|
95
|
+
when 60
|
96
|
+
@sales_last_60 / days_in_stock(60).to_f
|
97
|
+
when 30
|
98
|
+
return nil if @sales_last_30.nil?
|
99
|
+
return nil if days_in_stock(30).to_i == 0
|
100
|
+
@sales_last_30 / days_in_stock(30).to_f
|
101
|
+
else
|
102
|
+
raise UnsupportedNumberOfDaysError
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def sales_per_day_base
|
107
|
+
product_days_first_stock = @product.days_since_first_stock
|
108
|
+
#first saleproduct_days_first_stock = @product.days_since_first_stock
|
109
|
+
if @sales_last_365.present? && product_days_first_stock >= 365 && num_days_first_sale >= 365 && days_in_stock(365) != 0
|
110
|
+
return 365
|
111
|
+
elsif @sales_last_90.present? && product_days_first_stock >= 90 && num_days_first_sale >= 90 && days_in_stock(90) != 0
|
112
|
+
return 90
|
113
|
+
elsif @sales_last_60.present? && product_days_first_stock >= 60 && num_days_first_sale >= 60 && days_in_stock(60) != 0
|
114
|
+
return 60
|
115
|
+
#elsif @sales_last_30.present?
|
116
|
+
else
|
117
|
+
# today - last sale ?
|
118
|
+
return 30
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# For easier memoization
|
125
|
+
def calculate_corrected_sales num_days
|
126
|
+
return nil if days_in_stock(num_days).to_i == 0
|
127
|
+
return nil if real_sales(num_days).nil?
|
128
|
+
if days_in_stock(num_days).to_i != 0
|
129
|
+
real_sales(num_days) * factor_days_in_stock(num_days)
|
130
|
+
else
|
131
|
+
0
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# From the last num_days, how many days was the product in stock?
|
136
|
+
def days_in_stock num_days
|
137
|
+
num_days - out_of_stock_days(num_days)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Factor to extrapolate sales, e.g. 1/2 of time out of stock makes factor 2.0
|
141
|
+
def factor_days_in_stock num_days
|
142
|
+
num_days.to_f / days_in_stock(num_days)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Rawbotz
|
2
|
+
module Models
|
3
|
+
module StockProductFactory
|
4
|
+
include RawgentoModels
|
5
|
+
include RawgentoDB
|
6
|
+
|
7
|
+
def self.create_single product
|
8
|
+
product_id = product.product_id
|
9
|
+
sales_30 = Query.num_sales_since(Date.today - 30, product_id)
|
10
|
+
sales_60 = Query.num_sales_since(Date.today - 60, product_id)
|
11
|
+
sales_90 = Query.num_sales_since(Date.today - 90, product_id)
|
12
|
+
sales_365 = Query.num_sales_since(Date.today - 365, product_id)
|
13
|
+
|
14
|
+
beginning_of_time = StockItem.order(created_at: :asc).pluck(:created_at).first.to_date
|
15
|
+
|
16
|
+
sales = Query.num_sales_since(beginning_of_time, product_id)
|
17
|
+
first_sales = Query.first_sales(product_id)
|
18
|
+
# Default to today instead of nil date
|
19
|
+
first_sales.default = Date.today
|
20
|
+
|
21
|
+
# stock product has trouble when empty values ...
|
22
|
+
stock = Query.stock.find {|s| s.product_id = product_id}.qty
|
23
|
+
StockProduct.new(product: LocalProduct.unscoped.find_by(product_id: product_id),
|
24
|
+
current_stock: stock[product_id],
|
25
|
+
sales_last_30: sales_30[product_id]&.qty ,
|
26
|
+
sales_last_60: sales_60[product_id]&.qty ,
|
27
|
+
sales_last_90: sales_90[product_id]&.qty ,
|
28
|
+
sales_last_365: sales_365[product_id]&.qty ,
|
29
|
+
num_days_first_sale: Date.today - first_sales[product_id].to_date
|
30
|
+
)
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create suppliers
|
35
|
+
product_ids = LocalProduct.unscoped.where(supplier_id: suppliers.map(&:id), active: true).pluck(:product_id)
|
36
|
+
|
37
|
+
sales_30 = Query.num_sales_since(Date.today - 30, product_ids)
|
38
|
+
sales_60 = Query.num_sales_since(Date.today - 60, product_ids)
|
39
|
+
sales_90 = Query.num_sales_since(Date.today - 90, product_ids)
|
40
|
+
sales_365 = Query.num_sales_since(Date.today - 365, product_ids)
|
41
|
+
|
42
|
+
beginning_of_time = StockItem.order(created_at: :asc).first.created_at.to_date
|
43
|
+
|
44
|
+
sales = Query.num_sales_since(beginning_of_time, product_ids)
|
45
|
+
first_sales = Query.first_sales(product_ids)
|
46
|
+
# Default to today instead of nil date
|
47
|
+
first_sales.default = Date.today
|
48
|
+
stock = {}
|
49
|
+
|
50
|
+
Query.stock.each {|s| stock[s.product_id] = s.qty}
|
51
|
+
product_ids.map do |product_id|
|
52
|
+
StockProduct.new(product: LocalProduct.unscoped.find_by(product_id: product_id),
|
53
|
+
current_stock: stock[product_id],
|
54
|
+
sales_last_30: sales_30[product_id]&.qty,
|
55
|
+
sales_last_60: sales_60[product_id]&.qty,
|
56
|
+
sales_last_90: sales_90[product_id]&.qty,
|
57
|
+
sales_last_365: sales_365[product_id]&.qty,
|
58
|
+
num_days_first_sale: Date.today - first_sales[product_id].to_date
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Rawbotz
|
2
|
+
class OrderLinker
|
3
|
+
include RawgentoModels
|
4
|
+
|
5
|
+
OrderItemLine = Struct.new(:remote_product_name,
|
6
|
+
:qty_ordered,
|
7
|
+
:qty_refunded)
|
8
|
+
OrderItemRecord = Struct.new(:order_item,
|
9
|
+
:qty_ordered,
|
10
|
+
:qty_refunded)
|
11
|
+
|
12
|
+
attr_accessor :order, :orphans, :refunds
|
13
|
+
|
14
|
+
def initialize(order)
|
15
|
+
@order = order
|
16
|
+
end
|
17
|
+
|
18
|
+
# Links a local rawbotz order to a remote (magento) order.
|
19
|
+
#
|
20
|
+
# Set @orphans (remote order items that do not directly match,
|
21
|
+
# @refunds (maps not only refunded order_item to OrderItemLine)
|
22
|
+
# and @matched_order_items
|
23
|
+
def link!
|
24
|
+
# My, thats a hairy regex
|
25
|
+
shop_order_id = @order.remote_order_link[/\d+/]
|
26
|
+
@remote_order_lines = Rawbotz.mech.products_from_order(shop_order_id).map do |line|
|
27
|
+
OrderItemLine.new(line[0],
|
28
|
+
line[2],
|
29
|
+
line[3])
|
30
|
+
end
|
31
|
+
matches, orphans = @remote_order_lines.partition{|line| !order_item(line).nil?}
|
32
|
+
@matched_order_items = matches.map{|line| order_item line}
|
33
|
+
@orphans = orphans
|
34
|
+
@refunds = @matched_order_items.map do |oi|
|
35
|
+
[oi, @remote_order_lines.find{|l| l.remote_product_name == oi.local_product.remote_product.name}]
|
36
|
+
end.to_h
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
# Get the order item of the order, or nil.
|
41
|
+
def order_item order_item_line
|
42
|
+
remote_product = RemoteProduct.find_by name: order_item_line.remote_product_name
|
43
|
+
return nil if remote_product.blank?
|
44
|
+
return nil if remote_product.local_product.blank?
|
45
|
+
|
46
|
+
@order.order_items.processible.where(local_product: remote_product.local_product).first
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -1,8 +1,12 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
1
3
|
module Rawbotz
|
2
4
|
class OrderProcessor
|
3
5
|
def initialize(order, logger=Logger.new("/dev/null"))
|
4
6
|
@order = order
|
5
7
|
@logger = logger
|
8
|
+
@form_token = YAML::load_file(
|
9
|
+
Rawbotz::conf_file_path)["remote_shop"]["form_token"]
|
6
10
|
end
|
7
11
|
|
8
12
|
# Yield items, if block given
|
@@ -15,8 +19,10 @@ module Rawbotz
|
|
15
19
|
log_product_handling item
|
16
20
|
|
17
21
|
begin
|
18
|
-
ordered_qty = mech.add_to_cart! item.remote_product_id, item.num_wished
|
19
|
-
rescue
|
22
|
+
ordered_qty = mech.add_to_cart! item.remote_product_id, item.num_wished, @form_token
|
23
|
+
rescue Exception => e
|
24
|
+
STDERR.puts e.message.to_s
|
25
|
+
STDERR.puts e.backtrace
|
20
26
|
ordered_qty = nil
|
21
27
|
item.update(state: "error")
|
22
28
|
end
|
@@ -31,11 +37,12 @@ module Rawbotz
|
|
31
37
|
@logger.warn(item.attributes)
|
32
38
|
end
|
33
39
|
end
|
40
|
+
@order.update(ordered_at: DateTime.now)
|
34
41
|
end
|
35
42
|
|
36
43
|
# Returns diff -> perfect: [], ...
|
37
44
|
def check_against_cart
|
38
|
-
diff = {perfect: [], under_avail: [], extra: [], modified: [], miss: []}.to_h
|
45
|
+
diff = {perfect: [], under_avail: [], extra: [], modified: [], miss: [], error: []}.to_h
|
39
46
|
# have logger
|
40
47
|
mech = Rawbotz::new_mech
|
41
48
|
mech.login
|
@@ -65,6 +72,10 @@ module Rawbotz
|
|
65
72
|
diff[:extra] << [name, qty]
|
66
73
|
end
|
67
74
|
|
75
|
+
@order.order_items.where(state: "error").find_each do |item|
|
76
|
+
diff[:error] << [item.local_product.name]
|
77
|
+
end
|
78
|
+
|
68
79
|
diff
|
69
80
|
end
|
70
81
|
|