From 093c5737ea2e317886df67b24b6515da158052e4 Mon Sep 17 00:00:00 2001 From: Luke Kirby Date: Thu, 12 Sep 2019 11:15:40 +0100 Subject: [PATCH] Changes to BatchPayment to avoid timezone Issue The payment date of the batch payment should be passed as a string in the format yyyy-MM-dd according to the Xero API docs page however as it was being parsed as a date, it was subject to the timezone difference between the API user and Xero, so if you parsed a date object without a timepart, you could end up with yesterday's date being set for the payment date. See https://developer.xero.com/documentation/api/batch-payments#PUT --- CoreTests/CoreTests.csproj | 2 + .../BatchPayment/BatchPaymentsTest.cs | 66 +++++++++++++++++++ CoreTests/Integration/BatchPayment/Create.cs | 36 ++++++++++ Xero.Api/Core/Model/BatchPayment.cs | 18 ++++- 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 CoreTests/Integration/BatchPayment/BatchPaymentsTest.cs create mode 100644 CoreTests/Integration/BatchPayment/Create.cs diff --git a/CoreTests/CoreTests.csproj b/CoreTests/CoreTests.csproj index cb863932..c64e248d 100644 --- a/CoreTests/CoreTests.csproj +++ b/CoreTests/CoreTests.csproj @@ -86,6 +86,8 @@ + + diff --git a/CoreTests/Integration/BatchPayment/BatchPaymentsTest.cs b/CoreTests/Integration/BatchPayment/BatchPaymentsTest.cs new file mode 100644 index 00000000..b018c07b --- /dev/null +++ b/CoreTests/Integration/BatchPayment/BatchPaymentsTest.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using Xero.Api.Core.Model; +using Xero.Api.Core.Model.Status; +using Xero.Api.Core.Model.Types; + +namespace CoreTests.Integration.BatchPayments +{ + public abstract class BatchPaymentsTest : ApiWrapperTest + { + protected BatchPayment Given_a_batch_payment(decimal invoiceAmount, DateTime date, decimal amount, bool isReconciled = false) + { + var batchPayment = CreateBatchPayment(invoiceAmount, date, amount, isReconciled); + + return Api.BatchPayments.Create(batchPayment); + } + + protected BatchPayment CreateBatchPayment(decimal invoiceAmount, DateTime date, decimal amount, bool isReconciled = false) + { + var invoice = Given_an_invoice(invoiceAmount, Account.Code); + var bankCode = BankAccount.Id; + + var payment = new BatchPayment + { + Account = new Account { Id = bankCode }, + Date = date, + Payments = new List { new BatchPaymentPayment { + Amount = amount, + Invoice = new Invoice { Id = invoice.Id}, + BankAccountNumber = BankAccount.BankAccountNumber, + }} + }; + + if (isReconciled) + { + payment.IsReconciled = true; + } + + return payment; + } + + private Invoice Given_an_invoice(decimal amount = 100m, string accountCode = "100") + { + return Api.Create(new Invoice + { + Contact = new Contact { Name = "Richard" }, + Number = Random.GetRandomString(10), + Type = InvoiceType.AccountsPayable, + Date = DateTime.UtcNow, + DueDate = DateTime.UtcNow.AddDays(90), + LineAmountTypes = LineAmountType.Inclusive, + Status = InvoiceStatus.Authorised, + LineItems = new List + { + new LineItem + { + AccountCode = accountCode, + Description = "Good value item", + LineAmount = amount + } + } + }); + } + + } +} \ No newline at end of file diff --git a/CoreTests/Integration/BatchPayment/Create.cs b/CoreTests/Integration/BatchPayment/Create.cs new file mode 100644 index 00000000..2208d5c2 --- /dev/null +++ b/CoreTests/Integration/BatchPayment/Create.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Xero.Api.Core.Model; + +namespace CoreTests.Integration.BatchPayments +{ + [TestFixture] + public class Create : BatchPaymentsTest + { + [TestFixtureSetUp] + public void CreateBatchPaymentsSetUp() + { + SetUp(); + } + + [Test] + public void create_simple_batch_payment() + { + var date = DateTime.UtcNow; + const decimal expectedTotal = 32.6m; + const decimal invoiceAmount = 100; + + var batchPayment = Given_a_batch_payment(invoiceAmount, date, expectedTotal); + + Assert.IsNotNull(batchPayment); + + Assert.AreEqual(expectedTotal, batchPayment.Total); + Assert.AreEqual(date.Date, batchPayment.Date); + + + } + + } +} diff --git a/Xero.Api/Core/Model/BatchPayment.cs b/Xero.Api/Core/Model/BatchPayment.cs index 167ed40d..8f51580b 100644 --- a/Xero.Api/Core/Model/BatchPayment.cs +++ b/Xero.Api/Core/Model/BatchPayment.cs @@ -4,6 +4,7 @@ using Xero.Api.Common; using Xero.Api.Core.Model.Status; using Xero.Api.Core.Model.Types; +using Xero.Api.Infrastructure.ThirdParty.ServiceStack.Text.Common; namespace Xero.Api.Core.Model { @@ -37,10 +38,21 @@ public class BatchPayment : HasUpdatedDate, IHasId [DataMember(Name = "Narrative", EmitDefaultValue = false)] public string Narrative { get; set; } - [DataMember(Name = "Date", EmitDefaultValue = false)] - public DateTime? Date { get; set; } + public DateTime? Date { get; set; } - [DataMember(Name = "Payments")] + [DataMember(Name = "Date", EmitDefaultValue = false)] + public string DateString { + get + { + return Date.Value.ToString("yyyy-MM-dd"); + } + set + { + Date = DateTimeSerializer.ParseDateTimeOffset(value).UtcDateTime; + } + } + + [DataMember(Name = "Payments")] public List Payments { get; set; } [DataMember(Name = "TotalAmount", EmitDefaultValue = false)]