Skip to content

Commit

Permalink
[AWE-774] Add external payment phases
Browse files Browse the repository at this point in the history
GET /external_subscriptions/{external_subscription_id}/external_payment_phases
GET /external_subscriptions/{external_subscription_id}/external_payment_phases/{external_payment_phase_id}
GET /external_payment_phases/{external_payment_phase_id}
  • Loading branch information
paulorbpinho-fullstacklabs committed Nov 28, 2023
1 parent e02b0f5 commit 85fc56e
Show file tree
Hide file tree
Showing 15 changed files with 483 additions and 13 deletions.
15 changes: 15 additions & 0 deletions Library/ExternalInvoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ public ExternalSubscription ExternalSubscription
internal set { _externalSubscription = value; }
}

private string _externalPaymentPhaseUuid;
public string ExternalPaymentPhaseUuid => _externalPaymentPhaseUuid;

private ExternalPaymentPhase _externalPaymentPhase;
public ExternalPaymentPhase ExternalPaymentPhase
{
get { return _externalPaymentPhase ?? (_externalPaymentPhase = ExternalPaymentPhases.Get(_externalPaymentPhaseUuid)); }
internal set { _externalPaymentPhase = value; }
}
public string ExternalId { get; private set; }
public ExternalInvoiceState State { get; private set; }
public decimal Total { get; private set; }
Expand Down Expand Up @@ -86,6 +95,12 @@ internal override void ReadXml(XmlTextReader reader)
_externalSubscriptionUuid = Uri.UnescapeDataString(href.Substring(href.LastIndexOf("/") + 1));
break;

case "external_payment_phase":
href = reader.GetAttribute("href");
if (null != href)
_externalPaymentPhaseUuid = Uri.UnescapeDataString(href.Substring(href.LastIndexOf("/") + 1));
break;

case "external_id":
ExternalId = reader.ReadElementContentAsString();
break;
Expand Down
154 changes: 154 additions & 0 deletions Library/ExternalPaymentPhase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using System;
using System.Net;
using System.Xml;

namespace Recurly
{
public class ExternalPaymentPhase : RecurlyEntity
{
public DateTime StartedAt { get; private set; }
public DateTime EndsAt { get; private set; }
public int StartingBillingPeriodIndex { get; private set; }
public int EndingBillingPeriodIndex { get; private set; }
public string OfferType { get; private set; }
public string OfferName { get; private set; }
public int PeriodCount { get; private set; }
public string PeriodLength { get; private set; }
public decimal Amount { get; private set; }
public string Currency { get; private set; }
public DateTime CreatedAt { get; private set; }
public DateTime UpdatedAt { get; private set; }

internal const string UrlPrefix = "/external_payment_phases/";

internal ExternalPaymentPhase()
{
}
internal ExternalPaymentPhase(XmlTextReader reader)
{
ReadXml(reader);
}
#region Read XML documents

internal override void ReadXml(XmlTextReader reader)
{
while (reader.Read())
{
DateTime dateVal;

if (reader.Name == "external_payment_phase" && reader.NodeType == XmlNodeType.EndElement)
break;

if (reader.NodeType != XmlNodeType.Element) continue;

switch (reader.Name)
{
case "started_at":
if (DateTime.TryParse(reader.ReadElementContentAsString(), out dateVal))
StartedAt = dateVal; ;
break;

case "ends_at":
if (DateTime.TryParse(reader.ReadElementContentAsString(), out dateVal))
EndsAt = dateVal; ;
break;

case "starting_billing_period_index":
StartingBillingPeriodIndex = reader.ReadElementContentAsInt();
break;

case "ending_billing_period_index":
EndingBillingPeriodIndex = reader.ReadElementContentAsInt();
break;

case "offer_type":
OfferType = reader.ReadElementContentAsString();
break;

case "offer_name":
OfferName = reader.ReadElementContentAsString();
break;

case "period_count":
PeriodCount = reader.ReadElementContentAsInt();
break;

case "period_length":
PeriodLength = reader.ReadElementContentAsString();
break;

case "amount":
Amount = reader.ReadElementContentAsDecimal();
break;

case "currency":
Currency = reader.ReadElementContentAsString();
break;

case "updated_at":
if (DateTime.TryParse(reader.ReadElementContentAsString(), out dateVal))
UpdatedAt = dateVal; ;
break;

case "created_at":
if (DateTime.TryParse(reader.ReadElementContentAsString(), out dateVal))
CreatedAt = dateVal; ;
break;

}
}
}

internal override void WriteXml(XmlTextWriter writer)
{
throw new NotImplementedException();
}

#endregion

#region Object Overrides

public override string ToString()
{
return "Recurly External Payment Phase: " + StartedAt + " " + EndsAt + " " + StartingBillingPeriodIndex + " " + EndingBillingPeriodIndex + " " + OfferType + " " + OfferName + " " + PeriodCount + " " + PeriodLength + " " + Amount + " " + Currency + " " + CreatedAt + " " + UpdatedAt;
}

#endregion
}

public sealed class ExternalPaymentPhases
{
/// <summary>
/// Returns a list of recurly external_payment_phases
/// </summary>
/// <returns></returns>
public static RecurlyList<ExternalPaymentPhase> List()
{
return List(null);
}
/// <summary>
/// Returns a list of recurly external_payment_phases
/// </summary>
/// <param name="filter">FilterCriteria used to apply server side sorting and filtering</param>
/// <returns></returns>
public static RecurlyList<ExternalPaymentPhase> List(FilterCriteria filter)
{
filter = filter ?? FilterCriteria.Instance;
var parameters = filter.ToNamedValueCollection();
return new ExternalPaymentPhaseList(ExternalPaymentPhase.UrlPrefix + "?" + parameters.ToString());
}
public static ExternalPaymentPhase Get(string uuid)
{
if (string.IsNullOrWhiteSpace(uuid))
{
return null;
}
var externalPaymentPhase = new ExternalPaymentPhase();
var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get,
ExternalPaymentPhase.UrlPrefix + Uri.EscapeDataString(uuid),
externalPaymentPhase.ReadXml);

return statusCode == HttpStatusCode.NotFound ? null : externalPaymentPhase;
}
}
}
34 changes: 34 additions & 0 deletions Library/ExternalSubscription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public Account Account
internal set { _account = value; }
}

private List<ExternalInvoice> _externalInvoices;
public List<ExternalInvoice> ExternalInvoices
{
get { return _externalInvoices ?? (_externalInvoices = new List<ExternalInvoice>()); }
set { _externalInvoices = value; }
}
public string ExternalId { get; set; }
public string AppIdentifier { get; private set; }
public string State { get; set; }
Expand Down Expand Up @@ -204,5 +210,33 @@ public static RecurlyList<ExternalInvoice> GetExternalInvoices(string uuid)
{
return new ExternalInvoiceList(ExternalSubscription.UrlPrefix + Uri.EscapeDataString(uuid) + "/external_invoices/");
}

/// <summary>
/// Returns a list of external_payment_phases for this external subscription
/// </summary>
/// <returns></returns>
public static RecurlyList<ExternalPaymentPhase> GetExternalPaymentPhases(string uuid)
{
return new ExternalPaymentPhaseList(ExternalSubscription.UrlPrefix + Uri.EscapeDataString(uuid) + ExternalPaymentPhase.UrlPrefix);
}

/// <summary>
/// Returns an external payment phase for external subscription
/// </summary>
/// <returns></returns>
public static ExternalPaymentPhase GetExternalPaymentPhase(string uuid, string externalPaymentPhaseUuid)
{
if (string.IsNullOrWhiteSpace(uuid) || string.IsNullOrWhiteSpace(externalPaymentPhaseUuid))
{
return null;
}
var externalPaymentPhase = new ExternalPaymentPhase();
var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get,
ExternalSubscription.UrlPrefix + Uri.EscapeDataString(uuid) + ExternalPaymentPhase.UrlPrefix + Uri.EscapeDataString(externalPaymentPhaseUuid),
externalPaymentPhase.ReadXml);

return statusCode == HttpStatusCode.NotFound ? null : externalPaymentPhase;
}

}
}
3 changes: 3 additions & 0 deletions Library/List/ExternalInvoiceList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ internal ExternalInvoiceList(string baseUrl) : base(Client.HttpRequestMethod.Get
{
}

internal ExternalInvoiceList()
{
}
public override RecurlyList<ExternalInvoice> Start
{
get { return HasStartPage() ? new ExternalInvoiceList(StartUrl) : RecurlyList.Empty<ExternalInvoice>(); }
Expand Down
43 changes: 43 additions & 0 deletions Library/List/ExternalPaymentPhaseList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Xml;

namespace Recurly
{
public class ExternalPaymentPhaseList : RecurlyList<ExternalPaymentPhase>
{
internal ExternalPaymentPhaseList(string baseUrl) : base(Client.HttpRequestMethod.Get, baseUrl)
{
}

internal ExternalPaymentPhaseList()
{
}
public override RecurlyList<ExternalPaymentPhase> Start
{
get { return HasStartPage() ? new ExternalPaymentPhaseList(StartUrl) : RecurlyList.Empty<ExternalPaymentPhase>(); }
}

public override RecurlyList<ExternalPaymentPhase> Next
{
get { return HasNextPage() ? new ExternalPaymentPhaseList(NextUrl) : RecurlyList.Empty<ExternalPaymentPhase>(); }
}

public override RecurlyList<ExternalPaymentPhase> Prev
{
get { return HasPrevPage() ? new ExternalPaymentPhaseList(PrevUrl) : RecurlyList.Empty<ExternalPaymentPhase>(); }
}

internal override void ReadXml(XmlTextReader reader)
{
while (reader.Read())
{
if (reader.Name == "external_payment_phases" && reader.NodeType == XmlNodeType.EndElement)
break;

if (reader.NodeType == XmlNodeType.Element && reader.Name == "external_payment_phase")
{
Add(new ExternalPaymentPhase(reader));
}
}
}
}
}
16 changes: 10 additions & 6 deletions Test/ExternalInvoiceTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Xml;
using FluentAssertions;
using Xunit;
using Recurly.Test.Fixtures;

namespace Recurly.Test
{
Expand All @@ -10,12 +10,16 @@ public class ExternalInvoiceTest : BaseTest
[RecurlyFact(TestEnvironment.Type.Integration)]
public void LookupExternalInvoice()
{
var uuid = "sl7984v66da8";
var externalInvoice = ExternalInvoices.Get(uuid);
externalInvoice.ExternalId.Should().Be("external_id");
var xmlFixture = FixtureImporter.Get(FixtureType.ExternalInvoices, "show-200").Xml;
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(xmlFixture));
var externalInvoice = new ExternalInvoice();
externalInvoice.ReadXml(reader);
externalInvoice.ExternalId.Should().Be("2000000458276005");
externalInvoice.State.Should().Be(ExternalInvoice.ExternalInvoiceState.Paid);
externalInvoice.Total.Should().Be(123);
externalInvoice.Total.Should().Be(new decimal(10.45));
externalInvoice.Currency.Should().Be("USD");
externalInvoice.ExternalSubscriptionUuid.Should().Be("tsfnx2vn5wh6");
externalInvoice.ExternalPaymentPhaseUuid.Should().Be("twqswp627ri3");
externalInvoice.PurchasedAt.Should().NotBe(default(DateTime));
externalInvoice.CreatedAt.Should().NotBe(default(DateTime));
externalInvoice.UpdatedAt.Should().NotBe(default(DateTime));
Expand Down
31 changes: 31 additions & 0 deletions Test/ExternalPaymentPhaseTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Xml;
using FluentAssertions;
using Recurly.Test.Fixtures;

namespace Recurly.Test
{
public class ExternalPaymentPhaseTest : BaseTest
{
[RecurlyFact(TestEnvironment.Type.Integration)]
public void LookupExternalPaymentPhase()
{
var externalPaymentPhase = new ExternalPaymentPhase();
var xmlFixture = FixtureImporter.Get(FixtureType.ExternalPaymentPhases, "show-200").Xml;
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(xmlFixture));
externalPaymentPhase.ReadXml(reader);
externalPaymentPhase.StartedAt.Should().Be(new DateTime(2023, 11, 15, 0, 0, 0, DateTimeKind.Utc));
externalPaymentPhase.EndsAt.Should().Be(new DateTime(2023, 11, 17, 21, 27, 10, DateTimeKind.Utc));
externalPaymentPhase.StartingBillingPeriodIndex.Should().Be(1);
externalPaymentPhase.EndingBillingPeriodIndex.Should().Be(2);
externalPaymentPhase.OfferType.Should().Be("FREE_TRIAL");
externalPaymentPhase.OfferName.Should().Be("introductory");
externalPaymentPhase.PeriodCount.Should().Be(2);
externalPaymentPhase.PeriodLength.Should().Be("TWO WEEKS");
externalPaymentPhase.Amount.Should().Be(new decimal(1.99));
externalPaymentPhase.Currency.Should().Be("USD");
externalPaymentPhase.CreatedAt.Should().Be(new DateTime(2023, 11, 15, 16, 16, 43, DateTimeKind.Utc));
externalPaymentPhase.UpdatedAt.Should().Be(new DateTime(2023, 11, 15, 16, 16, 43, DateTimeKind.Utc));
}
}
}
17 changes: 15 additions & 2 deletions Test/Fixtures/FixtureImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ namespace Recurly.Test.Fixtures
{
public class FixtureImporter
{
public static string GetFixtureTypeDescription(FixtureType type)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])type
.GetType()
.GetField(type.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false);

return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
public static FixtureResponse Get(FixtureType type, string name)
{
if (name.IsNullOrEmpty())
Expand All @@ -16,7 +25,7 @@ public static FixtureResponse Get(FixtureType type, string name)
if (!Enum.IsDefined(typeof(FixtureType), type))
throw new InvalidEnumArgumentException("type", (int)type, typeof(FixtureType));

var fixturePath = string.Format("fixtures/{0}/{1}.xml", type, name);
var fixturePath = string.Format("Fixtures/{0}/{1}.xml", GetFixtureTypeDescription(type), name);

if (!File.Exists(fixturePath))
throw new FileNotFoundException("Could not locate the fixture response file!", fixturePath);
Expand Down Expand Up @@ -66,6 +75,10 @@ private static KeyValuePair<string, string> ParseHeader(string line)

public enum FixtureType
{
Accounts
Accounts,
[Description("external_payment_phases")]
ExternalPaymentPhases,
[Description("external_invoices")]
ExternalInvoices,
}
}
Loading

0 comments on commit 85fc56e

Please sign in to comment.