client_for_poslynx 0.3.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG +12 -0
  3. data/README.md +163 -36
  4. data/TODO.txt +6 -0
  5. data/bin/fake_pos_terminal +1 -1
  6. data/client_for_poslynx.gemspec +3 -1
  7. data/lib/client_for_poslynx/data/abstract_data.rb +4 -0
  8. data/lib/client_for_poslynx/data/requests/abstract_request.rb +4 -0
  9. data/lib/client_for_poslynx/data/requests/can_visit.rb +1 -0
  10. data/lib/client_for_poslynx/data/requests/pin_pad_reset.rb +17 -0
  11. data/lib/client_for_poslynx/data/requests.rb +1 -0
  12. data/lib/client_for_poslynx/data/responses/abstract_response.rb +4 -0
  13. data/lib/client_for_poslynx/data/responses/pin_pad_reset.rb +17 -0
  14. data/lib/client_for_poslynx/data/responses.rb +1 -0
  15. data/lib/client_for_poslynx/example_request_factory.rb +96 -0
  16. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/content_formatter.rb +75 -0
  17. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/is_ui_component.rb +169 -0
  18. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_handler.rb +66 -0
  19. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/abstract_processor.rb +41 -0
  20. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/credit_card_sale_processor.rb +87 -0
  21. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/debit_card_sale_processor.rb +79 -0
  22. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_display_message_processor.rb +43 -0
  23. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_display_specified_form_processor.rb +56 -0
  24. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_initialize_processor.rb +21 -0
  25. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_reset_processor.rb +21 -0
  26. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/processes_card_sale.rb +118 -0
  27. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/unsupported_processor.rb +20 -0
  28. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors.rb +22 -0
  29. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/term_manipulator.rb +35 -0
  30. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/ui_context.rb +21 -0
  31. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_button_number_selection_fetcher.rb +50 -0
  32. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_raw_text_line_fetcher.rb +49 -0
  33. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_text_line_fetcher.rb +55 -0
  34. data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface.rb +41 -195
  35. data/lib/client_for_poslynx/fake_pos_terminal/context.rb +10 -0
  36. data/lib/client_for_poslynx/fake_pos_terminal/keyboard_handler.rb +35 -0
  37. data/lib/client_for_poslynx/fake_pos_terminal/net_handler.rb +53 -0
  38. data/lib/client_for_poslynx/fake_pos_terminal/result_assemblers/card_sale_receipt.rb +1 -1
  39. data/lib/client_for_poslynx/fake_pos_terminal/{format.rb → value_formatting.rb} +1 -1
  40. data/lib/client_for_poslynx/fake_pos_terminal.rb +32 -8
  41. data/lib/client_for_poslynx/message_handling/xml_extractor.rb +4 -0
  42. data/lib/client_for_poslynx/message_handling/xml_lines_buffer.rb +35 -0
  43. data/lib/client_for_poslynx/message_handling.rb +1 -0
  44. data/lib/client_for_poslynx/net/em_protocol.rb +46 -0
  45. data/lib/client_for_poslynx/net/structured_client/em_connection.rb +72 -0
  46. data/lib/client_for_poslynx/net/structured_client.rb +104 -0
  47. data/lib/client_for_poslynx/net.rb +11 -0
  48. data/lib/client_for_poslynx/version.rb +1 -1
  49. data/lib/client_for_poslynx.rb +2 -0
  50. data/spec/client_for_poslynx/data/requests/credit_card_sale_spec.rb +1 -1
  51. data/spec/client_for_poslynx/data/requests/debit_card_sale_spec.rb +1 -1
  52. data/spec/client_for_poslynx/data/requests/pin_pad_display_message_spec.rb +1 -1
  53. data/spec/client_for_poslynx/data/requests/pin_pad_display_specified_form_spec.rb +1 -1
  54. data/spec/client_for_poslynx/data/requests/pin_pad_get_signature_spec.rb +1 -1
  55. data/spec/client_for_poslynx/data/requests/pin_pad_initialize_spec.rb +1 -1
  56. data/spec/client_for_poslynx/data/requests/pin_pad_reset_spec.rb +53 -0
  57. data/spec/client_for_poslynx/data/responses/credit_card_sale_spec.rb +1 -1
  58. data/spec/client_for_poslynx/data/responses/debit_card_sale_spec.rb +1 -1
  59. data/spec/client_for_poslynx/data/responses/pin_pad_display_message_spec.rb +1 -1
  60. data/spec/client_for_poslynx/data/responses/pin_pad_display_specified_form_spec.rb +1 -1
  61. data/spec/client_for_poslynx/data/responses/pin_pad_initialize_spec.rb +1 -1
  62. data/spec/client_for_poslynx/data/responses/pin_pad_reset_spec.rb +64 -0
  63. data/spec/client_for_poslynx/net/em_protocol_spec.rb +52 -0
  64. data/spec/client_for_poslynx/net/structured_client_spec.rb +118 -0
  65. data/spec/support/shared_examples.rb +22 -0
  66. data/spec/support/test_tcp_server.rb +163 -0
  67. metadata +75 -20
  68. data/bin/poslynx_client_console +0 -105
  69. data/lib/client_for_poslynx/fake_pos_terminal/request_dispatcher.rb +0 -36
  70. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/abstract_handler.rb +0 -38
  71. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/credit_card_sale.rb +0 -63
  72. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/debit_card_sale.rb +0 -54
  73. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/handles_card_sale.rb +0 -93
  74. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_display_message.rb +0 -35
  75. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_display_specified_form.rb +0 -49
  76. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_initialize.rb +0 -19
  77. data/lib/client_for_poslynx/fake_pos_terminal/request_handlers.rb +0 -18
  78. data/lib/client_for_poslynx/fake_pos_terminal/server.rb +0 -65
  79. data/lib/client_for_poslynx/has_client_console_support.rb +0 -109
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDIyYTM1NTlkMTFhYTllNzI4ZDNlZjBlMGJjY2E3MzcxNjQ1ODJmNA==
4
+ OGRhYTY1N2JmMWVkZmVlNzA3MzM3MTBmYjY5YzVhMTE2YTE5YjQ5Mg==
5
5
  data.tar.gz: !binary |-
6
- ZGM2ODlhZmQ2ZDZiMWM5ODkwM2QyNjc4MTdmMzFhMGU4OTVkYmNmZg==
6
+ N2YxY2IzMTUzODE1NjI2OGEwOWE3ZTFiYzVhMTMzY2IzOGExZTRhNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDE0NDIxOTM5NWI3YTU5OTg5OGM2ZDRhYzMzNDcxNzdkMzQ1NGY2OGQ2MTNl
10
- ZDk5ZjBiZTVjMzE2Mzc0ZGRkM2JjZmFjZjBkZWEzOGYyOTM0N2RhYWE4ZDM0
11
- ZGE2YjYzOWU1OGE0MzkyMzQwYTIwYWI4NjQzZmYwMjJiNTMyYmE=
9
+ MGRlY2MwMTgxMWU3YWExNGIxODE4MDI3NThkZDZjMTkwMmVjM2Y2MDk1MjQ4
10
+ MTRmODhhYjcxN2VmY2FkOWMwYTU5MjI4MTZmYTY4YTE1MzI3MzIzZDRkNmNm
11
+ MDRmMGE5ZTZjZDM0YTQ0NzFiNmY0N2ZmMTFiZWFiMTY1MmYxOGI=
12
12
  data.tar.gz: !binary |-
13
- NzA1ZmFiMDc1MDYyNTc4NTQyODZjZGNlZWI5N2U2OWE2NzkzNjM4MjYxZjBm
14
- MjYzMmM5NDZjMjY3MTBmNGQyYjdlYWU0NDk1NWE3MjZiZTJhMmJlZjQyZmYz
15
- YjA1NmJlNGUyOTIzNTY1MGMyYTQyNzY4MGZlMDE3YzFhYWQzMTM=
13
+ ZjVkODM0YThiMzZlZDFkM2QwZDhlMDY5MDAwMTk1YTUyYzEzNDIxMzQ1YzIw
14
+ YWNhOWNkZWRiZWM0YjY2MGE3NzY2NmNhOWM1MzRjYTc5MTM1ZmFiMGJkZDVl
15
+ MTYyMGU1OTliMWM2MDRlMGZhZDEzZjNiYzBhNDQ1NzhiZTU0NjI=
data/CHANGELOG CHANGED
@@ -43,3 +43,15 @@ Version 0.3.0
43
43
  - Change word separators in poslynx_client_console from under-
44
44
  scores to dashes.
45
45
  - Fake Poslynx includes signature image data in response.
46
+
47
+ Version 0.9.0
48
+ - Add a network client in the form of an EventManager protocol.
49
+ - Add a structured network client for use from within an irb
50
+ console.
51
+ - Add ExampleRequestFactory class.
52
+ - Remove the client console script aince the structured client
53
+ example request factory now provide the same capabilities from
54
+ within any irb session.
55
+ - Overhaul the fake pos terminal script to be based on
56
+ EventMachine and to allow request processing to be interrupted
57
+ by the receipt of a new request.
data/README.md CHANGED
@@ -9,52 +9,179 @@ Technologies.
9
9
  Features:
10
10
 
11
11
  * Data models for requests and responses.
12
- * Writing requests to output streams.
13
- * Reading responses from input streams.
12
+ * Network interaction using an EventMachine protocol.
13
+ * Simplified network interaction using a structured client
14
+ adapter.
14
15
  * A fake POSLynx appliance + PIN Pad script.
15
- * A POSLynx client console script.
16
16
 
17
- The best introduction to this gem is probably to play around with
18
- with the POSLynx client console. Assuming you have a POSLynx
19
- unit with IP address 192.168.1.123, listening on port 54321 using
20
- SSL encryption, with a registered client MAC of 000000000000, an
21
- example poslynx client session might look like...
22
-
23
- $ bundle exec poslynx_client_console 173.195.60.144:14270 --use-ssl --client_mac=000000000000
24
- 1.9.3-p545 :001 > req = poslynx_client.example_pin_pad_display_message_request
25
- => #<ClientForPoslynx::Data::Requests::PinPadDisplayMessage:0x007f941b4b1fe8 @client_mac="001C42E644FE", @text_lines=["First example line", "Second example line"], @line_count=2, @button_labels=["1st of optional buttons", "2nd button"]>
26
- 1.9.3-p545 :002 > resp = poslynx_client.send_request(req)
27
- <?xml version="1.0" standalone="yes" ?><PLResponse><Command>PPDISPLAY</Command><Result>Success</Result><ResultText>Success</ResultText><Response>2nd button</Response></PLResponse>
28
- => #<ClientForPoslynx::Data::Responses::PinPadDisplayMessage:0x007f941b4b8230 @result="Success", @result_text="Success", @button_response="2nd button", @source_data="<?xml version=\"1.0\" standalone=\"yes\" ?><PLResponse><Command>PPDISPLAY</Command><Result>Success</Result><ResultText>Success</ResultText><Response>2nd button</Response></PLResponse>\r\n">
29
-
30
- This gem also provides a fake POS/terminal application that you
31
- can run in a separate console window when you are working without
32
- access to an actual POSLynx unit and PIN pad. To start the fake
33
- POS/terminal listening on port 3010...
34
-
35
- bundle exec fake_pos_terminal 3010
36
-
37
- If you then want to start the client console to interact with the
38
- fake POS/terminal instance on the same machine...
39
-
40
- bundle exec poslynx_client_console :3010
17
+ ## Overview
18
+
19
+ The `client_for_poslynx` gem provides network adapters that can
20
+ be used to send requests to a POSLynx unit and receive the
21
+ responses to those requests. The gem also includes data models
22
+ with XML serialization/deserialization that are used by those
23
+ network adapters or may be used as part of a different network
24
+ adapter if you prefer to build your own.
25
+
26
+ The first network adapter provided is in the form of a protocol
27
+ for EventMachine. EventMachine is a gem for implementing
28
+ event-driven communication clients and servers. Essentially,
29
+ being event-driven means that requests are sent and responses are
30
+ received asynchronously. The application receives a call-back
31
+ when the server responds or the connection is lost, etc.
32
+
33
+ The second network adapter this gem provides is a "structured"
34
+ (as opposed to event-driven) API. This is primarily provided
35
+ as a convenience for use in situations where the event-driven
36
+ API is inconvenient, such as when experimenting with the gem
37
+ from an irb command line session.
38
+
39
+ In addition to the network client libraries, this gem includes
40
+ a script that acts as a fake POSLynx + PIN Pad. This is useful
41
+ when you are working without access to an actual POSLynx and
42
+ PIN Pad, and want to test your client code and try out
43
+ workflows. This script will probably be extracted into a
44
+ separate gem soon.
41
45
 
42
46
  ## Usage
43
47
 
44
- The code in the
45
- lib/client_for_poslynx/has_client_console_support.rb file
46
- provides a good example of how to use the facilities that this
47
- gem provides.
48
-
49
- Some releases may also include experimental features that must
50
- be separately loaded by requiring "client_for_poslynx/experimental'.
48
+ ### Using the structured client
49
+
50
+ A quick and easy way to try out this gem is to use the structured
51
+ client and example-request factory from an irb console.
52
+
53
+ Assuming you have a POSLynx host running at 192.168.1.99 on port
54
+ 1234 with SSL required, and if your lane has a registered client
55
+ MAC value of 123456789ABC, then with the client_for_poslynx gem
56
+ installed, you should be able to execute a sequence similar to
57
+ the following.
58
+
59
+ $ irb
60
+ 1.9.3-p545 :001 > require 'client_for_poslynx'
61
+ => true
62
+ 1.9.3-p545 :002 > client = ClientForPoslynx::Net::StructuredClient.new('192.168.1.99', 1234, true)
63
+ => #<ClientForPoslynx::Net::StructuredClient:0x007fefa2103aa8 @directive_queue=#<Queue:0x007fefa21039e0 @que=[], @waiting=[], @mutex=#<Mutex:0x007fefa2103968>>, @activity_queue=#<Queue:0x007fefa2103940 @que=[], @waiting=[], @mutex=#<Mutex:0x007fefa2103300>>, @em_thread=#<Thread:0x007fefa2103260 sleep>>
64
+ 1.9.3-p545 :003 > reqf = ClientForPoslynx::ExampleRequestFactory.new('1234567890ABC')
65
+ => #<ClientForPoslynx::ExampleRequestFactory:0x007fefa2036030 @client_mac="1234567890ABC">
66
+ 1.9.3-p545 :004 > req = reqf.pin_pad_initialize_request
67
+ => #<ClientForPoslynx::Data::Requests::PinPadInitialize:0x007fefa204f760 @client_mac="1234567890ABC", @idle_prompt="Example idle prompt">
68
+ 1.9.3-p545 :005 > client.send_request req
69
+ => nil
70
+ 1.9.3-p545 :006 > client.get_response
71
+ => #<ClientForPoslynx::Data::Responses::PinPadInitialize:0x007fefa21106e0 @result="Success", @result_text="PinPad Initialized", @error_code="1000", @source_data="<?xml version=\"1.0\" standalone=\"yes\" ?><PLResponse><Command>PPINIT</Command><Result>Success</Result><ResultText>PinPad Initialized</ResultText><ErrorCode>1000</ErrorCode></PLResponse>">
72
+ 1.9.3-p545 :007 > client.end_session
73
+ => nil
74
+
75
+ ### Using the EventMachine protocol
76
+
77
+ The following example code demonstrates how to write an
78
+ event-driven client using EventMachine and the POSLynx protocol
79
+ for EventMachine.
80
+
81
+ require 'client_for_poslynx'
82
+
83
+ HOST = '192.168.1.25'
84
+ PORT = 12345
85
+ CLIENT_MAC = '000000000000'
86
+ USE_SSL = true
87
+
88
+ class ButtonSelectionDemo < EM::Connection
89
+ include EM::Protocols::POSLynx
90
+
91
+ def connection_completed
92
+ puts "IP connection has been opened"
93
+ if USE_SSL
94
+ puts "Starting SSL"
95
+ start_tls verify_peer: false
96
+ else
97
+ puts "Using raw connection. No SSL"
98
+ display_the_message
99
+ end
100
+ end
101
+
102
+ def ssl_handshake_completed
103
+ puts "SSL session has been successfully started"
104
+ display_the_message
105
+ end
106
+
107
+ def display_the_message
108
+ puts "Sending the PIN Pad Display Message request"
109
+
110
+ req = ClientForPoslynx::Data::Requests::PinPadDisplayMessage.new
111
+ req.client_mac = CLIENT_MAC
112
+ req.line_count = 2
113
+ req.text_lines = [
114
+ "Heads, we clean the basement",
115
+ "Tails, we go to the movies"
116
+ ]
117
+ req.button_labels = %w[ Heads Tails ]
118
+
119
+ send_request req
120
+ end
121
+
122
+ def receive_response(response)
123
+ puts "Received response from POSLynx"
124
+ puts "Result text: #{response.result_text}"
125
+ puts "Selected button: #{response.button_response}"
126
+
127
+ puts "Closing the connection"
128
+ close_connection
129
+ end
130
+
131
+ def unbind
132
+ puts "The connection has been closed"
133
+ puts "Terminating the event loop"
134
+ EM.stop_event_loop
135
+ end
136
+
137
+ end
138
+
139
+ # This code will block until the event loop exits.
140
+ EM.run do
141
+ EM.connect HOST, PORT, ButtonSelectionDemo
142
+ EM.error_handler do |e|
143
+ raise e
144
+ end
145
+ end
146
+
147
+ puts "The event loop has ended"
148
+ puts "Bye"
149
+
150
+ # == Sample output ==
151
+ # IP connection has been opened
152
+ # Starting SSL
153
+ # SSL session has been successfully started
154
+ # Sending the PIN Pad Display Message request
155
+ # Received response from POSLynx
156
+ # Result text: Success
157
+ # Selected button: Tails
158
+ # Closing the connection
159
+ # The connection has been closed
160
+ # Terminating the event loop
161
+ # The event loop has ended
162
+ # Bye
163
+
164
+ ### Using the `fake_pos_terminal` script
165
+
166
+ The `fake_pos_terminal` script runs a console-based facsimile of
167
+ a PIN pad connected to a POSLynx device, listening on a local TCP
168
+ port. The script takes a single parameter indicating the port
169
+ number to listen on.
170
+
171
+ Under some circumstances, if you have installed the
172
+ `client_for_poslynx` gem using Bundler, you might need to use
173
+ `bundle exec` to run the script.
174
+
175
+ To run the script listening on port 3010 using `bundle exec`:
176
+
177
+ $ bundle exec fake_pos_terminal 3010
178
+
179
+ To stop the script, send an interrupt signal by pressing Ctrl+C.
51
180
 
52
181
  ## Known Limitations
53
182
 
54
183
  * Only a subset of the possible messages and elements is supported.
55
184
  __More will be added. Contributions are welcome and encouraged. :)__
56
- * Performs serialization of requests and parsing of responses, but
57
- does not encapsulate actually making TCP connections and requests.
58
185
 
59
186
  ## Installation
60
187
 
data/TODO.txt ADDED
@@ -0,0 +1,6 @@
1
+ ClientForPoslynx Gem development to-do items
2
+ ============================================
3
+
4
+ Extract the fake POS terminal into a separate gem since it
5
+ introduces Gem dependencies that ClientForPoslynx does not
6
+ otherwise have.
@@ -12,7 +12,7 @@ end
12
12
  # file name for input.
13
13
  $*.replace []
14
14
 
15
- # The only option we car about is --help, so we either show usage
15
+ # The only option we care about is --help, so we either show usage
16
16
  # for --help or because an unrecognized option was given.
17
17
  show_usage = option_args.length > 0
18
18
 
@@ -22,8 +22,10 @@ Gem::Specification.new do |spec|
22
22
  spec.required_ruby_version = '>= 1.9.3'
23
23
 
24
24
  spec.add_dependency 'nokogiri', "~> 1.5"
25
+ spec.add_dependency 'eventmachine', "~> 1.0.0"
26
+ spec.add_dependency 'ruby-termios'
25
27
 
26
28
  spec.add_development_dependency "bundler", "~> 1.6"
27
29
  spec.add_development_dependency "rake"
28
- spec.add_development_dependency "rspec"
30
+ spec.add_development_dependency "rspec", "~> 3.0"
29
31
  end
@@ -16,6 +16,10 @@ module ClientForPoslynx
16
16
  blank_new
17
17
  end
18
18
 
19
+ def short_name
20
+ name.split( '::' ).last
21
+ end
22
+
19
23
  def xml_parse(source_xml)
20
24
  doc = XmlDocument.from_xml( source_xml )
21
25
  data_class = concrete_data_class_for_nokogiri_document( doc )
@@ -14,6 +14,10 @@ module ClientForPoslynx
14
14
  instance
15
15
  end
16
16
 
17
+ def self.response_class
18
+ Data::Responses.const_get( short_name )
19
+ end
20
+
17
21
  def self.root_element_name
18
22
  ROOT_ELEMENT_NAME
19
23
  end
@@ -9,6 +9,7 @@ module ClientForPoslynx
9
9
  def visit_CreditCardSale(visitee) ; visit_general visitee ; end
10
10
  def visit_DebitCardSale(visitee) ; visit_general visitee ; end
11
11
  def visit_PinPadInitialize(visitee) ; visit_general visitee ; end
12
+ def visit_PinPadReset(visitee) ; visit_general visitee ; end
12
13
  def visit_PinPadDisplayMessage(visitee) ; visit_general visitee ; end
13
14
  def visit_PinPadDisplaySpecifiedForm(visitee) ; visit_general visitee ; end
14
15
  def visit_PinPadGetSignature(visitee) ; visit_general visitee ; end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+
3
+ require_relative 'abstract_request'
4
+
5
+ module ClientForPoslynx
6
+ module Data
7
+ module Requests
8
+
9
+ class PinPadReset < AbstractRequest
10
+
11
+ defining_property_value attribute: :command, element: 'Command', value: 'PPRESET'
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,7 @@ require_relative 'requests/pin_pad_initialize'
6
6
  require_relative 'requests/pin_pad_display_message'
7
7
  require_relative 'requests/pin_pad_display_specified_form'
8
8
  require_relative 'requests/pin_pad_get_signature'
9
+ require_relative 'requests/pin_pad_reset'
9
10
  require_relative 'requests/can_visit'
10
11
 
11
12
  module ClientForPoslynx
@@ -8,6 +8,10 @@ module ClientForPoslynx
8
8
 
9
9
  class AbstractResponse < AbstractData
10
10
 
11
+ def self.request_class
12
+ Data::Requests.const_get( short_name )
13
+ end
14
+
11
15
  def self.root_element_name
12
16
  ROOT_ELEMENT_NAME
13
17
  end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+
3
+ require_relative 'abstract_response'
4
+
5
+ module ClientForPoslynx
6
+ module Data
7
+ module Responses
8
+
9
+ class PinPadReset < AbstractResponse
10
+
11
+ defining_property_value attribute: :command, element: 'Command', value: 'PPRESET'
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,7 @@ require_relative 'responses/pin_pad_initialize'
6
6
  require_relative 'responses/pin_pad_display_message'
7
7
  require_relative 'responses/pin_pad_display_specified_form'
8
8
  require_relative 'responses/pin_pad_get_signature'
9
+ require_relative 'responses/pin_pad_reset'
9
10
 
10
11
  module ClientForPoslynx
11
12
  module Data
@@ -0,0 +1,96 @@
1
+ # coding: utf-8
2
+
3
+ module ClientForPoslynx
4
+
5
+ # A class of factories for building request data instances that
6
+ # are pre-populated with example data. This is primarily useful
7
+ # for exploration and experimentation in the irb console.
8
+ class ExampleRequestFactory
9
+ attr_reader :client_mac
10
+
11
+ # Initializes a ne factory instance, optionally with a
12
+ # client_mac value to be assigned to each request-data object
13
+ # that the factory builds.
14
+ def initialize(client_mac = nil)
15
+ @client_mac = client_mac
16
+ end
17
+
18
+ def pin_pad_initialize_request
19
+ Data::Requests::PinPadInitialize.new.tap { |req|
20
+ assign_common_example_request_attrs_to req
21
+ now_text = Time.now.strftime('%H:%M:%S')
22
+ req.idle_prompt = "Example idle prompt at #{now_text}"
23
+ }
24
+ end
25
+
26
+ def pin_pad_reset_request
27
+ Data::Requests::PinPadReset.new.tap { |req|
28
+ assign_common_example_request_attrs_to req
29
+ }
30
+ end
31
+
32
+ def pin_pad_display_message_request
33
+ ClientForPoslynx::Data::Requests::PinPadDisplayMessage.new.tap { |req|
34
+ assign_common_example_request_attrs_to req
35
+ req.text_lines = [
36
+ "First example line",
37
+ "Second example line",
38
+ ]
39
+ req.line_count = 2
40
+ req.button_labels = [
41
+ "1st of optional buttons",
42
+ "2nd button",
43
+ ]
44
+ }
45
+ end
46
+
47
+ def credit_card_sale_request
48
+ ClientForPoslynx::Data::Requests::CreditCardSale.new.tap { |req|
49
+ assign_common_example_request_attrs_to req
50
+ req.merchant_supplied_id = 'INVC-123-MERCH-SUPPL'
51
+ req.amount = '101.25'
52
+ req.input_source = 'EXTERNAL'
53
+ req.capture_signature = 'Yes'
54
+ }
55
+ end
56
+
57
+ def debit_card_sale_request
58
+ ClientForPoslynx::Data::Requests::DebitCardSale.new.tap { |req|
59
+ assign_common_example_request_attrs_to req
60
+ req.merchant_supplied_id = 'INVC-123-MERCH-SUPPL'
61
+ req.amount = '101.25'
62
+ req.cash_back = '20.00'
63
+ req.input_source = 'EXTERNAL'
64
+ }
65
+ end
66
+
67
+ def pin_pad_display_specified_form_request
68
+ ClientForPoslynx::Data::Requests::PinPadDisplaySpecifiedForm.new.tap { |req|
69
+ assign_common_example_request_attrs_to req
70
+ req.form_name = 'my_special_form'
71
+ req.text_values = [
72
+ "First example text value",
73
+ "Second example text value",
74
+ ]
75
+ req.button_labels = [
76
+ "1st of optional buttons",
77
+ "2nd button"
78
+ ]
79
+ }
80
+ end
81
+
82
+ def pin_pad_get_signature
83
+ ClientForPoslynx::Data::Requests::PinPadGetSignature.new.tap { |req|
84
+ assign_common_example_request_attrs_to req
85
+ }
86
+ end
87
+
88
+ private
89
+
90
+ def assign_common_example_request_attrs_to(request)
91
+ request.client_mac = client_mac if client_mac
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,75 @@
1
+ # coding: utf-8
2
+
3
+ require 'delegate'
4
+
5
+ module ClientForPoslynx
6
+ module FakePosTerminal
7
+ class ConsoleUserInterface
8
+
9
+ module ContentFormatter
10
+ extend self
11
+
12
+ extend FakePosTerminal::ValueFormatting
13
+
14
+ def multiline_message(text_lines)
15
+ centered_lines = text_lines.map { |text| text.center(68) }
16
+ "\n" << centered_lines * "\n" << "\n\n"
17
+ end
18
+
19
+ def buttons(button_labels)
20
+ button_strings = button_labels.map { |label| "[ #{label} ]" }
21
+ tot_button_space = button_strings.map(&:length).inject{ |m, length| m + length }
22
+ tot_marginal_space = 68 - tot_button_space
23
+ padding_size = tot_marginal_space / ( button_strings.length * 2 )
24
+ padding = ' ' * padding_size
25
+ button_strings.map! { |string| padding + string + padding }
26
+ ( button_strings * '' ).center( 68 )
27
+ end
28
+
29
+ def welcome_with_idle_prompt(prompt)
30
+ '
31
+ ___ _ _ ___
32
+ | | | | | / \ / \ | | |
33
+ | | | | | | | | |\ /| |
34
+ | | | |-- | | | | | \ / | |--
35
+ | / \ | | | | | | | | | |
36
+ \/ \/ |___ |___ \_/ \_/ | | | |___
37
+
38
+ ' + " (#{prompt})\n"
39
+ end
40
+
41
+ def signature_entry_box
42
+ '
43
+
44
+ Sign here...
45
+ -----------------------------------------------------------
46
+ | |
47
+ | |
48
+ | |
49
+ -----------------------------------------------------------
50
+
51
+ '
52
+ end
53
+
54
+ def payment_confirmation(amount)
55
+ lines = []
56
+ lines << "TOTAL AMOUNT"
57
+ lines << format_usd( amount )
58
+ multiline_message(lines)
59
+ end
60
+
61
+ def card_swipe_request(request_data)
62
+ total = request_data.amount
63
+ transaction = 'PURCHASE'
64
+ lines = []
65
+ lines << "Please swipe your card"
66
+ lines << "Total: " + format_usd( total ) if total
67
+ lines << "Transaction: " + transaction
68
+ multiline_message( lines )
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+ end
75
+ end