Class: Extface::Driver::EltradeTmU220

Inherits:
Extface::Driver show all
Includes:
Extface::Driver::Eltrade::CommandsFp4
Defined in:
app/models/extface/driver/eltrade_tm_u220.rb

Defined Under Namespace

Classes: Frame, PrinterStatus

Constant Summary collapse

NAME =
'Eltrade TM-U220 (Serial)'.freeze
GROUP =
Extface::FISCAL_DRIVER
DEVELOPMENT =

driver is not ready for production (not passing all tests or has major bugs)

true
RAW =

Select driver features

true
false
FISCAL =

POS, slip printers

true
REPORT =

cash registers, fiscal printers

false
RESPONSE_TIMEOUT =

only transmit data that must be parsed by handler, CDR, report devices

3
INVALID_FRAME_RETRIES =

seconds

6
FLAG_TRUE =

seconds

"\xff\xff"
FLAG_FALSE =
"\x00\x00"

Constants inherited from Extface::Driver

DRIVER_TYPES

Instance Method Summary collapse

Methods inherited from Extface::Driver

#flush, has_serial_config, #notify, #pull, #push, #rpush, #set_job

Instance Method Details

#build_packet(cmd, data = "") ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 169

def build_packet(cmd, data = "")
  "".tap() do |packet|
    packet << STRT.b
    packet << 0x00 #address
    packet << sequence_number
    packet << cmd
    packet << data.length
    packet << data.b
    packet << check_sum(packet[2..-1])
  end
end

#build_sale_data(price, text1 = "", text2 = nil, tax_group = 2, qty = 1, percent = nil, neto = nil, number = nil) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 95

def build_sale_data(price, text1 = "", text2 = nil, tax_group = 2, qty = 1, percent = nil, neto = nil, number = nil)
  "".b.tap() do |data|
    price_units = (price * 100).to_i # !FIXME
    price_bytes = "".b
    4.times{ |shift| price_bytes.insert 0, ((price_units >> shift*8) & 0xff).chr }
    data << price_bytes
    qty_units = ((qty || 1) * 1000).to_i # !FIXME
    qty_bytes = "".b
    4.times{ |shift| qty_bytes.insert 0, ((qty_units >> shift*8) & 0xff).chr }
    data << qty_bytes
    data << "\x00".b #number len FIXME
    data << "\xAA\xAA\xAA\xAA\xAA\xAA".b #number FIXME
    text = text1.truncate(20)
    data << text.length.chr
    data << text.ljust(20, " ").b
    data << (tax_group || 2).chr
  end
end

#cancel_doc_session ⇒ Object



146
147
148
149
150
151
152
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 146

def cancel_doc_session
  device.session("Doc cancel") do |s|
    s.notify "Doc Cancel Start"
    #s.fsend Sales::CANCEL_DOC
    s.notify "Doc Cancel End"
  end
end

#check_status ⇒ Object



163
164
165
166
167
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 163

def check_status
  flush
  fsend(Info::GET_STATUS)
  errors.empty?
end

#check_sum(buffer) ⇒ Object



211
212
213
214
215
216
217
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 211

def check_sum(buffer)
  sum = 0
  buffer.each_byte do |byte|
    sum -= byte
  end
  sum & 0xff
end

#close_receipt ⇒ Object



50
51
52
53
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 50

def close_receipt
  fsend Receipt::CLOSE_RECEIPT
  status = printer_status!
end

#fiscal_test ⇒ Object



89
90
91
92
93
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 89

def fiscal_test
  sale_and_pay_items_session([
    { price: 0.01, text1: "Extface Test" }
  ])
end

#frecv(timeout) ⇒ Object

return RespFrame or nil



202
203
204
205
206
207
208
209
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 202

def frecv(timeout) # return RespFrame or nil
  if frame_bytes = pull(timeout)
    return Frame.new(frame_bytes.b)
  else
    errors.add :base, "No data received from device"
    return nil
  end
end

#fsend(cmd, data = "") ⇒ Object

return data or nil



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 181

def fsend(cmd, data = "") #return data or nil
  packet_data = build_packet(cmd, data)
  result = false
  INVALID_FRAME_RETRIES.times do |retries|
    errors.clear
    push packet_data
    if resp = frecv(RESPONSE_TIMEOUT)
      if resp.valid?
        result = resp.data
        break
      else
        resp.errors.full_messages.each do |msg|
          errors.add :base, msg
        end
      end
    end
    errors.add :base, "#{INVALID_FRAME_RETRIES} Broken Packets Received. Abort!"
  end
  return result
end

#handle(buffer) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 30

def handle(buffer)
  bytes_processed = 0
  if frame_match = buffer.match(/\xAA\x55.{3}(.{1}).*/nm) #m Treat \x0a as a character matched by .
    len = frame_match.captures.first.ord
    skip = frame_match.pre_match.length
    bytes_processed = skip + 7 + len # 6 pre + 1 check sum
    rpush buffer[skip..bytes_processed]
  end
  return bytes_processed
end

#non_fiscal_test ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 75

def non_fiscal_test
  device.session("Non Fiscal Text") do |s|
    s.notify "Printing Non Fiscal Text"
    s.open_receipt Receipt::Variant::START_COMMENT_RECEIPT
    s.send_comment "********************************"
    s.send_comment "Extface Print Test".center(32)
    s.send_comment "********************************"
    s.send_comment ""
    s.send_comment "Driver: " + "#{self.class::NAME}".truncate(24)
    s.close_receipt
    s.notify "Printing finished"
  end
end

#open_receipt(variant = nil) ⇒ Object



41
42
43
44
45
46
47
48
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 41

def open_receipt(variant = nil)
  fsend Receipt::OPEN_RECEIPT
  status = printer_status!
  unless variant.blank?
    fsend Receipt::PRINT_RECEIPT, variant
    status = printer_status!
  end
end

#printer_status! ⇒ Object



155
156
157
158
159
160
161
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 155

def printer_status!
  fsend Info::GET_STATUS
  raise errors.full_messages.join(", ") if errors.any?
  status = PrinterStatus.new(fsend(Info::GET_PRINTER_STATUS))
  raise errors.full_messages.join(", ") if errors.any?
  status
end

#sale_and_pay_items_session(items = [], operator = "1", password = "1") ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 114

def sale_and_pay_items_session(items = [], operator = "1", password = "1")
  device.session("Fiscal Doc") do |s|
    s.notify "Fiscal Doc Start"
    s.open_receipt
    items.each do |item|
      s.send_plu build_sale_data(item[:price], item[:text1], nil, item[:tax_group], item[:qty], nil, nil, item[:number])
      s.send_comment(item[:text2]) unless item[:text2].blank?
    end
    s.send_payment
    s.close_receipt
    s.notify "Fiscal Doc End"
  end
end

#send_comment(text) ⇒ Object



55
56
57
58
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 55

def send_comment(text)
  fsend Receipt::PRINT_RECEIPT, Receipt::Variant::COMMENT + text
  status = printer_status!
end

#send_payment(type_num = 0, value = nil) ⇒ Object

0, 1, 2, 3



65
66
67
68
69
70
71
72
73
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 65

def send_payment(type_num = 0, value = nil) # 0, 1, 2, 3
  value_bytes = "\x00\x00\x00\x00" # recalculate
  unless value.nil?
    value_units = (value * 100).to_i # !FIXME
    value_bytes = "".b
    4.times{ |shift| value_bytes.insert 0, ((value_units >> shift*8) & 0xff).chr }
  end
  fsend Receipt::PRINT_RECEIPT, "" << (9 + type_num).chr << value_bytes
end

#send_plu(plu_data) ⇒ Object



60
61
62
63
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 60

def send_plu(plu_data)
  fsend Receipt::PRINT_RECEIPT, Receipt::Variant::PLU + plu_data
  status = printer_status!
end

#x_report_session ⇒ Object



137
138
139
140
141
142
143
144
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 137

def x_report_session
  device.session("Z Report") do |s|
    s.notify "Z Report Start"
    s.fsend Reports::DAILY_REPORT, FLAG_FALSE
    status = s.printer_status!
    s.notify "Z Report End"
  end
end

#z_report_session ⇒ Object



128
129
130
131
132
133
134
135
# File 'app/models/extface/driver/eltrade_tm_u220.rb', line 128

def z_report_session
  device.session("Z Report") do |s|
    s.notify "Z Report Start"
    s.fsend Reports::DAILY_REPORT, FLAG_TRUE
    status = s.printer_status!
    s.notify "Z Report End"
  end
end