super_tools 0.0.1

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.
@@ -0,0 +1,13 @@
1
+ module SuperFormatter
2
+ module Ecan
3
+ Head = Struct.new(:data) do
4
+ def indexes
5
+ @indexes ||= {
6
+ global_order_id: data.index('客戶單號'),
7
+ recipient: data.index('收件人'),
8
+ tracking_code: data.index('宅配單號')
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'super_formatter/import'
2
+ require 'super_formatter/hct/head'
3
+ require 'super_formatter/hct/row'
4
+ module SuperFormatter
5
+ module Ecan
6
+ class Import < SuperFormatter::Import
7
+
8
+ callable do
9
+ build_rows!(Head, Row)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require 'super_formatter/row'
2
+ module SuperFormatter
3
+ module Ecan
4
+ class Row < ::SuperFormatter::Row
5
+
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module SuperFormatter
2
+ module Hct
3
+ Head = Struct.new(:data) do
4
+ def indexes
5
+ @indexes ||= {
6
+ global_order_id: data.index('訂單號碼') || data.index('清單編號'),
7
+ mobile: data.index('收貨人電話') || data.index('收貨人電話1'),
8
+ recipient: data.index('收貨人') || data.index('收貨人名稱'),
9
+ tracking_code: data.index('查貨號碼') || data.index('十碼貨號')
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'super_formatter/import'
2
+ require 'super_formatter/hct/head'
3
+ require 'super_formatter/hct/row'
4
+ module SuperFormatter
5
+ module Hct
6
+ class Import < ::SuperFormatter::Import
7
+
8
+ callable do
9
+ build_rows!(Head, Row)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ require 'super_formatter/row'
2
+ module SuperFormatter
3
+ module Hct
4
+ class Row < ::SuperFormatter::Row
5
+
6
+ def tracking_code
7
+ (find(:tracking_code) || "").gsub("'", '')
8
+ end
9
+
10
+ def mobile
11
+ @mobile ||= begin
12
+ text = (find(:mobile) || "").gsub("'", "")
13
+ if text[0] == '9' && text.length == 9
14
+ "0#{text}"
15
+ else
16
+ text
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module SuperFormatter
2
+ class Import < SuperProcess::Core
3
+ init :spreadsheet
4
+ attr_accessor :head, :rows, :orders
5
+
6
+ protected
7
+
8
+ def build_rows!(head_klass, row_klass)
9
+ self.head = head_klass.new(spreadsheet.result.shift)
10
+ self.rows = spreadsheet.result.map.with_index do |data, i|
11
+ row_klass.new(data, head.indexes)
12
+ end.compact
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module SuperFormatter
2
+ Row = Struct.new(:data, :indexes) do
3
+ def method_missing(m)
4
+ find(m)
5
+ end
6
+
7
+ protected
8
+
9
+ def find(m)
10
+ i = indexes[m.to_sym]
11
+ i.nil? ? nil : data[i]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module SuperFormatter
2
+ module Shopline
3
+ Head = Struct.new(:data) do
4
+ def indexes
5
+ @indexes ||= {
6
+ order_id: data.index('訂單號碼'),
7
+ order_created: data.index('訂單日期'),
8
+ shipping_method: data.index('送貨方式'),
9
+ payment_method: data.index('付款方式'),
10
+ payment_status: data.index('付款狀態'),
11
+ recipient: data.index('收件人'),
12
+ mobile: data.index('收件人電話號碼'),
13
+ store_id: data.index('全家服務編號 / 7-11 店號'),
14
+ address: data.index('完整地址'),
15
+ total_order_amount: data.index('訂單合計'),
16
+ note: data.index('送貨備註'),
17
+ item_title: data.index('商品名稱'),
18
+ item_option: data.index('選項'),
19
+ item_code: data.index('商品貨號'),
20
+ item_qty: data.index('數量'),
21
+ item_cost: data.index('商品成本')
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'super_formatter/import'
2
+ require 'super_formatter/shopline/head'
3
+ require 'super_formatter/shopline/row'
4
+ require 'super_formatter/shopline/order'
5
+ module SuperFormatter
6
+ module Shopline
7
+ class Import < ::SuperFormatter::Import
8
+
9
+ callable do
10
+ build_rows!(Head, Row)
11
+
12
+ self.orders = merged_orders!.values
13
+
14
+ self.orders
15
+ end
16
+
17
+ protected
18
+
19
+ def merged_orders!
20
+ array = {}
21
+ rows.each do |row|
22
+ if array[row.order_id].present?
23
+ # 存在 Merge Item
24
+ array[row.order_id].merge!(row)
25
+ else
26
+ # 不存在建立 Order
27
+ array[row.order_id] = Order.new(row)
28
+ end
29
+ end
30
+ array
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,88 @@
1
+ require 'warehouse'
2
+ module SuperFormatter
3
+ module Shopline
4
+ class Order
5
+ attr_accessor :row
6
+ attr_accessor :items_array, :warehouse_items
7
+
8
+ delegate :recipient, to: :row
9
+ delegate :mobile, to: :row
10
+ delegate :total_order_amount, to: :row
11
+ delegate :store_id, to: :row
12
+ delegate :note, to: :row
13
+
14
+ def order_id
15
+ row.order_id.gsub("#", '')
16
+ end
17
+
18
+ def initialize(row)
19
+ self.row = row
20
+ merge!(row)
21
+ end
22
+
23
+ def provider
24
+ @provider ||= case
25
+ when row.shipping_method.include?('7-11')
26
+ :UNIMART
27
+ when row.shipping_method.include?('全家')
28
+ :FAMI
29
+ when row.shipping_method.include?('新竹')
30
+ :HCT
31
+ when row.shipping_method.include?('黑貓')
32
+ :TCAT
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ def ref_id
39
+ order_id
40
+ end
41
+
42
+ def destination
43
+ @destination ||= case provider
44
+ when :UNIMART, :FAMI
45
+ store_id
46
+ when :HCT, :TCAT
47
+ address
48
+ end
49
+ end
50
+
51
+ def address
52
+ row.address.gsub("台灣", "")
53
+ end
54
+
55
+ def order_created_at
56
+ row.order_created
57
+ end
58
+
59
+ def cash_on_delivery?
60
+ if row.payment_method.include?('取貨付款')
61
+ true
62
+ else
63
+ false
64
+ end
65
+ end
66
+
67
+ def only_delivery?
68
+ !cash_on_delivery?
69
+ end
70
+
71
+ def paid?
72
+ row.payment_status == '已付款'
73
+ end
74
+
75
+ def items
76
+ items_array.join(" ")
77
+ end
78
+
79
+ def merge!(row)
80
+ self.items_array ||= []
81
+ self.warehouse_items ||= Warehouse::List.new
82
+
83
+ self.items_array << "#{row.item_title}-#{row.item_option}*#{row.item_qty}"
84
+ self.warehouse_items += Warehouse::Item::Code.new(row.item_code, row.item_code, row.item_qty)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,8 @@
1
+ require 'super_formatter/row'
2
+ module SuperFormatter
3
+ module Shopline
4
+ class Row < ::SuperFormatter::Row
5
+
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module SuperFormatter
2
+ module Tcat
3
+ Head = Struct.new(:data) do
4
+ def indexes
5
+ @indexes ||= {
6
+ global_order_id: data.index('訂單編號'),
7
+ mobile: data.index('手機(收)'),
8
+ recipient: data.index('收件人'),
9
+ tracking_code: data.index('託運單號')
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'super_formatter/import'
2
+ require 'super_formatter/hct/head'
3
+ require 'super_formatter/hct/row'
4
+ module SuperFormatter
5
+ module Tcat
6
+ class Import < SuperFormatter::Import
7
+
8
+ callable do
9
+ build_rows!(Head, Row)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ require 'super_formatter/row'
2
+ module SuperFormatter
3
+ module Tcat
4
+ class Row < ::SuperFormatter::Row
5
+
6
+ def tracking_code
7
+ (find(:tracking_code) || "").gsub("'", '')
8
+ end
9
+
10
+ def mobile
11
+ @mobile ||= begin
12
+ text = (find(:mobile) || "").gsub("'", "")
13
+ if text[0] == '9' && text.length == 9
14
+ "0#{text}"
15
+ else
16
+ text
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,83 @@
1
+ require 'virtus'
2
+ module SuperProcess
3
+ class Core
4
+ include ActiveModel::Validations
5
+ include ActiveSupport::Callbacks
6
+ include Virtus.model
7
+
8
+ ValidError = Class.new(StandardError)
9
+
10
+ define_callbacks :validations, :task
11
+
12
+ def self.before_call(method_name)
13
+ set_callback :validations, :before, method_name
14
+ end
15
+
16
+ def self.after_call(method_name)
17
+ set_callback :validations, :after, method_name
18
+ end
19
+
20
+ def self.before_task(method_name)
21
+ set_callback :task, :before, method_name
22
+ end
23
+
24
+ def self.after_task(method_name)
25
+ set_callback :task, :after, method_name
26
+ end
27
+
28
+ def self.init(model_name, &block)
29
+ attr_accessor model_name
30
+
31
+ class_eval(&block) if block_given?
32
+
33
+ define_method :initialize do |model|
34
+ self.send("#{model_name}=", model)
35
+ end
36
+ end
37
+
38
+ def self.callable(&block)
39
+ define_method :call! do |params={}|
40
+ params.each do |attr, value|
41
+ public_send("#{attr}=", value) if respond_to?("#{attr}=")
42
+ end
43
+ run_callbacks :validations do
44
+ raise ValidError, "Validation Error" if valid? == false
45
+
46
+ run_callbacks :task do
47
+ instance_eval(&block)
48
+ end
49
+ end
50
+ end
51
+
52
+ define_method :call do |params={}|
53
+ begin
54
+ @result = call!(params)
55
+ true
56
+ rescue ValidError
57
+ false
58
+ end
59
+ end
60
+ end
61
+
62
+ def result
63
+ @result
64
+ end
65
+
66
+ def error_messages
67
+ if errors.messages.values.present?
68
+ errors.messages.values.first.first
69
+ else
70
+ ""
71
+ end
72
+ end
73
+
74
+ def self.method_missing(m, *args, &block)
75
+ puts "Missing: #{m} -> Context: #{self.inspect}" if Rails.env.development?
76
+ if block_given?
77
+ new.public_send(m, *args, &block)
78
+ else
79
+ new.public_send(m, *args)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,91 @@
1
+ require 'iconv'
2
+ require 'csv'
3
+ require 'roo'
4
+ require 'roo-xls'
5
+ module SuperSpreadsheet
6
+ class Loader < SuperProcess::Core
7
+ attr_accessor :file_path
8
+ validate :valid_format
9
+
10
+ def self.load!(file)
11
+ new(file)
12
+ end
13
+
14
+ def initialize(file_path)
15
+ @file_path = file_path
16
+ end
17
+
18
+ callable do
19
+ rows
20
+ end
21
+
22
+ def extension
23
+ ::File.extname(file_path).split('.').last.force_encoding('utf-8').downcase
24
+ end
25
+
26
+ def valid_format
27
+ if rows == false
28
+ errors.add(:file, '檔案格式錯誤')
29
+ elsif rows.flatten.empty?
30
+ errors.add(:file, '檔案內容錯誤,空白檔案')
31
+ end
32
+ end
33
+
34
+ def rows
35
+ @rows ||= rows!
36
+ end
37
+
38
+ protected
39
+
40
+ def rows!
41
+ case extension
42
+ when 'xls'
43
+ ::Roo::Excel.new(file_path).map { |row| convert_float_to_integer(row) }
44
+ when 'xlsx'
45
+ ::Roo::Excelx.new(file_path).map { |row| convert_float_to_integer(row) }
46
+ when 'csv'
47
+ ::CSV.parse(csv_content!)
48
+ else
49
+ false
50
+ end
51
+ rescue
52
+ false
53
+ end
54
+
55
+ def csv_content!
56
+ @decode_csv_content ||= begin
57
+ csv_content_big5!
58
+ rescue Iconv::IllegalSequence
59
+ begin
60
+ csv_content_big5_hkscs!
61
+ rescue Iconv::IllegalSequence
62
+ csv_content
63
+ end
64
+ end
65
+ end
66
+
67
+ def csv_content
68
+ @csv_content ||= File.read(file_path)
69
+ end
70
+
71
+ private
72
+
73
+ def csv_content_big5!
74
+ Iconv.new("utf-8", "Big5//TRANSLIT//IGNORE").iconv(csv_content)
75
+ end
76
+
77
+ def csv_content_big5_hkscs!
78
+ Iconv.new("utf-8", "Big5-HKSCS//TRANSLIT//IGNORE").iconv(csv_content)
79
+ end
80
+
81
+ def convert_float_to_integer(row)
82
+ row.map do |cell|
83
+ if cell.is_a?(Float) && cell = cell.to_i
84
+ cell.to_i
85
+ else
86
+ cell
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end