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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +173 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/super_form/basic.rb +43 -0
- data/lib/super_form/concerns/atomic_save.rb +70 -0
- data/lib/super_form/reform.rb +46 -0
- data/lib/super_formatter/ecan/head.rb +13 -0
- data/lib/super_formatter/ecan/import.rb +13 -0
- data/lib/super_formatter/ecan/row.rb +8 -0
- data/lib/super_formatter/hct/head.rb +14 -0
- data/lib/super_formatter/hct/import.rb +13 -0
- data/lib/super_formatter/hct/row.rb +22 -0
- data/lib/super_formatter/import.rb +15 -0
- data/lib/super_formatter/row.rb +14 -0
- data/lib/super_formatter/shopline/head.rb +26 -0
- data/lib/super_formatter/shopline/import.rb +34 -0
- data/lib/super_formatter/shopline/order.rb +88 -0
- data/lib/super_formatter/shopline/row.rb +8 -0
- data/lib/super_formatter/tcat/head.rb +14 -0
- data/lib/super_formatter/tcat/import.rb +13 -0
- data/lib/super_formatter/tcat/row.rb +22 -0
- data/lib/super_process/core.rb +83 -0
- data/lib/super_spreadsheet/loader.rb +91 -0
- data/lib/super_table/action_view.rb +40 -0
- data/lib/super_table/builder.rb +116 -0
- data/lib/super_table/record.rb +23 -0
- data/lib/super_table/tableable.rb +44 -0
- data/lib/super_table/view_helpers.rb +40 -0
- data/lib/super_tools.rb +41 -0
- data/lib/super_tools/version.rb +3 -0
- data/super_tools.gemspec +48 -0
- metadata +361 -0
@@ -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,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,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,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,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
|