public async Task report_unconsumed_attribute()
        {
            const string response = @"
                <?xml version=""1.0"" encoding=""UTF-8""?>
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""0""
                            retransmit=""n""
                            newAttribute=""42"">
                    <RequestCode>COUPON_INQUIRY</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>42</SVAN>
                    <AccountCurrency>DKK</AccountCurrency>
                    <ExchangeRate>1.00</ExchangeRate>
                    <ResponseCode>A</ResponseCode>
                    <DisplayMessage>There are no eligible coupons for this card.</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(() =>
                                                                                    sut.CouponInquiryAsync(new AccountNumber("42")));

                Assert.Contains(@"<SVCMessage newAttribute=""42"" />", e.InnerException.Message);
            }
        }
        public async Task invalid_account_returns_empty_row_set()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetCustomer</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <ResultSetMetaData>
                      <RSColumn name=""firstname"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""lastname"" type=""string"" nullable=""true""></RSColumn>
                    </ResultSetMetaData>
                    <Rows></Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.GetCustomerAsync(
                "primaryposref = ?",
                new[] { new ColumnValue("primaryPOSRef", "doesNotMatter") },
                new[] { new Column("firstname"), new Column("lastname") });

            Assert.Equal(2, actual.MetaData.Length);
            Assert.Empty(actual.Rows);
        }
        public async Task update_failed_on_invalid_account()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" hostversion=""1.00"">
                  <RequestCode>SetCustomer</RequestCode>
                  <ResponseCode>D</ResponseCode>
                  <DisplayMessage>com.micros.storedValue.worker.SetRollbackException: Update failed for row ID = 123</DisplayMessage>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(
                () =>
                sut.SetCustomerAsync(
                    123,
                    new[]
            {
                new ColumnValue("firstname", "Rubber"),
                new ColumnValue("lastname", "Duck")
            }));

            Assert.Contains("Update failed for row ID = 123", e.Message);
        }
Exemple #4
0
        public async Task program_id_on_valid_account()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                    <RequestCode>GetAccount</RequestCode>
                    <ResponseCode>A</ResponseCode>
                    <ResultSet>
                        <ResultSetMetaData>
                            <RSColumn name=""programid"" type=""long"" nullable=""false""></RSColumn>
                        </ResultSetMetaData>
                        <Rows>
                            <Row id=""106632"">
                                <Col>14631</Col>
                            </Row>
                        </Rows>
                    </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual =
                await sut.GetAccountAsync(
                    "accountposref = ?",
                    new[] { new ColumnValue("accountposref", "123") },
                    new[] { new Column("programid") });

            Assert.Single(actual.Rows);
            Assert.Equal(106632, actual.Rows[0].Id);
            Assert.Equal(14631, (long)actual.Rows[0].Columns["programid"]);
        }
Exemple #5
0
        public async Task invalid_account()
        {
            const string response = @"
                <?xml version=""1.0""?>
                <SVCMessage language=""en-US"" 
                            retransmit=""n"" 
                            sequence=""00"" 
                            currency=""DKK"" 
                            posIntfcVersion=""1.00"" 
                            posIntfcName=""posInterfaceName"" 
                            version=""1"" 
                            hostVersion=""9.1.0000.2301"">
                    <RequestCode>COUPON_INQUIRY</RequestCode>
                    <TraceID>190820113916N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>123</SVAN>
                    <ResponseCode hostCode=""1"">D</ResponseCode>
                    <DisplayMessage>There is no account number or the account number (123) is too short</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-20T11:39:16")))
            {
                var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(
                    () => sut.CouponInquiryAsync(new AccountNumber("123")));

                Assert.Equal("1", e.Code);
                Assert.Equal("There is no account number or the account number (123) is too short", e.Message);
            }
        }
Exemple #6
0
        public async Task error_on_invalid_programid()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                    <RequestCode>GetProgram</RequestCode>
                    <ResponseCode>A</ResponseCode>
                    <ResultSet>
                        <ResultSetMetaData>
                        <RSColumn name=""programcode"" type=""string"" nullable=""true""></RSColumn>
                        </ResultSetMetaData>
                        <Rows></Rows>
                    </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual =
                await sut.GetProgramAsync(
                    "programid = ?",
                    new[] { new ColumnValue("programid", "123") },
                    new[] { new Column("programcode") });

            Assert.Empty(actual.Rows);
        }
Exemple #7
0
        public async Task invalid_coupon_code()
        {
            const string response = @"
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""0"" 
                            retransmit=""n"">
                    <RequestCode>SV_ACCEPT_COUPON</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>123</SVAN>
                    <ResponseCode hostCode=""93"">D</ResponseCode>
                    <DisplayMessage>Coupon (NotExist) cannot be found</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(() =>
                                                                                    sut.CouponAcceptAsync(new AccountNumber("123"), new CouponCode("NotExist")));

                Assert.Equal("93", e.Code);
                Assert.Equal("Coupon (NotExist) cannot be found", e.Message);
            }
        }
        public async Task account_already_exists_and_closed()
        {
            const string response = @"
                <SVCMessage language=""en-US"" 
                            retransmit=""n""
                            sequence=""00""
                            currency=""DKK"" 
                            posIntfcVersion=""1.00"" 
                            posIntfcName=""posInterfaceName"" 
                            version=""1"" 
                            hostVersion=""9.1.0000.2301"">
                    <RequestCode>POINT_ISSUE</RequestCode>
                    <TraceID>190829140000N000000</TraceID>
                    <Amount>0</Amount>
                    <SVAN>2200000</SVAN>
                    <ResponseCode hostCode=""106"">D</ResponseCode>
                    <DisplayMessage>This account cannot be used, it is closed</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-29T14:00:00")))
            {
                var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(() =>
                                                                                    sut.PointIssueAsync(new AccountNumber("2200000")));

                Assert.Equal("106", e.Code);
                Assert.Equal("This account cannot be used, it is closed", e.Message);
            }
        }
        public async Task valid_account_with_multiple_customers()
        {
            // If we create multiple customers and associate each with the same
            // account, response becomes as below.
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetCustomer</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <ResultSetMetaData>
                      <RSColumn name=""firstname"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""lastname"" type=""string"" nullable=""true""></RSColumn>
                    </ResultSetMetaData>
                    <Rows>
                      <Row id=""416440"">
                        <Col>John</Col>
                        <Col>Doe</Col>
                      </Row>
                      <Row id=""422056"">
                        <Col />
                        <Col />
                      </Row>
                      <Row id=""456663"">
                        <Col>Rubber</Col>
                        <Col>Duck</Col>
                      </Row>
                    </Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.GetCustomerAsync(
                "primaryposref = ?",
                new[] { new ColumnValue("primaryPOSRef", "doesNotMatter") },
                new[] { new Column("firstname"), new Column("lastname") });

            Assert.Equal(3, actual.Rows.Length);

            var r0 = actual.Rows[0];

            Assert.Equal(416440, r0.Id);
            Assert.Equal("John", r0.Columns["firstname"]);
            Assert.Equal("Doe", r0.Columns["lastname"]);

            var r1 = actual.Rows[1];

            Assert.Equal(422056, r1.Id);
            Assert.Null(r1.Columns["firstname"]);
            Assert.Null(r1.Columns["lastname"]);

            var r2 = actual.Rows[2];

            Assert.Equal(456663, r2.Id);
            Assert.Equal("Rubber", r2.Columns["firstname"]);
            Assert.Equal("Duck", r2.Columns["lastname"]);
        }
        public async Task loyalty_account_created_with_rule_awards_pos_print_text_non_empty()
        {
            const string response = @"
                <SVCMessage hostVersion=""9.1.0000.2301""
                            version=""1""
                            posIntfcName=""posInterfaceName""
                            posIntfcVersion=""1.00""
                            language=""en-US""
                            currency=""DKK""
                            sequence=""00""
                            retransmit=""n"">
                <RequestCode>POINT_ISSUE</RequestCode>
                <TraceID>190826145135N000000</TraceID>
                <Amount>0</Amount>
                <SVAN>luxo7wt7mrm8rj4t0j24twi3</SVAN>
                <ItemType>T</ItemType>
                <ItemNumber>1234</ItemNumber>
                <AccountCurrency>DKK</AccountCurrency>
                <AccountBalance>0.00</AccountBalance>
                <LocalBalance>0.00</LocalBalance>
                <ExchangeRate>1.00</ExchangeRate>
                <ResponseCode>A</ResponseCode>
                <ProgramCode>lux</ProgramCode>
                <ProgramName>lux</ProgramName>
                <PointsIssued>0</PointsIssued>
                <BonusPointsIssued>0</BonusPointsIssued>
                <PrintLines>
                    <PrintLine>LUX BENEFIT</PrintLine>
                </PrintLines>
                <DisplayMessage>Transaction Complete. </DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var actual = await sut.PointIssueAsync(new AccountNumber("luxo7wt7mrm8rj4t0j24twi3"));

                Assert.Equal(ItemType.Kind.Tender, actual.ItemType.Value);
                Assert.Equal(1234, actual.ItemNumber.Value);
                Assert.Equal(Currency.Kind.DKK, actual.AccountCurrency.Value);
                Assert.Equal(0.00m, actual.AccountBalance.Value);
                Assert.Equal(0.00m, actual.LocalBalance.Value);
                Assert.Equal(1.00m, actual.ExchangeRate.Value);
                Assert.Equal("lux", actual.ProgramCode.Value);
                Assert.Equal("lux", actual.ProgramName.Value);
                Assert.Equal(0m, actual.PointsIssued.Value);
                Assert.Equal(0m, actual.BonusPointsIssued.Value);
                Assert.Single(actual.PrintLines.Values);
                Assert.Equal("LUX BENEFIT", actual.PrintLines.Values[0].Value);
                Assert.Equal("Transaction Complete. ", actual.DisplayMessage.Value);
            }
        }
        public async Task error_on_invalid_entity()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetColumnList</RequestCode>
                  <ResponseCode>E</ResponseCode>
                  <Error code=""1"">Unsupported parameter: NonExistingEntity</Error>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(() =>
                                                                                sut.GetColumnListAsync("NonExistingEntity"));

            Assert.Equal("1", e.Code);
        }
Exemple #12
0
        public async Task valid_coupon_code()
        {
            const string response = @"
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""00"" 
                            retransmit=""n"">
                    <RequestCode>SV_ISSUE_COUPON</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>123</SVAN>
                    <AccountCurrency>DKK</AccountCurrency>
                    <ExchangeRate>1.00</ExchangeRate>
                    <ItemType>T</ItemType>
                    <ItemNumber>1</ItemNumber>
                    <PrintLines />
                    <CouponCode>1006022</CouponCode>
                    <ResponseCode>A</ResponseCode>
                    <DisplayMessage>Coupon (10 DKK) has been issued to this account.</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var actual = await sut.CouponIssueAsync(new AccountNumber("123"), new CouponCode("doesNotMatter"));

                Assert.Equal("1006022", actual.CouponCode.Value);
                Assert.Equal("Coupon (10 DKK) has been issued to this account.", actual.DisplayMessage.Value);
                Assert.Equal(ItemType.Kind.Tender, actual.ItemType.Value);
                Assert.Equal(1, actual.ItemNumber.Value);
                Assert.Empty(actual.PrintLines.Values);
                Assert.Equal(Currency.Kind.DKK, actual.AccountCurrency.Value);
                Assert.Equal(1.00m, actual.ExchangeRate.Value);
            }
        }
Exemple #13
0
        public async Task reopen_account_already_open_disallowed()
        {
            const string response = @"
                <CRMMessage hostVersion=""9.1.0000.2301"" language=""en_US"" currency=""DKK"" isTrustedSAT=""false"">
                    <RequestCode>PostAccountTransaction</RequestCode>
                    <TraceID>Ark70tecHQrIBCXrS81XW</TraceID>
                    <SVAN>2200005</SVAN>
                    <ResponseCode>D</ResponseCode>
                    <DisplayMessage>This account cannot be used, its status is invalid</DisplayMessage>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(
                () => sut.PostAccountTransactionAsync(_transaction));

            Assert.Equal("This account cannot be used, its status is invalid", e.Message);
        }
Exemple #14
0
        public async Task reopen_closed_account_allowed()
        {
            const string response = @"
              <CRMMessage hostVersion=""9.1.0000.2301"" language=""en_US"" currency=""DKK"" isTrustedSAT=""false"">
                <RequestCode>PostAccountTransaction</RequestCode>
                <TraceID>Ark70tecHQrIBCXrS81XW</TraceID>
                <SVAN>2200005</SVAN>
                <ResponseCode>A</ResponseCode>
                <AccountBalance>0.00</AccountBalance>
                <LocalBalance>0.00</LocalBalance>
                <DisplayMessage>Account 2200005 has been re-opened</DisplayMessage>
              </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.PostAccountTransactionAsync(_transaction);

            Assert.Equal("Account 2200005 has been re-opened", actual.DisplayMessage.Value);
        }
Exemple #15
0
        public async Task error_on_invalid_account()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetCoupons</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <ResultSetMetaData>
                      <RSColumn name=""name"" type=""string"" nullable=""false""></RSColumn>
                      <RSColumn name=""description"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""serialNumber"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""validFromDate"" type=""timestamp"" nullable=""true""></RSColumn>
                      <RSColumn name=""validUntilDate"" type=""timestamp"" nullable=""true""></RSColumn>
                      <RSColumn name=""redeemed"" type=""boolean"" nullable=""false""></RSColumn>
                    </ResultSetMetaData>
                    <Rows></Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual =
                await sut.GetCouponsAsync(
                    "accountposref = ?",
                    new[]
            {
                new ColumnValue("accountposref", "doNotExist")
            });

            var metaData = actual.MetaData;

            Assert.Equal(6, metaData.Length);

            var rows = actual.Rows;

            Assert.Empty(rows);
        }
        public async Task valid_account_with_single_customer()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetCustomer</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <ResultSetMetaData>
                      <RSColumn name=""firstname"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""lastname"" type=""string"" nullable=""true""></RSColumn>
                    </ResultSetMetaData>
                    <Rows>
                      <Row id=""27350"">
                        <Col>George</Col>
                        <Col>Washington</Col>
                      </Row>
                    </Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.GetCustomerAsync(
                "primaryposref = ?",
                new[] { new ColumnValue("primaryposref", "doesNotMatter") },
                new[] { new Column("firstname"), new Column("lastname") });

            Assert.Equal(2, actual.MetaData.Length);
            Assert.Single(actual.Rows);

            var r0 = actual.Rows[0];

            Assert.Equal(27350, r0.Id);
            Assert.Equal("George", r0.Columns["firstname"]);
            Assert.Equal("Washington", r0.Columns["lastname"]);
        }
        public async Task with_both_unconsumed_element_and_backend_reporting_error_unconsumed_exception_takes_precedence()
        {
            // Only check ResponseCode and throw exception after validating
            // every element and attribute. Otherwise, we miss the opportunity
            // to catch responses of unanticipated forms.
            const string response = @"
                <?xml version=""1.0"" encoding=""UTF-8""?>
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""0""
                            retransmit=""n"">
                    <RequestCode>COUPON_INQUIRY</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>42</SVAN>
                    <ResponseCode hostCode=""93"">D</ResponseCode>
                    <DisplayMessage>Coupon (NotExist) cannot be found</DisplayMessage>
                    <NewElement>42</NewElement>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var e = await Assert.ThrowsAsync <OracleHospitalityClientException>(() =>
                                                                                    sut.CouponInquiryAsync(new AccountNumber("42")));

                Assert.Contains(
                    "<SVCMessage><NewElement>42</NewElement></SVCMessage>",
                    e.InnerException.Message.Replace(Environment.NewLine, "").Replace(" ", ""));
            }
        }
        public async Task create_and_update_success_response()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>SetCustomer</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <Row id=""456663"" />
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.SetCustomerAsync(
                123,
                new[]
            {
                new ColumnValue("FIRSTNAME", "Rubber"),
                new ColumnValue("LASTNAME", "Duck")
            });

            Assert.Equal(456663, actual.RowId);
        }
Exemple #19
0
        public async Task valid_coupon_code()
        {
            // For SV_ACCEPT_COUPON response, SVAN changes meaning from
            // mirroring the request SVAN to holding the issued CouponCode.
            const string response = @"
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""00""
                            retransmit=""n"">
                    <RequestCode>SV_ACCEPT_COUPON</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>1005016</SVAN>
                    <ItemType>D</ItemType>
                    <ItemNumber>150</ItemNumber>
                    <ResponseCode>A</ResponseCode>
                    <DisplayMessage>10 DKK Coupon accepted</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var actual = await sut.CouponAcceptAsync(new AccountNumber("doesNotMatter"), new CouponCode("1005016"));

                Assert.Equal(ItemType.Kind.Discount, actual.ItemType.Value);
                Assert.Equal(150, actual.ItemNumber.Value);
                Assert.Equal("10 DKK Coupon accepted", actual.DisplayMessage.Value);
                Assert.Equal("1005016", actual.AccountNumber.Value);
            }
        }
Exemple #20
0
        public async Task valid_account_with_one_coupon()
        {
            var response = @"
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""00"" 
                            retransmit=""n"">
                    <RequestCode>COUPON_INQUIRY</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>123</SVAN>
                    <AccountCurrency>DKK</AccountCurrency>
                    <ExchangeRate>1.00</ExchangeRate>
                    <ResponseCode>A</ResponseCode>
                    <Actions>
                        <Action>
                            <Type tid=""12"">Accept Coupon</Type>
                            <Data pid=""9"">1004019</Data>
                            <Code>10DKK</Code>
                            <Text>Coupon: 10 DKK, Always Valid</Text>
                        </Action>
                    </Actions>
                    <PrintLines />
                    <DisplayMessage>There is an eligible coupon for this card.</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var actual = await sut.CouponInquiryAsync(new AccountNumber("123"));

                // Attributes
                Assert.Equal("9.1.0000.2301", actual.HostVersion.Value);
                Assert.Equal("1", actual.Version.Value);
                Assert.Equal("posInterfaceName", actual.PosInterfaceName.Value);
                Assert.Equal("en-US", actual.Language.Value);
                Assert.Equal(Currency.Kind.DKK, actual.Currency.Value);
                Assert.Equal(0, actual.SequenceNumber.Value);
                Assert.Equal(Transmission.Kind.Normal, actual.Transmission.Value);

                // Elements
                Assert.Equal(TransactionKind.COUPON_INQUIRY, actual.RequestCode.Value);
                Assert.Equal("190826145135N000000", actual.TraceId.ToString());
                Assert.Equal(0, actual.Amount.Value);
                Assert.Equal("123", actual.AccountNumber.Value);
                Assert.Equal(Currency.Kind.DKK, actual.AccountCurrency.Value);
                Assert.Equal(1.00m, actual.ExchangeRate.Value);
                Assert.Equal(ResponseCode.Kind.Approved, actual.ResponseCode.Value);
                Assert.Single(actual.Actions);
                var action = actual.Actions[0];
                AssertAction(
                    action,
                    ActionType.TransactionId.AcceptCoupon,
                    ActionData.PromptId.PleaseEnterCoupon,
                    "1004019",
                    "10DKK",
                    "Coupon: 10 DKK, Always Valid");
                Assert.Empty(actual.PrintLines.Values);
                Assert.Equal("There is an eligible coupon for this card.", actual.DisplayMessage.Value);
            }
        }
Exemple #21
0
        public async Task valid_account_with_two_coupons()
        {
            const string response = @"
                <SVCMessage hostVersion=""9.1.0000.2301"" 
                            version=""1"" 
                            posIntfcName=""posInterfaceName"" 
                            posIntfcVersion=""1.00"" 
                            language=""en-US"" 
                            currency=""DKK"" 
                            sequence=""00"" 
                            retransmit=""n"">
                    <RequestCode>COUPON_INQUIRY</RequestCode>
                    <TraceID>190826145135N000000</TraceID>
                    <Amount>0.00</Amount>
                    <SVAN>123</SVAN>
                    <AccountCurrency>DKK</AccountCurrency>
                    <ExchangeRate>1.00</ExchangeRate>
                    <ResponseCode>A</ResponseCode>
                    <Actions>
                    <Action>
                        <Type tid=""12"">Accept Coupon</Type>
                        <Data pid=""9"">1005016</Data>
                        <Code>10DKK</Code>
                        <Text>Coupon: 10 DKK, Always Valid</Text>
                    </Action>
                    <Action>
                        <Type tid=""12"">Accept Coupon</Type>
                        <Data pid=""9"">1006014</Data>
                        <Code>10DKK</Code>
                        <Text>Coupon: 10 DKK, Always Valid</Text>
                    </Action>
                    </Actions>
                    <PrintLines/>
                    <DisplayMessage>There are 2 eligible coupons for this card.</DisplayMessage>
                </SVCMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new PosClient(_messageSequencingStrategy, executor);

            using (new TimeProviderTestScope(() => DateTime.Parse("2019-08-26T14:51:35")))
            {
                var actual = await sut.CouponInquiryAsync(new AccountNumber("123"));

                Assert.Equal("There are 2 eligible coupons for this card.", actual.DisplayMessage.Value);

                Assert.Equal(2, actual.Actions.Count);
                var a = actual.Actions[0];
                AssertAction(
                    a,
                    ActionType.TransactionId.AcceptCoupon,
                    ActionData.PromptId.PleaseEnterCoupon,
                    "1005016",
                    "10DKK",
                    "Coupon: 10 DKK, Always Valid");
                var b = actual.Actions[1];
                AssertAction(
                    b,
                    ActionType.TransactionId.AcceptCoupon,
                    ActionData.PromptId.PleaseEnterCoupon,
                    "1006014",
                    "10DKK",
                    "Coupon: 10 DKK, Always Valid");
            }
        }
        public async Task valid_entity_returns_column_metadata()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetColumnList</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <Rows>
                      <Row>
                        <Col type=""A10"">PREFIX</Col>
                        <Col type=""N19"">PARENTCACUSTOMERID</Col>
                        <Col type=""A25"">MOBILEPHONENUMBER</Col>
                        <Col type=""N1"">MEETINGPLANNER</Col>
                        <Col type=""A50"">USERIDNUMBER</Col>
                        <Col type=""A32"">LATITUDE</Col>
                        <Col type=""A32"">MIDDLENAME</Col>
                        <Col type=""Timestamp"">SIGNUPDATE</Col>
                        <Col type=""N1"">EMAILCHNLDELIVERABLE</Col>
                        <Col type=""N5"">PRIMARYPOSREFSTATUS</Col>
                        <Col type=""Timestamp"">LASTTRANSACTIONBUSINESSDATE</Col>
                        <Col type=""N1"">MAILCHNLDELIVERABLE</Col>
                        <Col type=""A50"">MISCFIELD1</Col>
                        <Col type=""Timestamp"">ANNIVERSARYDATE</Col>
                        <Col type=""Decimal"">DISTANCE</Col>
                        <Col type=""A50"">SOURCECODE</Col>
                        <Col type=""A32"">LASTUPDATEDBY</Col>
                        <Col type=""A50"">MISCFIELD4</Col>
                        <Col type=""A10"">SUFFIX</Col>
                        <Col type=""A50"">MISCFIELD3</Col>
                        <Col type=""A50"">MISCFIELD2</Col>
                        <Col type=""N10"">SIGNUPSOURCEID</Col>
                        <Col type=""A25"">WORKPHONENUMBER</Col>
                        <Col type=""Timestamp"">REISSUENEWCUSTKITDATE</Col>
                        <Col type=""N19"">SORTVALUE</Col>
                        <Col type=""A32"">STOREEXTREF</Col>
                        <Col type=""A50"">PASSWORDHINT</Col>
                        <Col type=""N10"">DATASOURCEID</Col>
                        <Col type=""Timestamp"">LASTUPDATED</Col>
                        <Col type=""N1"">OTHERCHNLDELIVERABLE</Col>
                        <Col type=""N1"">ISCLEANED</Col>
                        <Col type=""A50"">USERNAME</Col>
                        <Col type=""A50"">CITY</Col>
                        <Col type=""A25"">FAXNUMBER</Col>
                        <Col type=""N1"">ACTIVE</Col>
                        <Col type=""N5"">EMAILCHNLSTATUS</Col>
                        <Col type=""A50"">LASTNAME</Col>
                        <Col type=""A32"">STATE</Col>
                        <Col type=""Decimal"">USERNUMERIC1</Col>
                        <Col type=""N5"">HOMEPHONECHNLSTATUS</Col>
                        <Col type=""A76"">ADDRESSLINE1</Col>
                        <Col type=""A76"">ADDRESSLINE2</Col>
                        <Col type=""Timestamp"">REPLACECARDDATE</Col>
                        <Col type=""N10"">PARENTRELATIONSHIP</Col>
                        <Col type=""N19"">CACUSTOMERID</Col>
                        <Col type=""A50"">CAMPAIGN</Col>
                        <Col type=""Timestamp"">FIRSTTRANSACTIONBUSINESSDATE</Col>
                        <Col type=""N10"">REISSUENEWCUSTKITCOUNTER</Col>
                        <Col type=""A16"">OTHERPHONENUMBER</Col>
                        <Col type=""A50"">FIRSTNAME</Col>
                        <Col type=""A16"">POSTALCODE</Col>
                        <Col type=""A50"">COUNTY</Col>
                        <Col type=""N10"">HASHCODE</Col>
                        <Col type=""N5"">OTHERCHNLSTATUS</Col>
                        <Col type=""N1"">ISORGANIZATION</Col>
                        <Col type=""N1"">CONCIERGE</Col>
                        <Col type=""N19"">KID</Col>
                        <Col type=""Decimal"">USERNUMERIC2</Col>
                        <Col type=""N19"">SIGNUPLOCATIONID</Col>
                        <Col type=""A150"">PASSWORD</Col>
                        <Col type=""N10"">REPLACECARDCOUNTER</Col>
                        <Col type=""A50"">EMAILADDRESS</Col>
                        <Col type=""N1"">WELCOMEEMAILSENT</Col>
                        <Col type=""Timestamp"">BIRTHDAY</Col>
                        <Col type=""A50"">COUNTRY</Col>
                        <Col type=""Timestamp"">CREATEDDATE</Col>
                        <Col type=""N1"">USEFORTESTEMAIL</Col>
                        <Col type=""N1"">HOMEPHONECHNLDELIVERABLE</Col>
                        <Col type=""A32"">PRIMARYPOSREF</Col>
                        <Col type=""A25"">HOMEPHONENUMBER</Col>
                        <Col type=""N3"">BIRTHMONTH</Col>
                        <Col type=""A1"">GENDER</Col>
                        <Col type=""N1"">ISDEDUPED</Col>
                        <Col type=""A32"">LONGITUDE</Col>
                        <Col type=""N3"">BIRTHDAYOFMONTH</Col>
                        <Col type=""A50"">USERALPHA1</Col>
                        <Col type=""N5"">MAILCHNLSTATUS</Col>
                        <Col type=""A50"">USERALPHA2</Col>
                        <Col type=""A50"">ORGANIZATIONNAME</Col>
                        <Col type=""A10"">PMACODE</Col>
                      </Row>
                    </Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual = await sut.GetColumnListAsync("customer");

            var columns = actual.Row.Columns;

            Assert.Equal(80, columns.Count);

            // Oracle backend uses all caps for fields. That's a direct
            // translation of field names from GL's MS SQL Server database. In
            // queries both upper and lower case may be used as MS SQL Server is
            // generally case insensitive.
            Assert.Equal("A10", columns["PREFIX"]);
            Assert.Equal("N1", columns["ACTIVE"]);
        }
Exemple #23
0
        public async Task valid_account_returns_coupon_metadata()
        {
            const string response = @"
                <CRMMessage language=""en_US"" currency=""DKK"" isTrustedSAT=""false"" hostversion=""1.00"">
                  <RequestCode>GetCoupons</RequestCode>
                  <ResponseCode>A</ResponseCode>
                  <ResultSet>
                    <ResultSetMetaData>
                      <RSColumn name=""name"" type=""string"" nullable=""false""></RSColumn>
                      <RSColumn name=""description"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""serialNumber"" type=""string"" nullable=""true""></RSColumn>
                      <RSColumn name=""validFromDate"" type=""timestamp"" nullable=""true""></RSColumn>
                      <RSColumn name=""validUntilDate"" type=""timestamp"" nullable=""true""></RSColumn>
                      <RSColumn name=""redeemed"" type=""boolean"" nullable=""false""></RSColumn>
                    </ResultSetMetaData>
                    <Rows>
                      <Row>
                        <Col>10 DKK</Col>
                        <Col />
                        <Col>1006014</Col>
                        <Col />
                        <Col />
                        <Col>false</Col>
                      </Row>
                      <Row>
                        <Col>10 DKK</Col>
                        <Col />
                        <Col>1004019</Col>
                        <Col />
                        <Col />
                        <Col>true</Col>
                      </Row>
                    </Rows>
                  </ResultSet>
                </CRMMessage>";

            var handler  = CreateMockMessageHandler(HttpStatusCode.OK, CreateSoapResponse(response.Trim()));
            var executor = new OracleHospitalityExecutor(_options, _executorLogger, new HttpClient(handler));
            var sut      = new CrmClient(_options, executor);

            var actual =
                await sut.GetCouponsAsync(
                    "accountposref = ?",
                    new[]
            {
                new ColumnValue("accountposref", "123")
            });

            Assert.Equal(Language.Kind.EnUs, actual.Language.Value);
            Assert.Equal(Currency.Kind.DKK, actual.Currency.Value);
            Assert.False(actual.IsTrustedSat.Value);
            Assert.Equal("1.00", actual.HostVersion.Value);
            Assert.Equal(RequestCode.Kind.GetCoupons, actual.RequestCode.Value);
            Assert.Equal(ResponseCode.Kind.Approved, actual.ResponseCode.Value);

            var metaData = actual.MetaData;

            Assert.Equal(6, metaData.Length);
            Assert.Equal("name", metaData[0].Name_.Value);
            Assert.Equal(ResultSetMetaDataColumn.Type.Kind.String, metaData[0].Type_.Value);
            Assert.False(metaData[0].Nullable_.Value);
            Assert.Equal("redeemed", metaData[5].Name_.Value);
            Assert.Equal(ResultSetMetaDataColumn.Type.Kind.Boolean, metaData[5].Type_.Value);
            Assert.False(metaData[5].Nullable_.Value);

            var rows = actual.Rows;

            Assert.Equal(2, rows.Length);

            var r0 = Assert.IsType <string>(rows[0].Columns["name"]);

            Assert.Null(rows[0].Id);
            Assert.Equal("10 DKK", r0);
            Assert.Null(rows[0].Columns["description"]);
            var r2 = Assert.IsType <string>(rows[0].Columns["serialNumber"]);

            Assert.Equal("1006014", r2);
            Assert.Null(rows[0].Columns["validFromDate"]);
            Assert.Null(rows[0].Columns["validUntilDate"]);
            var r5 = Assert.IsType <bool>(rows[0].Columns["redeemed"]);

            Assert.False(r5);
        }