Class: Extface::Driver::DaisyFx1200

Inherits:
Base::Fiscal
  • Object
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
RESPONSE_TIMEOUT =

seconds

3
INVALID_FRAME_RETRIES =

count (bad length, bad checksum)

6
ACKS_MAX_WAIT =

count / nothing is forever

60
NAKS_MAX_COUNT =

count

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

Instance Method Summary collapse

Instance Method Details

#add_comment(text) ⇒ Object



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

def add_comment(text)
  raise "Not in fiscal session" unless @fiscal_session
end

#add_payment(type_num) ⇒ Object



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

def add_payment(type_num)
  raise "Not in fiscal session" unless @fiscal_session
end

#add_sale(sale_item) ⇒ Object



116
117
118
119
# File 'app/models/extface/driver/daisy_fx1200.rb', line 116

def add_sale(sale_item)
  raise "Not in fiscal session" unless @fiscal_session
  fsend Sales::SALE_AND_SHOW, build_sale_data(sale_item)
end

#autocut(partial = true) ⇒ Object

other



161
162
163
164
# File 'app/models/extface/driver/daisy_fx1200.rb', line 161

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

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



173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/extface/driver/daisy_fx1200.rb', line 173

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

#cancel_doc_session ⇒ Object



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

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

#check_status ⇒ Object

auto called for session, return true for OK



167
168
169
170
171
# File 'app/models/extface/driver/daisy_fx1200.rb', line 167

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

#close_fiscal_doc ⇒ Object



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

def close_fiscal_doc
  raise "Not in fiscal session" unless @fiscal_session
  fsend Sales::END_FISCAL_DOC
  @fiscal_session = false
end

#close_non_fiscal_doc ⇒ Object



99
100
101
102
# File 'app/models/extface/driver/daisy_fx1200.rb', line 99

def close_non_fiscal_doc
  fsend Sales::END_NON_FISCAL_DOC
  @print_session = false
end

#fiscal_test ⇒ Object



62
63
64
65
66
# File 'app/models/extface/driver/daisy_fx1200.rb', line 62

def fiscal_test
  sale_and_pay_items_session([
    SaleItem.new( price: 0.01, text1: "Extface Test" )
  ])
end

#frecv(timeout) ⇒ Object

return RespFrame or nil



225
226
227
228
229
230
231
232
# File 'app/models/extface/driver/daisy_fx1200.rb', line 225

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



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'app/models/extface/driver/daisy_fx1200.rb', line 186

def fsend(cmd, data = "") #return data or nil
  packet_data = build_packet(cmd, data)
  result = false
  invalid_frames = 0
  nak_messages = 0
  push packet_data
  ACKS_MAX_WAIT.times do |retries|
    errors.clear
    if resp = frecv(RESPONSE_TIMEOUT)
      if resp.valid?
        human_status_errors(resp.status)
        if errors.empty?
          result = resp.data
          break
        else
          raise errors.full_messages.join(',')
        end
      else #ack, nak or bad
        if resp.nak?
          nak_messages += 1
          if nak_messages > NAKS_MAX_COUNT
            errors.add :base, "#{NAKS_MAX_COUNT} NAKs Received. Abort!"
            break
          end
        elsif !resp.ack?
          invalid_frames += 1
          if nak_messages > INVALID_FRAME_RETRIES
            errors.add :base, "#{INVALID_FRAME_RETRIES} Broken Packets Received. Abort!"
            break
          end
        end
        push packet_data unless resp.ack?
      end
    end
    errors.add :base, "#{ACKS_MAX_WAIT} ACKs Received. Abort!"
  end
  return result
end

#handle(buffer) ⇒ Object

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



37
38
39
40
41
42
43
44
45
# File 'app/models/extface/driver/daisy_fx1200.rb', line 37

def handle(buffer) #buffer is filled with multiple pushes, wait for full frame (ACKs)STX..PA2..PA1..ETX
  if frame_len = buffer.index("\x03") || buffer.index("\x16") || 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

#non_fiscal_test ⇒ Object

tests



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/models/extface/driver/daisy_fx1200.rb', line 48

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

#open_fiscal_doc(operator = "1", password = "1") ⇒ Object

fiscal



105
106
107
108
# File 'app/models/extface/driver/daisy_fx1200.rb', line 105

def open_fiscal_doc(operator = "1", password = "1")
  fsend Sales::START_FISCAL_DOC, "#{operator.presence || "1"},#{password.presence || "1"},00001"
  @fiscal_session = true
end

#open_non_fiscal_doc ⇒ Object

print



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

def open_non_fiscal_doc
  fsend Sales::START_NON_FISCAL_DOC
  @print_session = true
end

#period_report_session(from, to, detailed = true) ⇒ Object



85
86
# File 'app/models/extface/driver/daisy_fx1200.rb', line 85

def period_report_session(from, to, detailed = true)
end


94
95
96
97
# File 'app/models/extface/driver/daisy_fx1200.rb', line 94

def print(text)
  raise "Not in print session" unless @print_session
  fsend Sales::PRINT_NON_FISCAL_TEXT, text
end

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

basket



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

def sale_and_pay_items_session(items = [], operator = "1", password = "1")
  device.session("Fiscal Doc") do |s|
    s.notify "Fiscal Doc Start"
    s.open_fiscal_doc
    s.notify "Register Sale"
    items.each do |item|
      s.add_sale(item)
    end
    s.notify "Register Payment"
    s.total_payment
    s.notify "Close Fiscal Receipt"
    s.close_fiscal_doc
    s.notify "Fiscal Doc End"
  end
end

#total_payment ⇒ Object



129
130
131
132
# File 'app/models/extface/driver/daisy_fx1200.rb', line 129

def total_payment
  raise "Not in fiscal session" unless @fiscal_session
  fsend(Sales::TOTAL, "\t")
end

#x_report_session ⇒ Object



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

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_session ⇒ Object

reports



69
70
71
72
73
74
75
# File 'app/models/extface/driver/daisy_fx1200.rb', line 69

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