client_for_poslynx 0.3.0 → 0.9.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.
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