diff --git a/lib/syspro/business_objects/combrw.rb b/lib/syspro/business_objects/combrw.rb index 9b3b34a..050f5bb 100644 --- a/lib/syspro/business_objects/combrw.rb +++ b/lib/syspro/business_objects/combrw.rb @@ -9,13 +9,16 @@ module Syspro include Syspro::ApiOperations::Query include Syspro::BusinessObjects::Parsers - attr_accessor :browse_name, :start_at_key, :start_condition, :return_rows, :filters, - :table_name, :title, :columns + attr_accessor :browse_name, :start_at_key, :start_condition, :return_rows, + :filters, :table_name, :title, :columns + + attr_writer :filters def call(user_id, raw = false) xml_in = template.result(binding) params = { 'UserId' => user_id, 'XmlIn' => xml_in } resp = ComBrw.browse(params) + if raw resp else @@ -38,6 +41,10 @@ module Syspro parser = ComBrwParser.new(resp[0].data) parser.parse end + + def filters + @filters || [] + end end end end diff --git a/lib/syspro/business_objects/parsers/combrw_parser.rb b/lib/syspro/business_objects/parsers/combrw_parser.rb index 4176fd3..2acfad7 100644 --- a/lib/syspro/business_objects/parsers/combrw_parser.rb +++ b/lib/syspro/business_objects/parsers/combrw_parser.rb @@ -4,6 +4,8 @@ module Syspro module BusinessObjects module Parsers class ComBrwParser + BrowseObject = Struct.new(:headers, :rows, :next_key, :prev_key, :fwd, :back, :key) + attr_reader :doc def initialize(doc) @@ -11,44 +13,32 @@ module Syspro end def parse - next_prev_key = doc.first_element_child.xpath('NextPrevKey') - next_prev_key_obj = next_prev_key.children.map do |el| - next if el.name == 'text' - { - name: el.name, - text: el.text - } - end.compact - - header_details = doc.first_element_child.xpath('HeaderDetails') - header_details_obj = header_details.children.map do |el| - next if el.name == 'text' - { - name: el.name, - text: el.text - } - end.compact + prev_key = doc.xpath('//NextPrevKey/PrevKey').text + next_key = doc.xpath('//NextPrevKey/NextKey').text + fwd = doc.xpath('//NextPrevKey/Fwd').text.casecmp('true').zero? + back = doc.xpath('//NextPrevKey/Back').text.casecmp('true').zero? + headers = doc.xpath('//HeaderDetails/Header').map { |h| h.text } + key = doc.xpath('//HeaderDetails/Key').text - rows = doc.first_element_child.xpath('Row') - rows_obj = rows.flat_map do |el| - el.elements.map do |inner| - { - name: inner.name, - value: inner.xpath('Value').text, - data_type: inner.xpath('DataType').text - } + rows = doc.xpath('//Row').map do |row| + columns = row.children.select { |n| n.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT } + columns.each_with_object({}) do |column, hash| + hash[column.name] = column.children + .find { |child| child.name == 'Value' } + .text end - end.compact + end BrowseObject.new( - doc.first_element_child.xpath('Title').text, - rows_obj, - next_prev_key_obj, - header_details_obj + headers, + rows, + next_key, + prev_key, + fwd, + back, + key ) end - - BrowseObject = Struct.new(:title, :rows, :next_prev_key, :header_details) end end end diff --git a/lib/syspro/business_objects/schemas/combrw.xml.erb b/lib/syspro/business_objects/schemas/combrw.xml.erb index 3d70c88..d5cd3b8 100644 --- a/lib/syspro/business_objects/schemas/combrw.xml.erb +++ b/lib/syspro/business_objects/schemas/combrw.xml.erb @@ -4,11 +4,11 @@ <%= @start_at_key %> <%= @start_condition %> <%= @return_rows %> - <% for @filter in @filters %> + <% for filter in filters %> - <%= @filter[:name] %> - <%= @filter[:value] %> - + <%= filter[:name] %> + <%= filter[:value] %> + <% end %> diff --git a/test/cassettes/test_inv_wh_ctrl_qry.yml b/test/cassettes/test_inv_wh_ctrl_qry.yml new file mode 100644 index 0000000..63438ae --- /dev/null +++ b/test/cassettes/test_inv_wh_ctrl_qry.yml @@ -0,0 +1,104 @@ +--- +http_interactions: +- request: + method: get + uri: http://syspro.wildlandlabs.com:90/SYSPROWCFService/Rest/logon?CompanyId=&CompanyPassword=&Operator=&OperatorPassword= + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Syspro/7 RubyBindings/1.0.0.alpha.2 + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/octet-stream + Server: + - Microsoft-HTTPAPI/2.0 + Date: + - Thu, 30 May 2019 23:45:30 GMT + Content-ength: + - '36' + body: + encoding: UTF-8 + string: '919BB8178D221E4F92299528B68B597000 ' + http_version: + recorded_at: Thu, 30 May 2019 23:45:29 GMT +- request: + method: get + uri: http://syspro.wildlandlabs.com:90/SYSPROWCFService/Rest/Query/Browse?UserId=919BB8178D221E4F92299528B68B597000%20%20&XmlIn=%3C?xml%20version=%221.0%22%20encoding=%22Windows-1252%22?%3E%0A%3CBrowse%20xmlns:xsd=%22http://www.w3.org/2001/XMSchema-instance%22%20xsd:noNamespaceSchemaocation=%22COMBRW.XSD%22%3E%0A%20%20%3CBrowseName%3EabbeeInvWhControl%3C/BrowseName%3E%0A%20%20%3CStartAtKey%3E%3C/StartAtKey%3E%0A%20%20%3CStartCondition%3E%3C/StartCondition%3E%0A%20%20%3CReturnRows%3E30%3C/ReturnRows%3E%0A%20%20%0A%3C/Browse%3E%0A%0A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Syspro/7 RubyBindings/1.0.0.alpha.2 + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/octet-stream + Server: + - Microsoft-HTTPAPI/2.0 + Date: + - Thu, 30 May 2019 23:45:57 GMT + Content-ength: + - '7988' + body: + encoding: UTF-8 + string: "\nanguage='05' + anguage2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' + Version='7.0.038' OperatorPrimaryRole=' '>\nWarehouses\n\n\nBJ\nAlphaNumeric\n\n\nBRONSON + & JACOBS\nAlphaNumeric\n\n\n\n\nCB\nAlphaNumeric\n\n\nCOGATE + @ BEGIUM\nAlphaNumeric\n\n\n\n\nCG\nAlphaNumeric\n\n\nCOGATE + @ harrah\nAlphaNumeric\n\n\n\n\nDR\nAlphaNumeric\n\n\nHARRAH-ABBEEMINT + OWNED\nAlphaNumeric\n\n\n\n\nEX\nAlphaNumeric\n\n\nESSEX + ABS\nAlphaNumeric\n\n\n\n\nF9\nAlphaNumeric\n\n\nFIRMENICH + HED INVENTORY\nAlphaNumeric\n\n\n\n\nFI\nAlphaNumeric\n\n\nFIRMENICH\nAlphaNumeric\n\n\n\n\nGV\nAlphaNumeric\n\n\nGIVAUDAN\nAlphaNumeric\n\n\n\n\nH0\nAlphaNumeric\n\n\nHARRAH-GROWER + OWNED\nAlphaNumeric\n\n\n\n\nH1\nAlphaNumeric\n\n\nHARRAH-ABBEEMINT + OWNED\nAlphaNumeric\n\n\n\n\nH8\nAlphaNumeric\n\n\nHARRAH-CUSTOMER + OWNED\nAlphaNumeric\n\n\n\n\nH9\nAlphaNumeric\n\n\nHARRAH-CUSTOMER + SET ASIDE\nAlphaNumeric\n\n\n\n\nHD\nAlphaNumeric\n\n\nHRF(D)\nAlphaNumeric\n\n\n\n\nHQ\nAlphaNumeric\n\n\nMAIN-11793 + FORT ROAD\nAlphaNumeric\n\n\n\n\nHR\nAlphaNumeric\n\n\nHAARMANN + & RIEMER\nAlphaNumeric\n\n\n\n\nI9\nAlphaNumeric\n\n\nIFF + HED INVENTORY\nAlphaNumeric\n\n\n\n\nIF\nAlphaNumeric\n\n\nIFF\nAlphaNumeric\n\n\n\n\nJ9\nAlphaNumeric\n\n\nJC + BUCK HED INVENTORY\nAlphaNumeric\n\n\n\n\nJC\nAlphaNumeric\n\n\nJCBUCK + TD HED INVENTORY\nAlphaNumeric\n\n\n\n\nK9\nAlphaNumeric\n\n\nKAR + RAPP HED INVENTORY\nAlphaNumeric\n\n\n\n\nM0\nAlphaNumeric\n\n\nMADRAS-GROWER + OWNED\nAlphaNumeric\n\n\n\n\nM1\nAlphaNumeric\n\n\nMADRAS-ABBEEMINT + OWNED\nAlphaNumeric\n\n\n\n\nMD\nAlphaNumeric\n\n\nMADRAS + OREGON\nAlphaNumeric\n\n\n\n\nMS\nAlphaNumeric\n\n\nMATAS\nAlphaNumeric\n\n\n\n\nMW\nAlphaNumeric\n\n\nPORTAGE + WISCONSIN\nAlphaNumeric\n\n\n\n\nN0\nAlphaNumeric\n\n\nNAMPA-GROWER + OWNED\nAlphaNumeric\n\n\n\n\nN1\nAlphaNumeric\n\n\nNAMPA-ABBEEMINT + OWNED\nAlphaNumeric\n\n\n\n\nNV\nAlphaNumeric\n\n\nNOVIE\nAlphaNumeric\n\n\n\n\nP0\nAlphaNumeric\n\n\nPORTAGE-GROWER + OWNED\nAlphaNumeric\n\n\n\n\nP1\nAlphaNumeric\n\n\nPORTAGE-ABBEEMINT + OWNED\nAlphaNumeric\n\n\n\n\nP8\nAlphaNumeric\n\n\nPORTAGE-CUSTOMER + OWNED\nAlphaNumeric\n\n\n\n\nP9\nAlphaNumeric\n\n\nPORTAGE-CUSTOMER + SETASIDE\nAlphaNumeric\n\n\n\n\nPG\nAlphaNumeric\n\n\nPROCTER&GAMBE\nAlphaNumeric\n\n\n\n\nPO\nAlphaNumeric\n\n\nPOAROME\nAlphaNumeric\n\n\n\n\nQI\nAlphaNumeric\n\n\nQUEST + INTRNTN\nAlphaNumeric\n\n\n\n\nRE\nAlphaNumeric\n\n\nREYNAUD@St. + Didier\nAlphaNumeric\n\n\n\n\nT9\nAlphaNumeric\n\n\nMT + OWNED INV AT PDI\nAlphaNumeric\n\n\n\n\nT\nAlphaNumeric\n\n\nTIOTS + WAREHOUSE\nAlphaNumeric\n\n\n\n\nU8\nAlphaNumeric\n\n\nU + OWNED @ PDI\nAlphaNumeric\n\n\n\n\nWY\nAlphaNumeric\n\n\nWRIGEY\nAlphaNumeric\n\n\n\nBJ\nWY\nFalse\nFalse\n\n\n
Warehouse
\n
Description + \ .
\nWarehouse\nWarehouse + code\nInvWhControl
\n
\n
\n " + http_version: + recorded_at: Thu, 30 May 2019 23:45:56 GMT +recorded_with: VCR 4.0.0 diff --git a/test/cassettes/test_portor.yml b/test/cassettes/test_portor.yml index 16bfbcb..0a1e22c 100644 --- a/test/cassettes/test_portor.yml +++ b/test/cassettes/test_portor.yml @@ -25,17 +25,17 @@ http_interactions: Server: - Microsoft-HTTPAPI/2.0 Date: - - Thu, 23 May 2019 16:43:21 GMT + - Wed, 19 Jun 2019 21:18:47 GMT Content-ength: - '36' body: encoding: UTF-8 - string: '6D8139C868FDD74487FB2B80F8CC4EBD00 ' + string: '2088C39D9FF2C34281100962D8D28EC100 ' http_version: - recorded_at: Thu, 23 May 2019 16:43:18 GMT + recorded_at: Wed, 19 Jun 2019 21:18:45 GMT - request: method: get - uri: http://syspro.wildlandlabs.com:90/SYSPROWCFService/Rest/Transaction/Post?BusinessObject=PORTOR&UserId=6D8139C868FDD74487FB2B80F8CC4EBD00%20%20&XmlIn=%3C?xml%20version=%221.0%22%20encoding=%22Windows-1252%22?%3E%0A%3CPostPurchaseOrderReceipts%20xmlns:xsd=%22http://www.w3.org/2001/XMSchema-instance%22%20xsd:noNamespaceSchemaocation=%22portordoc.xsd%22%3E%0A%20%20%0A%20%20%3CItem%3E%0A%20%20%20%20%3CReceiptIntoInspection%3E%0A%20%20%20%20%20%20%3CPurchaseOrder%3EZ01308%3C/PurchaseOrder%3E%0A%20%20%20%20%20%20%3CWarehouse%3EP0%3C/Warehouse%3E%0A%20%20%20%20%20%20%3CStockCode%3E8801%3C/StockCode%3E%0A%20%20%20%20%20%20%3CQuantity%3E0.01%3C/Quantity%3E%0A%20%20%20%20%20%20%3CCountedQuantityComplete%3EY%3C/CountedQuantityComplete%3E%0A%20%20%20%20%20%20%3CDeliveryNote%3EDEIVER%20NOTE%20HERE-W%3C/DeliveryNote%3E%0A%20%20%20%20%20%20%3CCertificate%3E8/45-3%3C/Certificate%3E%0A%20%20%20%20%20%20%3CNarration%3E%3C/Narration%3E%0A%20%20%20%20%20%20%3Cot%3E7097505%3C/ot%3E%0A%20%20%20%20%20%20%3CGRNNumber%3E%3C/GRNNumber%3E%0A%20%20%20%20%20%20%3CConcession%3E%3C/Concession%3E%0A%20%20%20%20%20%20%3CCostBasis%3E%3C/CostBasis%3E%0A%20%20%20%20%20%20%3CNotation%3E%3C/Notation%3E%0A%20%20%20%20%20%20%3CReference%3E%3C/Reference%3E%0A%20%20%20%20%20%20%3CGRNSource%3E%3C/GRNSource%3E%0A%20%20%20%20%20%20%0A%20%20%20%20%3C/ReceiptIntoInspection%3E%0A%20%20%3C/Item%3E%0A%20%20%20%20%20%20%0A%3C/PostPurchaseOrderReceipts%3E&XmlParameters=%3C?xml%20version=%221.0%22%20encoding=%22Windows-1252%22?%3E%0A%3CPostPurchaseOrderReceipts%20xmlns:xsd=%22http://www.w3.org/2001/XMSchema-instance%22%20xsd:noNamespaceSchemaocation=%22portor.xsd%22%3E%0A%20%20%3CParameters%3E%0A%20%20%20%20%3CTransactionDate%3E2019-05-23%3C/TransactionDate%3E%0A%20%20%20%20%3CIgnoreWarnings%3EN%3C/IgnoreWarnings%3E%0A%20%20%20%20%3CNonStockedWhToUse%3E%3C/NonStockedWhToUse%3E%0A%20%20%20%20%3CGRNMatchingAction%3EA%3C/GRNMatchingAction%3E%0A%20%20%20%20%3CAllowBlankSupplier%3EN%3C/AllowBlankSupplier%3E%0A%20%20%20%20%3CApplyIfEntireDocumentValid%3EN%3C/ApplyIfEntireDocumentValid%3E%0A%20%20%20%20%3CValidateOnly%3EN%3C/ValidateOnly%3E%0A%20%20%20%20%3CManualSerialTransfersAllowed%3EN%3C/ManualSerialTransfersAllowed%3E%0A%20%20%20%20%3CIgnoreAnalysis%3EN%3C/IgnoreAnalysis%3E%0A%20%20%3C/Parameters%3E%0A%3C/PostPurchaseOrderReceipts%3E + uri: http://syspro.wildlandlabs.com:90/SYSPROWCFService/Rest/Transaction/Post?BusinessObject=PORTOR&UserId=2088C39D9FF2C34281100962D8D28EC100%20%20&XmlIn=%3C?xml%20version=%221.0%22%20encoding=%22Windows-1252%22?%3E%0A%3CPostPurchaseOrderReceipts%20xmlns:xsd=%22http://www.w3.org/2001/XMSchema-instance%22%20xsd:noNamespaceSchemaocation=%22portordoc.xsd%22%3E%0A%20%20%0A%20%20%3CItem%3E%0A%20%20%20%20%3CReceiptIntoInspection%3E%0A%20%20%20%20%20%20%3CPurchaseOrder%3EZ01308%3C/PurchaseOrder%3E%0A%20%20%20%20%20%20%3CWarehouse%3EP0%3C/Warehouse%3E%0A%20%20%20%20%20%20%3CStockCode%3E8801%3C/StockCode%3E%0A%20%20%20%20%20%20%3CQuantity%3E0.01%3C/Quantity%3E%0A%20%20%20%20%20%20%3CCountedQuantityComplete%3EY%3C/CountedQuantityComplete%3E%0A%20%20%20%20%20%20%3CDeliveryNote%3EDEIVER%20NOTE%20HERE-W%3C/DeliveryNote%3E%0A%20%20%20%20%20%20%3CCertificate%3E8/45-3%3C/Certificate%3E%0A%20%20%20%20%20%20%3CNarration%3E%3C/Narration%3E%0A%20%20%20%20%20%20%3Cot%3E7097505%3C/ot%3E%0A%20%20%20%20%20%20%3CGRNNumber%3E%3C/GRNNumber%3E%0A%20%20%20%20%20%20%3CConcession%3E%3C/Concession%3E%0A%20%20%20%20%20%20%3CCostBasis%3E%3C/CostBasis%3E%0A%20%20%20%20%20%20%3CNotation%3E%3C/Notation%3E%0A%20%20%20%20%20%20%3CReference%3E%3C/Reference%3E%0A%20%20%20%20%20%20%3CGRNSource%3E%3C/GRNSource%3E%0A%20%20%20%20%20%20%0A%20%20%20%20%3C/ReceiptIntoInspection%3E%0A%20%20%3C/Item%3E%0A%20%20%20%20%20%20%0A%3C/PostPurchaseOrderReceipts%3E&XmlParameters=%3C?xml%20version=%221.0%22%20encoding=%22Windows-1252%22?%3E%0A%3CPostPurchaseOrderReceipts%20xmlns:xsd=%22http://www.w3.org/2001/XMSchema-instance%22%20xsd:noNamespaceSchemaocation=%22portor.xsd%22%3E%0A%20%20%3CParameters%3E%0A%20%20%20%20%3CTransactionDate%3E2019-06-19%3C/TransactionDate%3E%0A%20%20%20%20%3CIgnoreWarnings%3EN%3C/IgnoreWarnings%3E%0A%20%20%20%20%3CNonStockedWhToUse%3E%3C/NonStockedWhToUse%3E%0A%20%20%20%20%3CGRNMatchingAction%3EA%3C/GRNMatchingAction%3E%0A%20%20%20%20%3CAllowBlankSupplier%3EN%3C/AllowBlankSupplier%3E%0A%20%20%20%20%3CApplyIfEntireDocumentValid%3EN%3C/ApplyIfEntireDocumentValid%3E%0A%20%20%20%20%3CValidateOnly%3EN%3C/ValidateOnly%3E%0A%20%20%20%20%3CManualSerialTransfersAllowed%3EN%3C/ManualSerialTransfersAllowed%3E%0A%20%20%20%20%3CIgnoreAnalysis%3EN%3C/IgnoreAnalysis%3E%0A%20%20%3C/Parameters%3E%0A%3C/PostPurchaseOrderReceipts%3E body: encoding: US-ASCII string: '' @@ -58,14 +58,14 @@ http_interactions: Server: - Microsoft-HTTPAPI/2.0 Date: - - Thu, 23 May 2019 16:43:23 GMT + - Wed, 19 Jun 2019 21:18:47 GMT Content-ength: - '397' body: encoding: UTF-8 string: "\nanguage='05' anguage2='EN' CssStyle='' DecFormat='1' - DateFormat='01' Role='01' Version='7.0.111' OperatorPrimaryRole=' '>\n\n\nZ01308\n<ine>0002ine>\nP00013152\n<otNumber>7097505otNumber>\n\n000001\n\n\n " + DateFormat='01' Role='01' Version='7.0.111' OperatorPrimaryRole=' '>\n\n\nZ01308\n<ine>0002ine>\nP00013151\n<otNumber>7097505otNumber>\n\n000001\n\n\n " http_version: - recorded_at: Thu, 23 May 2019 16:43:20 GMT + recorded_at: Wed, 19 Jun 2019 21:18:46 GMT recorded_with: VCR 4.0.0 diff --git a/test/combrw_test.rb b/test/combrw_test.rb new file mode 100644 index 0000000..2278cd6 --- /dev/null +++ b/test/combrw_test.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'test_helper' + +class ComBrwTest < Minitest::Test + extend Minitest::Spec::DSL + before do + VCR.insert_cassette name + end + after { VCR.eject_cassette } + + let(:username) { ENV['SYSPRO_USERNAME'] } + let(:password) { ENV['SYSPRO_PASSWORD'] } + let(:company) { ENV['SYSPRO_COMPANY'] } + let(:company_password) { '' } + let(:user_id) do + Syspro::Logon.logon(username, password, company, company_password) + end + + def test_inv_wh_ctrl_qry + com_browse = Syspro::BusinessObjects::ComBrw.new + + com_browse.return_rows = 30 + com_browse.browse_name = 'LabbeeInvWhControl' + query = com_browse.call(user_id.guid) + + assert_kind_of Syspro::BusinessObjects::Parsers::ComBrwParser::BrowseObject, query + assert query.headers, 'has headers' + assert_equal 2, query.headers.count, 'has headers' + assert query.prev_key, 'has a previous key' + assert query.next_key, 'has a next key' + assert query.key, 'has a key' + assert_includes [true, false], query.fwd + assert_includes [true, false], query.back + query.rows.each do |row| + assert_kind_of( + Hash, + row + ) + + assert row.key?('Warehouse'), 'row should contain a warehouse' + assert row.key?('Description'), 'row should contain a description' + end + end +end -- libgit2 0.21.4