18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/bakong/khqr/controllers/decode_validation.rb', line 18
def call(khqr_string)
all_fields = KHQR_TAG.map { |el| el[:tag] }
subtag_set = KHQR_TAG.select { |el| el[:sub] }.map { |el| el[:tag] }
required_fields = KHQR_TAG.select { |el| el[:required] }.map { |el| el[:tag] }
sub_tag_input = KHQR_SUBTAG[:input]
sub_tag_compare = KHQR_SUBTAG[:compare]
tags = []
merchant_type = "individual"
last_tag = ""
remainder = khqr_string
until remainder.nil? || remainder.empty?
slice = Helpers::CutString.call(remainder)
tag = slice[:tag]
value = slice[:value]
remainder = slice[:remainder]
break if tag == last_tag
if tag == "30"
merchant_type = "merchant"
tag = "29"
end
if all_fields.include?(tag)
tags << { tag: tag, value: value }
required_fields.delete(tag)
end
last_tag = tag
end
if tags.any? { |t| t[:tag] == "01" && t[:value] == "12" }
raise Error.from(ERROR_CODES[:INVALID_DYNAMIC_KHQR]) unless tags.any? { |t| t[:tag] == "54" }
raise Error.from(ERROR_CODES[:EXPIRATION_TIMESTAMP_REQUIRED]) unless tags.any? { |t| t[:tag] == "99" }
end
if tags.any? { |t| t[:tag] == "54" } && tags.none? { |t| t[:tag] == "99" }
raise Error.from(ERROR_CODES[:EXPIRATION_TIMESTAMP_REQUIRED])
end
unless required_fields.empty?
required_tag = required_fields.first
missing_instance = KHQR_TAG.find { |el| el[:tag] == required_tag }[:instance]
missing_instance.new(required_tag, nil) end
decode_value = { merchant_type: merchant_type }
sub_tag_input.each { |el| decode_value.merge!(el[:data]) }
poi = nil
tags.each do |khqr_tag|
tag = khqr_tag[:tag]
schema = KHQR_TAG.find { |el| el[:tag] == tag }
value = khqr_tag[:value]
input_value = value
poi = value if tag == EMV[:POINT_OF_INITIATION_METHOD]
if subtag_set.include?(tag)
input_data_template = sub_tag_input.find { |el| el[:tag] == tag }[:data]
input_data = deep_dup(input_data_template)
while value && !value.empty?
cut = Helpers::CutString.call(value)
sub_tag = cut[:tag]
sub_value = cut[:value]
value = cut[:remainder]
name_subtag = sub_tag_compare
.select { |el| el[:tag] == tag }
.find { |el| el[:sub_tag] == sub_tag }
next unless name_subtag
input_data[name_subtag[:name]] = sub_value
input_value = input_data
end
decode_value.merge!(input_value) if input_value.is_a?(Hash)
if tag == EMV[:TIMESTAMP_TAG]
schema[:instance].new(tag, input_value, poi)
else
schema[:instance].new(tag, input_value)
end
else
instance = schema[:instance].new(tag, input_value)
decode_value[schema[:type]] = instance.value
end
end
decode_value
end
|