agris 0.1.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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +21 -0
  6. data/README.md +36 -0
  7. data/Rakefile +6 -0
  8. data/agris.gemspec +30 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/agris.rb +61 -0
  12. data/lib/agris/api.rb +21 -0
  13. data/lib/agris/api/accounts_payables.rb +30 -0
  14. data/lib/agris/api/accounts_receivables.rb +11 -0
  15. data/lib/agris/api/accounts_receivables/invoice.rb +166 -0
  16. data/lib/agris/api/accounts_receivables/invoices.rb +29 -0
  17. data/lib/agris/api/accounts_receivables/specific_invoice_extract.rb +17 -0
  18. data/lib/agris/api/document_query_response.rb +59 -0
  19. data/lib/agris/api/grain.rb +12 -0
  20. data/lib/agris/api/grain/new_ticket.rb +118 -0
  21. data/lib/agris/api/grain/new_ticket_application.rb +34 -0
  22. data/lib/agris/api/grain/new_ticket_remark.rb +23 -0
  23. data/lib/agris/api/grain/tickets.rb +17 -0
  24. data/lib/agris/api/inventory.rb +16 -0
  25. data/lib/agris/api/inventory/delivery_ticket.rb +84 -0
  26. data/lib/agris/api/inventory/delivery_ticket_line_item.rb +59 -0
  27. data/lib/agris/api/inventory/delivery_tickets.rb +30 -0
  28. data/lib/agris/api/inventory/orders.rb +51 -0
  29. data/lib/agris/api/inventory/specific_delivery_ticket_extract.rb +17 -0
  30. data/lib/agris/api/inventory/specific_order_extract.rb +18 -0
  31. data/lib/agris/api/messages.rb +25 -0
  32. data/lib/agris/api/messages/import.rb +40 -0
  33. data/lib/agris/api/messages/message_base.rb +42 -0
  34. data/lib/agris/api/messages/query_base.rb +37 -0
  35. data/lib/agris/api/messages/query_changed_delivery_tickets.rb +41 -0
  36. data/lib/agris/api/messages/query_changed_invoices.rb +48 -0
  37. data/lib/agris/api/messages/query_changed_orders.rb +41 -0
  38. data/lib/agris/api/messages/query_delivery_ticket_documents.rb +35 -0
  39. data/lib/agris/api/messages/query_invoice_documents.rb +40 -0
  40. data/lib/agris/api/messages/query_order_documents.rb +35 -0
  41. data/lib/agris/api/new_order.rb +86 -0
  42. data/lib/agris/api/new_order_remark.rb +22 -0
  43. data/lib/agris/api/new_voucher.rb +113 -0
  44. data/lib/agris/api/order.rb +63 -0
  45. data/lib/agris/api/order_line.rb +32 -0
  46. data/lib/agris/api/post_result.rb +24 -0
  47. data/lib/agris/api/remark.rb +16 -0
  48. data/lib/agris/api/support.rb +77 -0
  49. data/lib/agris/api/tran_code.rb +17 -0
  50. data/lib/agris/client.rb +39 -0
  51. data/lib/agris/context.rb +6 -0
  52. data/lib/agris/credentials.rb +7 -0
  53. data/lib/agris/credentials/anonymous.rb +11 -0
  54. data/lib/agris/credentials/basic_auth.rb +15 -0
  55. data/lib/agris/process_message_response.rb +58 -0
  56. data/lib/agris/resources/post_sales_order.xml +93 -0
  57. data/lib/agris/resources/post_sales_order_response.xml +21 -0
  58. data/lib/agris/savon_request.rb +73 -0
  59. data/lib/agris/user_agent.rb +7 -0
  60. data/lib/agris/version.rb +3 -0
  61. data/lib/agris/xml_model.rb +62 -0
  62. metadata +188 -0
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ module Messages
5
+ class QueryOrderDocuments < QueryBase
6
+ def initialize(document_references)
7
+ @document_references = document_references
8
+ end
9
+
10
+ def message_number
11
+ 80_900
12
+ end
13
+
14
+ protected
15
+
16
+ def input_hash
17
+ input_base_hash
18
+ end
19
+
20
+ def xml_hash
21
+ xml_base_hash
22
+ .merge(
23
+ order: @document_references.map(&:to_xml_hash),
24
+ lineitemdetail: true,
25
+ componentdetail: true,
26
+ remarkdetail: true,
27
+ lineremarkdetail: true,
28
+ trancodedetail: true,
29
+ specificationdetail: true
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ class NewOrder
5
+ include XmlModel
6
+
7
+ ATTRIBUTE_NAMES = %w(
8
+ order_location
9
+ order_number
10
+ order_status
11
+ order_type
12
+ line_item_no
13
+ order_date
14
+ shipment_date
15
+ bill_to_from_id
16
+ item_location
17
+ item_number
18
+ item_descr
19
+ price_code
20
+ price_level
21
+ price_schedule
22
+ invoice_terms
23
+ contract_location
24
+ contract_number
25
+ contract_price_schedule
26
+ weight_uom
27
+ quantity_uom
28
+ price_uom
29
+ state
30
+ county
31
+ trancode_1
32
+ trancode_2
33
+ trancode_3
34
+ trancode_4
35
+ trancode_5
36
+ user_order_field_1
37
+ user_order_field_2
38
+ user_line_item_field_1
39
+ external_order_number
40
+ user_line_item_field_1
41
+ exec_id
42
+ ship_to_from_id
43
+ shipper_id
44
+ agent_id
45
+ quantity_ordered
46
+ unit_price
47
+ pre_promo_price
48
+ amount_ordered
49
+ change_type
50
+ cost_proration
51
+ add_update_option
52
+ update_field_selection
53
+ reserved
54
+ last_production_stage
55
+ in_blend
56
+ expiration_date
57
+ item_description
58
+ uniqueid
59
+ ).freeze
60
+
61
+ attr_reader :record_type
62
+ attr_accessor(*ATTRIBUTE_NAMES)
63
+
64
+ def initialize(hash = {})
65
+ super
66
+
67
+ @record_type = 'INVP0'
68
+ end
69
+
70
+ def add_remark(remark)
71
+ @remarks ||= []
72
+ @remarks << remark
73
+
74
+ self
75
+ end
76
+
77
+ def remarks
78
+ @remarks || []
79
+ end
80
+
81
+ def xml_ignore_attributes
82
+ [:remarks]
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ class NewOrderRemark
5
+ include XmlModel
6
+
7
+ ATTRIBUTE_NAMES = %w(
8
+ number
9
+ order_line
10
+ value
11
+ ).freeze
12
+
13
+ attr_reader :record_type
14
+
15
+ def initialize(hash = {})
16
+ super
17
+
18
+ @record_type = 'INVP3'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Agris
4
+ module Api
5
+ class NewVoucher
6
+ include XmlModel
7
+
8
+ attr_reader :details
9
+
10
+ ATTRIBUTE_NAMES = %w(
11
+ agent_id
12
+ currency_code
13
+ discount_amount
14
+ discount_date
15
+ doc_type
16
+ due_date
17
+ exchange_rate
18
+ exchange_rate_date
19
+ first_voucher_no
20
+ name_id_type
21
+ original_date
22
+ record_type
23
+ remark_value
24
+ remit_to_id
25
+ ship_from_id
26
+ shipper_id
27
+ state_county
28
+ terms_code
29
+ their_invoice_no
30
+ their_order_no
31
+ trancode_1
32
+ trancode_2
33
+ trancode_3
34
+ trancode_4
35
+ trancode_5
36
+ trans_status
37
+ usr_order_field_1
38
+ usr_order_field_2
39
+ voucher_amount
40
+ voucher_date
41
+ voucher_description
42
+ voucher_location
43
+ voucher_number
44
+ voucher_type
45
+ ).freeze
46
+
47
+ attr_reader(*ATTRIBUTE_NAMES)
48
+
49
+ def initialize(hash = {})
50
+ super
51
+
52
+ @details = []
53
+ @record_type = 'ACPV0'
54
+ end
55
+
56
+ def add_detail(voucher)
57
+ @details << voucher
58
+ end
59
+
60
+ def xml_ignore_attributes
61
+ [:details]
62
+ end
63
+
64
+ class GeneralLedgerDetail
65
+ include XmlModel
66
+
67
+ ATTRIBUTE_NAMES = %w(
68
+ distribution_amount
69
+ execution_id
70
+ gl_account_main_code
71
+ gl_account_detail_code
72
+ gl_account_profit_center
73
+ gl_loc_code
74
+ record_type
75
+ ).freeze
76
+
77
+ def initialize(hash = {})
78
+ super
79
+
80
+ @record_type = 'ACPV2'
81
+ end
82
+ end
83
+
84
+ class InventoryItemDetail
85
+ include XmlModel
86
+
87
+ ATTRIBUTE_NAMES = %w(
88
+ cost_uom
89
+ detail_type
90
+ direct_cost
91
+ exec_id_number
92
+ item_loc
93
+ item_no
94
+ other_ref
95
+ order_location
96
+ order_number
97
+ quantity
98
+ quantity_uom
99
+ record_type
100
+ unit_cost
101
+ ).freeze
102
+
103
+ def initialize(orders, hash = {})
104
+ super(hash)
105
+
106
+ @detail_type = 'I'
107
+ @orders = orders
108
+ @record_type = 'ACPV1'
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ # NB: This is the model for returning orders
5
+ class Order
6
+ include XmlModel
7
+
8
+ ATTRIBUTE_NAMES = %w(
9
+ order_location
10
+ order_number
11
+ order_status
12
+ order_type
13
+ order_date
14
+ bill_to_from_id
15
+ delete
16
+ price_code
17
+ price_level
18
+ price_schedule
19
+ invoice_terms
20
+ statecounty
21
+ user_order_field_1
22
+ user_order_field_2
23
+ external_order_number
24
+ ship_to_from_id
25
+ shipper_id
26
+ agent_id
27
+ unique_id
28
+ ).freeze
29
+
30
+ attr_reader(*(%w(line_items tran_codes) + ATTRIBUTE_NAMES))
31
+
32
+ def self.from_xml_hash(hash)
33
+ super.tap do |order|
34
+ if hash['lineitems']
35
+ order.line_items.concat(
36
+ [hash['lineitems']['lineitem']]
37
+ .flatten
38
+ .map do |lineitem|
39
+ OrderLine.from_xml_hash(lineitem)
40
+ end
41
+ )
42
+ end
43
+ if hash['trancodes']
44
+ order.tran_codes.concat(
45
+ [hash['trancodes']['trancode']]
46
+ .flatten
47
+ .map do |trancode|
48
+ Agris::Api::TranCode.from_xml_hash(trancode)
49
+ end
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ def initialize(hash = {})
56
+ super
57
+
58
+ @line_items = []
59
+ @tran_codes = []
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ # NB: Question, should we split this into a NewOrderLine and reserve this
5
+ # class for data extracts.
6
+ class OrderLine
7
+ include XmlModel
8
+
9
+ ATTRIBUTE_NAMES = %w(
10
+ contract_location
11
+ contract_number
12
+ exec_id
13
+ expiration_date
14
+ line_item_no
15
+ item_location
16
+ item_number
17
+ item_type
18
+ order_status
19
+ price_code
20
+ price_uom
21
+ quantity_ordered
22
+ quantity_shipped
23
+ quantity_uom
24
+ shipment_date
25
+ weight_uom
26
+ unit_price
27
+ ).freeze
28
+
29
+ attr_reader(*ATTRIBUTE_NAMES)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ PostResult = Struct.new(:response) do
5
+ def document_number
6
+ results['result']['document']
7
+ end
8
+
9
+ def reject_reasons
10
+ results['result']['rejects']['reject']
11
+ .compact
12
+ .map { |rejection| rejection['reason'] }
13
+ end
14
+
15
+ def results
16
+ response.output_hash['results']
17
+ end
18
+
19
+ def status
20
+ results.fetch('result', 'status' => 'No Result').fetch('status')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ class Remark
5
+ include XmlModel
6
+
7
+ ATTRIBUTE_NAMES = %w(
8
+ number
9
+ label
10
+ value
11
+ ).freeze
12
+
13
+ attr_reader(*ATTRIBUTE_NAMES)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+ module Agris
3
+ module Api
4
+ module Support
5
+ # NB: I feel like this module could be broken up into more appropriately
6
+ # named files, but I'm not sure what those would be at present.
7
+ def build_response(output_hash, type)
8
+ DocumentQueryResponse.new(output_hash, type)
9
+ end
10
+
11
+ def extract_documents(message, type)
12
+ response = @request.process_message(
13
+ Gyoku.xml(xml: context_hash),
14
+ message.message_number,
15
+ message.to_xml
16
+ )
17
+
18
+ build_response(response.output_hash, type)
19
+ end
20
+
21
+ # NB: We could refactor these into builder classes so that we can
22
+ # use Gyoku to convert to XML. I imagine some kind of composite
23
+ # builder that wraps child builders with the xml container tags.
24
+ # Classes like SpecificOrderExtract and NewOrder would be possible
25
+ # candidates to become builders, include the builder module or have
26
+ # companion builder classes. AgrisInput, AgrisOutput?
27
+ def context_hash
28
+ {
29
+ login: {
30
+ :@dataset => @context.dataset,
31
+ :@databasetype => 'SQL',
32
+ :@database => @context.database,
33
+ :@userid => @context.userid,
34
+ :@password => @context.password,
35
+ :@datapath => @context.datapath,
36
+ :@log => 'Y',
37
+ :@loglevel => '9'
38
+ }
39
+ }
40
+ end
41
+
42
+ def post_input_hash
43
+ {
44
+ input: {
45
+ :@endofprocessoption => 1,
46
+ :@altnameidonfile => 'N',
47
+ :@usecurdate4outofrange => 'N',
48
+ :@reportoption => 1,
49
+ :@usefile => false
50
+ }
51
+ }
52
+ end
53
+
54
+ def create_post_payload_xml(details)
55
+ details_xml = details.map do |detail|
56
+ Gyoku.xml(detail: detail)
57
+ end.join
58
+
59
+ '<xml>' \
60
+ "#{Gyoku.xml(post_input_hash)}<details>#{details_xml}</details>" \
61
+ '</xml>'
62
+ end
63
+
64
+ def import(model)
65
+ import_message = Messages::Import.new(model)
66
+
67
+ response = @request.process_message(
68
+ Gyoku.xml(xml: context_hash),
69
+ import_message.message_number,
70
+ import_message.to_xml
71
+ )
72
+
73
+ PostResult.new(response)
74
+ end
75
+ end
76
+ end
77
+ end