extface 0.1.9 → 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/MIT-LICENSE +1 -1
- data/app/models/extface/driver/daisy_fx1200.rb +1 -1
- data/app/models/extface/driver/eltrade/commands_fp4.rb +78 -0
- data/app/models/extface/driver/eltrade_tm_u220.rb +359 -0
- data/app/views/extface/driver/{epson_tm_u220 → eltrade_tm_u220}/_settings.html.erb +0 -0
- data/lib/extface/version.rb +1 -1
- metadata +7 -8
- data/app/models/extface/driver/epson/esc_pos.rb +0 -12
- data/app/models/extface/driver/epson/fiscal.rb +0 -99
- data/app/models/extface/driver/epson_tm_u220.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffc7be7748574fcff49cfea02aab44e7f4f97760
|
4
|
+
data.tar.gz: 426759fdcff98ca0979ef600877c42674f9b4733
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cf1335ec7f7cf50da17e1816213b740a675e5d0b6223f13b9d4145ff14a14d50c6411b4ec29808568b9d39f456b1d657f160122c64da8596f5dfb0439d86ad9
|
7
|
+
data.tar.gz: 6821ca4e6a6e1078740eebc9c7d30a4dd899e204eb1c979eca3dd695080b35141c7eaff4bf036969151031c830dd4a2483b124396c357264e348391bd597361d
|
data/MIT-LICENSE
CHANGED
@@ -269,7 +269,7 @@ module Extface
|
|
269
269
|
def initialize(buffer)
|
270
270
|
# test Extface::Driver::DaisyFx1200::RespFrame.new("\x16\x16\x01\x2c\x20\x2dP\x04SSSSSS\x05\BBBB\x03")
|
271
271
|
# LEN SEQ CMD DATA STATUS BCC
|
272
|
-
if match = buffer.match(/\x01(.{1})(.{1})(.{1})(.*)\x04(.{6})\x05(.{4})\x03/
|
272
|
+
if match = buffer.match(/\x01(.{1})(.{1})(.{1})(.*)\x04(.{6})\x05(.{4})\x03/nm)
|
273
273
|
@frame = match.to_a.first
|
274
274
|
@len, @seq, @cmd, @data, @status, @bcc = match.captures
|
275
275
|
else
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#Source: ELTRADE COMMUNICATION PROTOCOL for Fiscal Printers (ver 4.0.2.12)
|
2
|
+
|
3
|
+
module Extface
|
4
|
+
module Driver::Eltrade::CommandsFp4
|
5
|
+
STRT = "\xAA\x55"
|
6
|
+
|
7
|
+
module Info
|
8
|
+
GET_SERIAL_NUMBER = 0x10
|
9
|
+
GET_HEADING_ROWS_1_6 = 0x11
|
10
|
+
GET_FISC_MEM_NUMBER = 0x14
|
11
|
+
GET_TAX_NUMBER = 0x15
|
12
|
+
GET_HEADING_ROWS_7_10 = 0x17
|
13
|
+
GET_TAX_GROUPS = 0x19
|
14
|
+
GET_OPERATOR = 0x1A
|
15
|
+
GET_PAYMENTS = 0x1B
|
16
|
+
GET_PRINTER_STATUS = 0x2C
|
17
|
+
GET_FISCAL_STATUS = 0x30
|
18
|
+
GET_FISCAL_TYPE = 0x3C
|
19
|
+
GET_DATE_TIME = 0x3E
|
20
|
+
REQUEST_HARDWARE_STAT = 0x46
|
21
|
+
GET_HARDWARE_STATUS = 0x47
|
22
|
+
GET_STATUS = 0x70
|
23
|
+
end
|
24
|
+
module Receipt
|
25
|
+
OPEN_RECEIPT = 0x2D
|
26
|
+
PRINT_RECEIPT = 0x2E
|
27
|
+
module Variant
|
28
|
+
COMMENT = "\x01"
|
29
|
+
PLU = "\x02"
|
30
|
+
START_INVOICE_RECEIPT = "\x0D"
|
31
|
+
START_COMMENT_RECEIPT = "\x0F"
|
32
|
+
end
|
33
|
+
CLOSE_RECEIPT = 0x2F
|
34
|
+
LAST_DOC_COPY = 0x31
|
35
|
+
SET_INVOICE_NUMBER = 0x34
|
36
|
+
PRINT_RECEIPT_HEADER = 0x38
|
37
|
+
end
|
38
|
+
module Reports
|
39
|
+
SILENT0_PLU = 0x22
|
40
|
+
SILENT_PRINTER = 0x23
|
41
|
+
PLU_REPORT = 0x32
|
42
|
+
DAILY_REPORT = 0x33
|
43
|
+
end
|
44
|
+
module Init
|
45
|
+
GRAPHIC_LOGO_PRINTING = 0x13
|
46
|
+
SET_OPERATOR_INFO = 0x2A
|
47
|
+
SET_PAYMENT_TYPES = 0x2B
|
48
|
+
SET_FISCAL_DEV_NUM = 0x35
|
49
|
+
FISCAL_PARAMS_REC = 0x36
|
50
|
+
SET_PRINT_PLU_NUMBER = 0x3A
|
51
|
+
SET_SERIAL_NUMBER = 0x3B
|
52
|
+
SET_DATE_TIME = 0x3D
|
53
|
+
end
|
54
|
+
module Other
|
55
|
+
EXEC_PRINTER_TEST = 0x24
|
56
|
+
FISC_MEM_READ_TEST = 0x25
|
57
|
+
FISC_MEM_WRITE_TEST = 0x26
|
58
|
+
PAYED_RECV_ACCOUNT = 0x28 # ?
|
59
|
+
GET_DATE_TIME = 0x3E
|
60
|
+
SET_DATE_TIME = 0x3D
|
61
|
+
OPEN_CASH_DRAWER = 0x4B
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_packet(cmd, fields = [])
|
65
|
+
String.new.tap() do |frame|
|
66
|
+
frame << STX
|
67
|
+
frame << sequence_number
|
68
|
+
frame << cmd
|
69
|
+
fields.each do |field|
|
70
|
+
frame << SEP
|
71
|
+
frame << field
|
72
|
+
end
|
73
|
+
frame << ETX
|
74
|
+
frame << bcc(frame)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,359 @@
|
|
1
|
+
|
2
|
+
# 1 2 3 4 5 6 6+n
|
3
|
+
#STRT ADDR SEQ CMD LEN DATA CS
|
4
|
+
# 1 1 1 1 1 1 4 1
|
5
|
+
#AAh 55h 0–FFh 0–FFh 10h–70h 0-FFh 30h–3Fh 0-FFh
|
6
|
+
|
7
|
+
module Extface
|
8
|
+
class Driver::EltradeTmU220 < Extface::Driver
|
9
|
+
NAME = 'Eltrade TM-U220 (Serial)'.freeze
|
10
|
+
GROUP = Extface::FISCAL_DRIVER
|
11
|
+
|
12
|
+
DEVELOPMENT = true #driver is not ready for production (not passing all tests or has major bugs)
|
13
|
+
|
14
|
+
# Select driver features
|
15
|
+
RAW = true #responds to #push(data) and #pull
|
16
|
+
PRINT = false #POS, slip printers
|
17
|
+
FISCAL = true #cash registers, fiscal printers
|
18
|
+
REPORT = false #only transmit data that must be parsed by handler, CDR, report devices
|
19
|
+
|
20
|
+
RESPONSE_TIMEOUT = 3 #seconds
|
21
|
+
INVALID_FRAME_RETRIES = 6 #seconds
|
22
|
+
|
23
|
+
FLAG_TRUE = "\xff\xff"
|
24
|
+
FLAG_FALSE = "\x00\x00"
|
25
|
+
|
26
|
+
has_serial_config
|
27
|
+
|
28
|
+
include Extface::Driver::Eltrade::CommandsFp4
|
29
|
+
|
30
|
+
def handle(buffer)
|
31
|
+
bytes_processed = 0
|
32
|
+
if frame_match = buffer.match(/\xAA\x55.{3}(.{1}).*/nm) #m Treat \x0a as a character matched by .
|
33
|
+
len = frame_match.captures.first.ord
|
34
|
+
skip = frame_match.pre_match.length
|
35
|
+
bytes_processed = skip + 7 + len # 6 pre + 1 check sum
|
36
|
+
rpush buffer[skip..bytes_processed]
|
37
|
+
end
|
38
|
+
return bytes_processed
|
39
|
+
end
|
40
|
+
|
41
|
+
def open_receipt(variant = nil)
|
42
|
+
fsend Receipt::OPEN_RECEIPT
|
43
|
+
status = printer_status!
|
44
|
+
unless variant.blank?
|
45
|
+
fsend Receipt::PRINT_RECEIPT, variant
|
46
|
+
status = printer_status!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def close_receipt
|
51
|
+
fsend Receipt::CLOSE_RECEIPT
|
52
|
+
status = printer_status!
|
53
|
+
end
|
54
|
+
|
55
|
+
def send_comment(text)
|
56
|
+
fsend Receipt::PRINT_RECEIPT, Receipt::Variant::COMMENT + text
|
57
|
+
status = printer_status!
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_plu(plu_data)
|
61
|
+
fsend Receipt::PRINT_RECEIPT, Receipt::Variant::PLU + plu_data
|
62
|
+
status = printer_status!
|
63
|
+
end
|
64
|
+
|
65
|
+
def send_payment(type_num = 0, value = nil) # 0, 1, 2, 3
|
66
|
+
value_bytes = "\x00\x00\x00\x00" # recalculate
|
67
|
+
unless value.nil?
|
68
|
+
value_units = (value * 100).to_i # !FIXME
|
69
|
+
value_bytes = "".b
|
70
|
+
4.times{ |shift| value_bytes.insert 0, ((value_units >> shift*8) & 0xff).chr }
|
71
|
+
end
|
72
|
+
fsend Receipt::PRINT_RECEIPT, "" << (9 + type_num).chr << value_bytes
|
73
|
+
end
|
74
|
+
|
75
|
+
def non_fiscal_test
|
76
|
+
device.session("Non Fiscal Text") do |s|
|
77
|
+
s.notify "Printing Non Fiscal Text"
|
78
|
+
s.open_receipt Receipt::Variant::START_COMMENT_RECEIPT
|
79
|
+
s.send_comment "********************************"
|
80
|
+
s.send_comment "Extface Print Test".center(32)
|
81
|
+
s.send_comment "********************************"
|
82
|
+
s.send_comment ""
|
83
|
+
s.send_comment "Driver: " + "#{self.class::NAME}".truncate(24)
|
84
|
+
s.close_receipt
|
85
|
+
s.notify "Printing finished"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def fiscal_test
|
90
|
+
sale_and_pay_items_session([
|
91
|
+
{ price: 0.01, text1: "Extface Test" }
|
92
|
+
])
|
93
|
+
end
|
94
|
+
|
95
|
+
def build_sale_data(price, text1 = "", text2 = nil, tax_group = 2, qty = 1, percent = nil, neto = nil, number = nil)
|
96
|
+
"".b.tap() do |data|
|
97
|
+
price_units = (price * 100).to_i # !FIXME
|
98
|
+
price_bytes = "".b
|
99
|
+
4.times{ |shift| price_bytes.insert 0, ((price_units >> shift*8) & 0xff).chr }
|
100
|
+
data << price_bytes
|
101
|
+
qty_units = ((qty || 1) * 1000).to_i # !FIXME
|
102
|
+
qty_bytes = "".b
|
103
|
+
4.times{ |shift| qty_bytes.insert 0, ((qty_units >> shift*8) & 0xff).chr }
|
104
|
+
data << qty_bytes
|
105
|
+
data << "\x00".b #number len FIXME
|
106
|
+
data << "\xAA\xAA\xAA\xAA\xAA\xAA".b #number FIXME
|
107
|
+
text = text1.truncate(20)
|
108
|
+
data << text.length.chr
|
109
|
+
data << text.ljust(20, " ").b
|
110
|
+
data << (tax_group || 2).chr
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def sale_and_pay_items_session(items = [], operator = "1", password = "1")
|
115
|
+
device.session("Fiscal Doc") do |s|
|
116
|
+
s.notify "Fiscal Doc Start"
|
117
|
+
s.open_receipt
|
118
|
+
items.each do |item|
|
119
|
+
s.send_plu build_sale_data(item[:price], item[:text1], nil, item[:tax_group], item[:qty], nil, nil, item[:number])
|
120
|
+
s.send_comment(item[:text2]) unless item[:text2].blank?
|
121
|
+
end
|
122
|
+
s.send_payment
|
123
|
+
s.close_receipt
|
124
|
+
s.notify "Fiscal Doc End"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def z_report_session
|
129
|
+
device.session("Z Report") do |s|
|
130
|
+
s.notify "Z Report Start"
|
131
|
+
s.fsend Reports::DAILY_REPORT, FLAG_TRUE
|
132
|
+
status = s.printer_status!
|
133
|
+
s.notify "Z Report End"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def x_report_session
|
138
|
+
device.session("Z Report") do |s|
|
139
|
+
s.notify "Z Report Start"
|
140
|
+
s.fsend Reports::DAILY_REPORT, FLAG_FALSE
|
141
|
+
status = s.printer_status!
|
142
|
+
s.notify "Z Report End"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def cancel_doc_session
|
147
|
+
device.session("Doc cancel") do |s|
|
148
|
+
s.notify "Doc Cancel Start"
|
149
|
+
#s.fsend Sales::CANCEL_DOC
|
150
|
+
s.notify "Doc Cancel End"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def printer_status!
|
156
|
+
fsend Info::GET_STATUS
|
157
|
+
raise errors.full_messages.join(", ") if errors.any?
|
158
|
+
status = PrinterStatus.new(fsend(Info::GET_PRINTER_STATUS))
|
159
|
+
raise errors.full_messages.join(", ") if errors.any?
|
160
|
+
status
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_status
|
164
|
+
flush
|
165
|
+
fsend(Info::GET_STATUS)
|
166
|
+
errors.empty?
|
167
|
+
end
|
168
|
+
|
169
|
+
def build_packet(cmd, data = "")
|
170
|
+
"".tap() do |packet|
|
171
|
+
packet << STRT.b
|
172
|
+
packet << 0x00 #address
|
173
|
+
packet << sequence_number
|
174
|
+
packet << cmd
|
175
|
+
packet << data.length
|
176
|
+
packet << data.b
|
177
|
+
packet << check_sum(packet[2..-1])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def fsend(cmd, data = "") #return data or nil
|
182
|
+
packet_data = build_packet(cmd, data)
|
183
|
+
result = false
|
184
|
+
INVALID_FRAME_RETRIES.times do |retries|
|
185
|
+
errors.clear
|
186
|
+
push packet_data
|
187
|
+
if resp = frecv(RESPONSE_TIMEOUT)
|
188
|
+
if resp.valid?
|
189
|
+
result = resp.data
|
190
|
+
break
|
191
|
+
else
|
192
|
+
resp.errors.full_messages.each do |msg|
|
193
|
+
errors.add :base, msg
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
errors.add :base, "#{INVALID_FRAME_RETRIES} Broken Packets Received. Abort!"
|
198
|
+
end
|
199
|
+
return result
|
200
|
+
end
|
201
|
+
|
202
|
+
def frecv(timeout) # return RespFrame or nil
|
203
|
+
if frame_bytes = pull(timeout)
|
204
|
+
return Frame.new(frame_bytes.b)
|
205
|
+
else
|
206
|
+
errors.add :base, "No data received from device"
|
207
|
+
return nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def check_sum(buffer)
|
212
|
+
sum = 0
|
213
|
+
buffer.each_byte do |byte|
|
214
|
+
sum -= byte
|
215
|
+
end
|
216
|
+
sum & 0xff
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
def sequence_number(increment = true)
|
221
|
+
@seq ||= 0
|
222
|
+
@seq += 1 if increment
|
223
|
+
@seq = 0 if @seq == 0xff
|
224
|
+
@seq
|
225
|
+
end
|
226
|
+
|
227
|
+
class Frame
|
228
|
+
include ActiveModel::Validations
|
229
|
+
attr_reader :frame, :addr, :seq, :cmd, :len, :data, :check_sum
|
230
|
+
|
231
|
+
validates_presence_of :frame
|
232
|
+
validate :check_sum_validation
|
233
|
+
validate :len_validation
|
234
|
+
validate :response_code_validation
|
235
|
+
|
236
|
+
def initialize(buffer)
|
237
|
+
if match = buffer.match(/\xAA\x55(.{1})(.{1})(.{1})(.{1})(.*)(.{1})$/nm)
|
238
|
+
@frame = match.to_a.first
|
239
|
+
@addr, @seq, @cmd, @len, @data, @check_sum = match.captures
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def ready?
|
244
|
+
@ready || true
|
245
|
+
end
|
246
|
+
|
247
|
+
private
|
248
|
+
def check_sum_validation
|
249
|
+
sum = 0
|
250
|
+
frame[2..-1].each_byte do |byte|
|
251
|
+
sum += byte
|
252
|
+
end
|
253
|
+
errors.add(:check_sum, I18n.t('errors.messages.invalid')) if (sum & 0xff) != 0
|
254
|
+
end
|
255
|
+
|
256
|
+
def len_validation
|
257
|
+
errors.add(:len, I18n.t('errors.messages.invalid')) if len.ord != data.length
|
258
|
+
end
|
259
|
+
|
260
|
+
def response_code_validation
|
261
|
+
case cmd.ord
|
262
|
+
when 0x2c then
|
263
|
+
case data[0] # printer error code
|
264
|
+
when 1 then errors.add :base, "Opening of the cash register document is not requested"
|
265
|
+
when 2 then errors.add :base, "Transaction code recognized (refer to command 0x2E)"
|
266
|
+
when 3 then errors.add :base, "Transaction buffer overflow"
|
267
|
+
when 4 then errors.add :base, "Transaction sequence error"
|
268
|
+
when 5 then errors.add :base, "Multiplication overflow"
|
269
|
+
when 6 then errors.add :base, "Cash register document overflow"
|
270
|
+
when 7 then errors.add :base, "'0' length of code name"
|
271
|
+
when 8 then errors.add :base, "Negative result"
|
272
|
+
when 9 then errors.add :base, "Cash register document surcharge"
|
273
|
+
when 10 then errors.add :base, "Out of range parameter"
|
274
|
+
when 11 then errors.add :base, "Cash register document not paid"
|
275
|
+
when 12 then errors.add :base, "'0' result"
|
276
|
+
when 13 then errors.add :base, "Memory overflow because of too many PLUs"
|
277
|
+
when 14 then errors.add :base, "Daily report overflow"
|
278
|
+
end
|
279
|
+
when 0x6F then
|
280
|
+
case data[1]
|
281
|
+
when 1 then errors.add :base, "End of paper"
|
282
|
+
when 2 then errors.add :base, "Printing error"
|
283
|
+
when 16 then errors.add :base, "Fiscal error 0: Error at writing in FM"
|
284
|
+
when 17 then errors.add :base, "Fiscal error 1: Attempt for writing in overflowing FM"
|
285
|
+
when 18 then errors.add :base, "Fiscal error 2: Incorrect structure in fiscal part 1"
|
286
|
+
when 19 then errors.add :base, "Fiscal error 3: Control sum error"
|
287
|
+
when 20 then errors.add :base, "Fiscal error 4: Incorrect structure in fiscal part 2"
|
288
|
+
when 21 then errors.add :base, "Fiscal error 5: No connection with the fiscal memory"
|
289
|
+
when 22 then errors.add :base, "Fiscal error 6: Incorrect record structure"
|
290
|
+
when 23 then errors.add :base, "Fiscal error 7: Fiscal memory overflow"
|
291
|
+
|
292
|
+
when 32 then errors.add :base, "No connection with terminal"
|
293
|
+
when 33 then errors.add :base, "No valid registration (IMSI on the SIM is different than the one recorded in fiscal memory"
|
294
|
+
when 34 then errors.add :base, "Not used"
|
295
|
+
when 35 then errors.add :base, "3 Daily reports with zeroing and no connection with NRA’s server"
|
296
|
+
when 36 then errors.add :base, "Missing or invalid SIM card"
|
297
|
+
when 37 then errors.add :base, "GSM module data reading error"
|
298
|
+
when 38 then errors.add :base, "Terminal data memory error"
|
299
|
+
when 39 then errors.add :base, "Terminal data memory damaged"
|
300
|
+
when 40 then errors.add :base, "GSM module error (registration not possible, wrong PIN, damaged GSM module)"
|
301
|
+
when 41 then errors.add :base, "KLEN SD card is not valid"
|
302
|
+
when 42 then errors.add :base, "KLEN SD card is missing"
|
303
|
+
when 43 then errors.add :base, "KLEN SD card data error"
|
304
|
+
when 44 then errors.add :base, "New KLEN SD card is put in a terminal with sales registration in RAM memory (daily report with zeroing must be done before changing the KLEN SD cards)"
|
305
|
+
when 45 then errors.add :base, "New KLEN SD card is not registered because some fiscal parameters cannot be changed"
|
306
|
+
when 46 then errors.add :base, "New KLEN SD card is put and fiscalization must be done"
|
307
|
+
when 47 then errors.add :base, "Recognized a KLEN SD card from a different device – only reports are available"
|
308
|
+
end
|
309
|
+
when 0x70 then @ready = true
|
310
|
+
when 0x71 then @ready = false
|
311
|
+
when 0x7E then errors.add :base, "Failed RAM"
|
312
|
+
when 0x7F then errors.add :base, "Wrong command"
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
class PrinterStatus
|
318
|
+
|
319
|
+
def initialize(status)
|
320
|
+
end
|
321
|
+
|
322
|
+
def start_bon_flag?
|
323
|
+
end
|
324
|
+
|
325
|
+
def end_bon_flag?
|
326
|
+
end
|
327
|
+
|
328
|
+
def last_transaction
|
329
|
+
end
|
330
|
+
|
331
|
+
def transaction_count
|
332
|
+
end
|
333
|
+
|
334
|
+
def last_transaction_sum
|
335
|
+
end
|
336
|
+
|
337
|
+
def all_transaction_sum
|
338
|
+
end
|
339
|
+
|
340
|
+
def total_sum
|
341
|
+
end
|
342
|
+
|
343
|
+
def stl_discount_flag?
|
344
|
+
end
|
345
|
+
|
346
|
+
def last_recept_number
|
347
|
+
end
|
348
|
+
|
349
|
+
def last_invoice_number
|
350
|
+
end
|
351
|
+
|
352
|
+
def available_invoice_numbers
|
353
|
+
end
|
354
|
+
|
355
|
+
def plu_count_in_memory
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
File without changes
|
data/lib/extface/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: extface
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Vangelov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.0.
|
19
|
+
version: 4.0.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.0.
|
26
|
+
version: 4.0.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: redis
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,9 +98,8 @@ files:
|
|
98
98
|
- app/models/extface/driver.rb
|
99
99
|
- app/models/extface/driver/daisy/commands_fx1200.rb
|
100
100
|
- app/models/extface/driver/daisy_fx1200.rb
|
101
|
-
- app/models/extface/driver/
|
102
|
-
- app/models/extface/driver/
|
103
|
-
- app/models/extface/driver/epson_tm_u220.rb
|
101
|
+
- app/models/extface/driver/eltrade/commands_fp4.rb
|
102
|
+
- app/models/extface/driver/eltrade_tm_u220.rb
|
104
103
|
- app/models/extface/driver/generic_pos.rb
|
105
104
|
- app/models/extface/driver/star_scp700.rb
|
106
105
|
- app/models/extface/driver/star_tsp200.rb
|
@@ -111,7 +110,7 @@ files:
|
|
111
110
|
- app/views/extface/devices/index.html.erb
|
112
111
|
- app/views/extface/devices/show.html.erb
|
113
112
|
- app/views/extface/driver/daisy_fx1200/_settings.html.erb
|
114
|
-
- app/views/extface/driver/
|
113
|
+
- app/views/extface/driver/eltrade_tm_u220/_settings.html.erb
|
115
114
|
- app/views/extface/driver/generic_pos/_settings.html.erb
|
116
115
|
- app/views/extface/driver/star_scp700/_settings.html.erb
|
117
116
|
- app/views/extface/driver/star_tsp200/_settings.html.erb
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
module Extface
|
3
|
-
module Driver::Epson::EscPos
|
4
|
-
|
5
|
-
def autocut(partial = true) # (Function B)
|
6
|
-
# <GS> 'V' 0x65 x - Full-cut command
|
7
|
-
# <GS> 'V' 0x66 x - Partial-cut command
|
8
|
-
push partial ? "\x1D\x56\x65\x03" : "\x1D\x56\x66\x03"
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
module Extface
|
2
|
-
module Driver::Epson::Fiscal
|
3
|
-
STX = 0x02
|
4
|
-
ETX = 0x03
|
5
|
-
SEP = 0x1c
|
6
|
-
DC2 = 0x12
|
7
|
-
DC4 = 0x14
|
8
|
-
NAK = 0x15
|
9
|
-
|
10
|
-
module Control
|
11
|
-
STATUS_IF = 0x38
|
12
|
-
X_Z_REPORTS = 0x39
|
13
|
-
FISC_MEM_REPORT_DATE = 0x3a
|
14
|
-
FISC_MEM_REPORT = 0x3b
|
15
|
-
end
|
16
|
-
module Vouchers
|
17
|
-
OPEN_FISCAL_VOUCHER = 0x40
|
18
|
-
PRINT_FISCAL_TEXT = 0x41
|
19
|
-
PRINT_FISCAL_ARTICLE = 0x42
|
20
|
-
SUBTOTAL_FISCAL = 0x43
|
21
|
-
FISCAL_VOUCHER = 0x44 # pay / cancel / discount in
|
22
|
-
CLOSE_FISCAL_VOUCHER = 0x45
|
23
|
-
end
|
24
|
-
module NonFiscal
|
25
|
-
OPEN_NON_FISCAL_DOC = 0x48
|
26
|
-
PRINT_NON_FISCAL_TEXT = 0x49
|
27
|
-
CLOSE_NON_FISCAL_DOC = 0x4a
|
28
|
-
end
|
29
|
-
module Printer
|
30
|
-
CUT_PAPER = 0x4b
|
31
|
-
ADVANCE_PAPER = 0x50
|
32
|
-
ACTIVATE_SLIP = 0xa0 #TMU950, TMU675
|
33
|
-
DISABLE_SLIP = 0xa1
|
34
|
-
FORMAT_CHECKS = 0xaa
|
35
|
-
FORMAT_ENDOSEMENT = 0xab
|
36
|
-
end
|
37
|
-
module General
|
38
|
-
SET_DATE_HOUR = 0x58
|
39
|
-
GET_DATE_HOUR = 0x59
|
40
|
-
HEADED = 0x5d
|
41
|
-
FOOT_OF_PAGE = 0x5e
|
42
|
-
OPEN_DRAWER_1 = 0x7b
|
43
|
-
OPEN_DRAWER_2 = 0x7c
|
44
|
-
end
|
45
|
-
|
46
|
-
def handle(buffer)
|
47
|
-
bytes_processed = 0
|
48
|
-
if frame_match = buffer.match(/\x02.*\x03.{4}/n)
|
49
|
-
frame_data = frame_match.to_s
|
50
|
-
rpush frame_data
|
51
|
-
bytes_processed = frame_match.pre_match.length + frame_data.length
|
52
|
-
end
|
53
|
-
return bytes_processed
|
54
|
-
end
|
55
|
-
|
56
|
-
def build_packet(cmd, fields = [])
|
57
|
-
String.new.tap() do |frame|
|
58
|
-
frame << STX
|
59
|
-
frame << sequence_number
|
60
|
-
frame << cmd
|
61
|
-
fields.each do |field|
|
62
|
-
frame << SEP
|
63
|
-
frame << field
|
64
|
-
end
|
65
|
-
frame << ETX
|
66
|
-
frame << bcc(frame)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
def bcc(buffer)
|
72
|
-
sum = 0
|
73
|
-
buffer.each_byte do |b|
|
74
|
-
sum += b
|
75
|
-
end
|
76
|
-
sum.to_s(16).rjust(4, '0')
|
77
|
-
end
|
78
|
-
|
79
|
-
def sequence_number(increment = true)
|
80
|
-
@seq ||= 0x20
|
81
|
-
@seq += 1 if increment
|
82
|
-
@seq = 0x20 if @seq == 0x7f
|
83
|
-
@seq
|
84
|
-
end
|
85
|
-
|
86
|
-
class Frame
|
87
|
-
include ActiveModel::Validations
|
88
|
-
attr_reader :frame, :seq, :cmd, :fields_data, :fields, :bcc
|
89
|
-
|
90
|
-
def initialize(buffer)
|
91
|
-
if match = buffer.match(/\x02([\x20-\x7F])([\x30-\xaf])\x1c(.*)\x03(.{4})/n)
|
92
|
-
@frame = match.to_a.first
|
93
|
-
@seq, @cmd, @fileds_data, @bcc = match.captures
|
94
|
-
@fields = @fields_data.split("\x1c")
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'extface/driver/epson/esc_pos'
|
2
|
-
require 'extface/driver/epson/fiscal'
|
3
|
-
module Extface
|
4
|
-
class Driver::EpsonTmU220 < Driver::GenericPos
|
5
|
-
NAME = 'Epson TM-U220 (Serial)'.freeze
|
6
|
-
GROUP = Extface::FISCAL_DRIVER
|
7
|
-
|
8
|
-
DEVELOPMENT = true #driver is not ready for production (not passing all tests or has major bugs)
|
9
|
-
|
10
|
-
# Select driver features
|
11
|
-
RAW = true #responds to #push(data) and #pull
|
12
|
-
PRINT = true #POS, slip printers
|
13
|
-
FISCAL = true #cash registers, fiscal printers
|
14
|
-
REPORT = false #only transmit data that must be parsed by handler, CDR, report devices
|
15
|
-
|
16
|
-
has_serial_config
|
17
|
-
|
18
|
-
include Extface::Driver::Epson::EscPos
|
19
|
-
include Extface::Driver::Epson::Fiscal
|
20
|
-
end
|
21
|
-
end
|