Class: Extface::Driver::DaisyFx1200

Inherits:
Extface::Driver show all
Includes:
Extface::Driver::Daisy::CommandsFx1200
Defined in:
app/models/extface/driver/daisy_fx1200.rb

Defined Under Namespace

Classes: RespFrame

Constant Summary collapse

NAME =
'Daisy FX1200 (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
TAX_GROUPS_MAP =

seconds

{
  1 => "\xc0",
  2 => "\xc1",
  3 => "\xc2",
  4 => "\xc3",
  5 => "\xc4",
  6 => "\xc5",
  7 => "\xc6",
  8 => "\xc7"
}

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

#autocut(partial = true) ⇒ Object

return “P” - success, “F” - failed



58
59
60
61
# File 'app/models/extface/driver/daisy_fx1200.rb', line 58

def autocut(partial = true) # return "P" - success, "F" - failed
  resp = fsend(Printer::CUT)
  resp == "P"
end

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



139
140
141
142
143
144
145
146
147
148
149
150
# File 'app/models/extface/driver/daisy_fx1200.rb', line 139

def build_packet(cmd, data = "")
  String.new.tap() do |packet|
    packet << STX
    packet << 0x20 + 4 + data.length
    packet << sequence_number
    packet << cmd
    packet << data
    packet << PA1
    packet << bcc(packet[1..-1])
    packet << ETX
  end
end

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



83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/models/extface/driver/daisy_fx1200.rb', line 83

def build_sale_data(price, text1 = nil, text2 = nil, tax_group = 2, qty = nil, percent = nil, neto = nil)
  "".tap() do |data|
    data << text1 unless text1.blank?
    data << "\x0a#{text2}" unless text2.blank?
    data << "\t"
    data << TAX_GROUPS_MAP[tax_group || 2]
    data << price.to_s
    data << "*#{qty.to_s}" unless qty.blank?
    data << ",#{percent}" unless percent.blank?
    data << "$#{neto}" unless neto.blank?
  end
end

#cancel_doc_sessionObject



125
126
127
128
129
130
131
# File 'app/models/extface/driver/daisy_fx1200.rb', line 125

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_statusObject



133
134
135
136
137
# File 'app/models/extface/driver/daisy_fx1200.rb', line 133

def check_status
  flush
  fsend(Info::STATUS) # return 6 byte status
  errors.empty?
end

#fiscal_testObject



77
78
79
80
81
# File 'app/models/extface/driver/daisy_fx1200.rb', line 77

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

#frecv(timeout) ⇒ Object

return RespFrame or nil



178
179
180
181
182
183
184
185
# File 'app/models/extface/driver/daisy_fx1200.rb', line 178

def frecv(timeout) # return RespFrame or nil
  if frame_bytes = pull(timeout)
    return RespFrame.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



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/models/extface/driver/daisy_fx1200.rb', line 161

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
      end
    end
    errors.add :base, "#{INVALID_FRAME_RETRIES} Broken Packets Received. Abort!"
  end
  return result
end

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

return data or raise



152
153
154
155
156
157
158
159
# File 'app/models/extface/driver/daisy_fx1200.rb', line 152

def fsend!(cmd, data = "") # return data or raise
  push build_packet(cmd, data) # return 6 byte status
  if resp = frecv(RESPONSE_TIMEOUT)
    return resp.data if resp.valid?
  else
    raise errors.full_messages.join(', ')
  end
end

#handle(buffer) ⇒ Object

buffer is filled with multiple pushes, wait for full frame (ACKs)STX..PA2..PA1..ETX



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/models/extface/driver/daisy_fx1200.rb', line 44

def handle(buffer) #buffer is filled with multiple pushes, wait for full frame (ACKs)STX..PA2..PA1..ETX
  if buffer[/^\x16+$/] # skip if only ACKs
    return buffer.length 
  else
    if frame_len = buffer.index("\x03") || buffer.index("\x15")
      rpush buffer[0..frame_len]
      return frame_len+1 # return number of bytes processed
    else
      #TODO check buffer.length
      return 0 #no bytes processed
    end
  end
end

#non_fiscal_testObject



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/extface/driver/daisy_fx1200.rb', line 63

def non_fiscal_test
  device.session("Non Fiscal Text") do |s|
    s.notify "Printing Non Fiscal Text"
    s.fsend Sales::START_NON_FISCAL_DOC
    s.fsend Sales::PRINT_NON_FISCAL_TEXT, "********************************"
    s.fsend Sales::PRINT_NON_FISCAL_TEXT, "Extface Print Test".center(32)
    s.fsend Sales::PRINT_NON_FISCAL_TEXT, "********************************"
    s.fsend Printer::MOVE, "1"
    s.fsend Sales::PRINT_NON_FISCAL_TEXT, "Driver: " + "#{self.class::NAME}".truncate(24)
    s.fsend Sales::END_NON_FISCAL_DOC
    s.notify "Printing finished"
  end
end

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



96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/extface/driver/daisy_fx1200.rb', line 96

def sale_and_pay_items_session(items = [], operator = "1", password = "1")
  device.session("Fiscal Doc") do |s|
    s.notify "Fiscal Doc Start"
    s.fsend Sales::START_FISCAL_DOC, "#{operator || "1"},#{password || "1"},00001"
    items.each do |item|
      s.fsend Sales::SALE_AND_SHOW, build_sale_data(item[:price], item[:text1], item[:text2], item[:tax_group], item[:qty], item[:percent], item[:neto])
    end
    s.fsend(Sales::TOTAL, "\t")
    s.fsend(Sales::END_FISCAL_DOC)
    s.notify "Fiscal Doc End"
  end
end

#x_report_sessionObject



117
118
119
120
121
122
123
# File 'app/models/extface/driver/daisy_fx1200.rb', line 117

def x_report_session
  device.session("X Report") do |s|
    s.notify "X Report Start"
    s.fsend Closure::DAY_FIN_REPORT, "2"
    s.notify "X Report End"
  end
end

#z_report_sessionObject



109
110
111
112
113
114
115
# File 'app/models/extface/driver/daisy_fx1200.rb', line 109

def z_report_session
  device.session("Z Report") do |s|
    s.notify "Z Report Start"
    s.fsend Closure::DAY_FIN_REPORT, "0"
    s.notify "Z Report End"
  end
end