Skip to content

Commit

Permalink
Merge pull request #818 from recurly/add-revrec-settings-to-plans
Browse files Browse the repository at this point in the history
[V2] Add RevRec settings to the Plan entity
  • Loading branch information
8eth authored Feb 6, 2024
2 parents 583b1c7 + a5091aa commit 4990e0b
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 5 deletions.
31 changes: 28 additions & 3 deletions Library/Extensions/XmlWriterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ public static void WriteStringIfValid(this XmlWriter writer, string localName, s
writer.WriteElementString(localName, value);
}

/// <summary>
/// Convenience implementation that allows specifically writing "nil nodes" for the
/// purpose of unsetting associations from models. Using a simply JSON `null` is
/// simple enough in V3, but in V2, we need to write a `nil` attribute.
///
/// An empty string for <paramref name="value"/> will result in the node not being
/// created. If it is `null`, the node will be created with the attribute.
/// </summary>
/// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/> that will be written to.</param>
/// <param name="localName"></param>
/// <param name="value"></param>
public static void WriteValidStringOrNil(this XmlWriter writer, string localName, string value)
{
if (value == null)
{
writer.WriteStartElement(localName);
writer.WriteAttributeString("nil", "nil");
writer.WriteEndElement();
}
else
{
writer.WriteStringIfValid(localName, value);
}
}

/// <summary>
/// If the given collection <paramref name="items"/> has any elements, writes the contents to the <see cref="T:System.Xml.XmlTextWriter"/> <paramref name="writer"/>
/// using the provided <paramref name="localName"/> and <paramref name="stringValue"/> <see cref="T:System.Func{T,TResult}"/>s.
Expand All @@ -42,7 +67,7 @@ public static void WriteIfCollectionHasAny<T>(this XmlTextWriter writer, string
}

/// <summary>
/// If the given collection has any elements, writes the contents of the <paramref name="items"/> to the <see cref="T:System.Xml.XmlTextWriter"/>
/// If the given collection has any elements, writes the contents of the <paramref name="items"/> to the <see cref="T:System.Xml.XmlTextWriter"/>
/// using each element's <see cref="Recurly.RecurlyEntity.WriteXml"/> implementation.
/// </summary>
/// <typeparam name="T">The type of each element of <paramref name="items"/>, derived from <see cref="Recurly.RecurlyEntity"/>.</typeparam>
Expand All @@ -57,7 +82,7 @@ public static void WriteIfCollectionHasAny<T>(this XmlTextWriter writer, string
}

/// <summary>
/// If the given collection has any elements, writes the contents of the <paramref name="items"/> to the <see cref="T:System.Xml.XmlTextWriter"/>
/// If the given collection has any elements, writes the contents of the <paramref name="items"/> to the <see cref="T:System.Xml.XmlTextWriter"/>
/// using each element's <see cref="Recurly.RecurlyEntity.WriteXml"/> implementation. If the collection needs to write an empty element for an empty collection, it will do so.
/// </summary>
/// <typeparam name="T">The type of each element of <paramref name="items"/>, derived from <see cref="Recurly.RecurlyEntity"/>.</typeparam>
Expand All @@ -82,4 +107,4 @@ private static void WriteCollection<T>(this XmlTextWriter writer, string collect
writer.WriteEndElement();
}
}
}
}
28 changes: 27 additions & 1 deletion Library/Plan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Recurly
{
public class Plan : RecurlyEntity
public class Plan : RevRecEntity
{
public enum IntervalUnit
{
Expand Down Expand Up @@ -41,6 +41,10 @@ public enum IntervalUnit
public string AccountingCode { get; set; }
public string SetupFeeAccountingCode { get; set; }

public string SetupFeeLiabilityGlAccountId = "";
public string SetupFeeRevenueGlAccountId = "";
public string SetupFeePerformanceObligationId { get; set; }

public DateTime CreatedAt { get; private set; }
public DateTime UpdatedAt { get; private set; }

Expand Down Expand Up @@ -288,6 +292,10 @@ internal override void ReadXml(XmlTextReader reader)

bool b;

// reading standard revrec nodes. setup fee revrec nodes are
// implemented manually, in this class.
ReadRevRecNode(reader);

switch (reader.Name)
{
case "plan_code":
Expand Down Expand Up @@ -364,6 +372,18 @@ internal override void ReadXml(XmlTextReader reader)
SetupFeeAccountingCode = reader.ReadElementContentAsString();
break;

case "setup_fee_liability_gl_account_id":
SetupFeeLiabilityGlAccountId = reader.ReadElementContentAsString();
break;

case "setup_fee_revenue_gl_account_id":
SetupFeeRevenueGlAccountId = reader.ReadElementContentAsString();
break;

case "setup_fee_performance_obligation_id":
SetupFeePerformanceObligationId = reader.ReadElementContentAsString();
break;

case "dunning_campaign_id":
DunningCampaignId = reader.ReadElementContentAsString();
break;
Expand Down Expand Up @@ -455,6 +475,12 @@ internal override void WriteXml(XmlTextWriter xmlWriter)
xmlWriter.WriteStringIfValid("accounting_code", AccountingCode);
xmlWriter.WriteStringIfValid("setup_fee_accounting_code", SetupFeeAccountingCode);

// product revrec features (and setup fee revrec features)
WriteRevRecNodes(xmlWriter);
xmlWriter.WriteValidStringOrNil("setup_fee_liability_gl_account_id", SetupFeeLiabilityGlAccountId);
xmlWriter.WriteValidStringOrNil("setup_fee_revenue_gl_account_id", SetupFeeRevenueGlAccountId);
xmlWriter.WriteStringIfValid("setup_fee_performance_obligation_id", SetupFeePerformanceObligationId);

if (DunningCampaignId != null)
xmlWriter.WriteElementString("dunning_campaign_id", DunningCampaignId);

Expand Down
36 changes: 36 additions & 0 deletions Library/RevRecEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Xml;

namespace Recurly
{
public abstract class RevRecEntity : RecurlyEntity
{
public string LiabilityGlAccountId = "";
public string RevenueGlAccountId = "";
public string PerformanceObligationId { get; set; }

internal protected void ReadRevRecNode(XmlTextReader reader)
{
switch (reader.Name)
{
case "liability_gl_account_id":
LiabilityGlAccountId = reader.ReadElementContentAsString();
break;

case "revenue_gl_account_id":
RevenueGlAccountId = reader.ReadElementContentAsString();
break;

case "performance_obligation_id":
PerformanceObligationId = reader.ReadElementContentAsString();
break;
};
}

internal protected void WriteRevRecNodes(XmlTextWriter writer)
{
writer.WriteValidStringOrNil("liability_gl_account_id", LiabilityGlAccountId);
writer.WriteValidStringOrNil("revenue_gl_account_id", RevenueGlAccountId);
writer.WriteStringIfValid("performance_obligation_id", PerformanceObligationId);
}
}
}
2 changes: 2 additions & 0 deletions Test/Fixtures/FixtureImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,7 @@ public enum FixtureType
GeneralLedgerAccounts,
[Description("performance_obligations")]
PerformanceObligations,
[Description("plans")]
Plans,
}
}
6 changes: 6 additions & 0 deletions Test/Fixtures/plans/show-200.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Content-Type: application/xml; charset=utf-8
<total_billing_cycles type="integer">6</total_billing_cycles>
<accounting_code nil="nil"></accounting_code>
<dunning_campaign_id>1234abcd</dunning_campaign_id>
<liability_gl_account_id>twrbsq39zvo5</liability_gl_account_id>
<revenue_gl_account_id>bwrks63lznoi</revenue_gl_account_id>
<performance_obligation_id>rkslzn</performance_obligation_id>
<setup_fee_liability_gl_account_id>twrisqjjzvo5</setup_fee_liability_gl_account_id>
<setup_fee_revenue_gl_account_id>dlrk123lzabc</setup_fee_revenue_gl_account_id>
<setup_fee_performance_obligation_id>bks6noi</setup_fee_performance_obligation_id>
<created_at type="datetime">2011-04-19T07:00:00Z</created_at>
<unit_amount_in_cents>
<USD type="integer">1000</USD>
Expand Down
21 changes: 20 additions & 1 deletion Test/PlanTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using FluentAssertions;
using Recurly.Test.Fixtures;
using Xunit;



namespace Recurly.Test
{
public class PlanTest : BaseTest
Expand Down Expand Up @@ -284,5 +287,21 @@ public void DeactivatePlan()
get.ShouldThrow<NotFoundException>();
}

[RecurlyFact(TestEnvironment.Type.Unit)]
public void CheckForRevRecData()
{
var plan = new Plan();

var xmlFixture = FixtureImporter.Get(FixtureType.Plans, "show-200").Xml;
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(xmlFixture));
plan.ReadXml(reader);

plan.LiabilityGlAccountId.Should().Be("twrbsq39zvo5");
plan.RevenueGlAccountId.Should().Be("bwrks63lznoi");
plan.PerformanceObligationId.Should().Be("rkslzn");
plan.SetupFeeLiabilityGlAccountId.Should().Be("twrisqjjzvo5");
plan.SetupFeeRevenueGlAccountId.Should().Be("dlrk123lzabc");
plan.SetupFeePerformanceObligationId.Should().Be("bks6noi");
}
}
}

0 comments on commit 4990e0b

Please sign in to comment.