Skip to content

Commit

Permalink
feat: deal timeline endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidRouyer committed Jun 17, 2021
1 parent 583d5d4 commit b23d116
Show file tree
Hide file tree
Showing 15 changed files with 283 additions and 10 deletions.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ You can debug this library right from your application by configuring the [NuGet
- [x] getDeals
- [x] searchDeals
- [x] getDealsSummary
- [ ] getDealsTimeline
- [x] getDealsTimeline
- [x] getDeal
- [x] getDealActivities
- [ ] getDealFiles
Expand Down
19 changes: 19 additions & 0 deletions src/Pipedrive.net.Tests.Integration/Clients/DealsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,25 @@ public async Task ReturnsCorrectSummaryWithFilters()
}
}

public class TheGetTimelineMethod
{
[IntegrationTest]
public async Task ReturnsCorrectTimeline()
{
var pipedrive = Helper.GetAuthenticatedClient();

var timeline = await pipedrive.Deal.GetTimeline(new DealsTimelineFilters()
{
StartDate = new DateTime(2019, 01, 01),
Interval = DateInterval.Month,
Amount = 12,
FieldKey = "close_time",
});

Assert.Equal(12, timeline.Count);
}
}

public class TheGetUpdatesMethod
{
[IntegrationTest]
Expand Down
40 changes: 40 additions & 0 deletions src/Pipedrive.net.Tests/Clients/DealsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,46 @@ await connection.Get<DealSummary>(
}
}

public class TheGetTimelineMethod
{
[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new DealsClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetTimeline(null));
}

[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DealsClient(connection);

var filters = new DealsTimelineFilters
{
StartDate = new DateTime(2021, 01, 01),
Interval = DateInterval.Month,
Amount = 1,
FieldKey = "close_time"
};

await client.GetTimeline(filters);

Received.InOrder(async () =>
{
await connection.Get<IReadOnlyList<DealTimeline>>(
Arg.Is<Uri>(u => u.ToString() == "deals/timeline"),
Arg.Is<Dictionary<string, string>>(d => d.Count == 5
&& d["start_date"] == "2021-01-01"
&& d["interval"] == "month"
&& d["amount"] == "1"
&& d["field_key"] == "close_time"
&& d["exclude_deals"] == "0"));
});
}
}

public class TheGetUpdatesMethod
{
[Fact]
Expand Down
9 changes: 9 additions & 0 deletions src/Pipedrive.net/Clients/DealsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ public Task<DealSummary> GetSummary(DealsSummaryFilters filters)
return ApiConnection.Get<DealSummary>(ApiUrls.DealsSummary(), parameters);
}

public Task<IReadOnlyList<DealTimeline>> GetTimeline(DealsTimelineFilters filters)
{
Ensure.ArgumentNotNull(filters, nameof(filters));

var parameters = filters.Parameters;

return ApiConnection.Get<IReadOnlyList<DealTimeline>>(ApiUrls.DealsTimeline(), parameters);
}

public Task<IReadOnlyList<EntityUpdateFlow>> GetUpdates(long dealId, DealUpdateFilters filters)
{
Ensure.ArgumentNotNull(filters, nameof(filters));
Expand Down
2 changes: 2 additions & 0 deletions src/Pipedrive.net/Clients/IDealsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface IDealsClient

Task<DealSummary> GetSummary(DealsSummaryFilters filters);

Task<IReadOnlyList<DealTimeline>> GetTimeline(DealsTimelineFilters filters);

Task<IReadOnlyList<EntityUpdateFlow>> GetUpdates(long dealId, DealUpdateFilters filters);

Task<IReadOnlyList<DealFollower>> GetFollowers(long dealId);
Expand Down
42 changes: 42 additions & 0 deletions src/Pipedrive.net/Converters/CurrencyValueConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Pipedrive.Internal
{
public class CurrencyValueConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<string, decimal>);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var values = new Dictionary<string, decimal>();

Console.WriteLine(reader.TokenType);
if (reader.TokenType == JsonToken.StartObject)
{
var jObject = JObject.Load(reader);
foreach (var property in jObject.Properties())
{
values.Add(property.Name, property.Value.ToObject<decimal>());
}
}

if (reader.TokenType == JsonToken.StartArray)
{
JArray.Load(reader);
}

return values;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new System.NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@

namespace Pipedrive.Internal
{
public class ValueTotalConverter : JsonConverter
public class CurrencyValueTotalConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<string, ValueTotal>);
return objectType == typeof(Dictionary<string, CurrencyValueTotal>);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var values = new Dictionary<string, ValueTotal>();
var values = new Dictionary<string, CurrencyValueTotal>();

var jObject = JObject.Load(reader);
foreach (var property in jObject.Properties())
{
values.Add(property.Name, property.Value.ToObject<ValueTotal>());
values.Add(property.Name, property.Value.ToObject<CurrencyValueTotal>());
}

return values;
Expand Down
5 changes: 5 additions & 0 deletions src/Pipedrive.net/Helpers/ApiUrls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ public static Uri DealsSummary()
return new Uri("deals/summary", UriKind.Relative);
}

public static Uri DealsTimeline()
{
return new Uri("deals/timeline", UriKind.Relative);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the specified deal.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/Pipedrive.net/Models/Common/DateInterval.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Pipedrive
{
public enum DateInterval
{
Day,
Week,
Month,
Quarter
}
}
8 changes: 8 additions & 0 deletions src/Pipedrive.net/Models/Common/ExcludeDeals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Pipedrive
{
public enum ExcludeDeals
{
None = 0,
Exclude = 1
}
}
74 changes: 74 additions & 0 deletions src/Pipedrive.net/Models/Request/Deals/DealsTimelineFilters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Pipedrive
{
public class DealsTimelineFilters
{
[JsonProperty("start_date")]
public DateTime StartDate { get; set; }

public DateInterval Interval { get; set; }

public long Amount { get; set; }

[JsonProperty("field_key")]
public string FieldKey { get; set; }

[JsonProperty("user_id")]
public long? UserId { get; set; }

[JsonProperty("pipeline_id")]
public long? PipelineId { get; set; }

[JsonProperty("filter_id")]
public long? FilterId { get; set; }

[JsonProperty("exclude_deals")]
public ExcludeDeals ExcludeDeals { get; set; }

[JsonProperty("totals_convert_currency")]
public string TotalsConvertCurrency { get; set; }

/// <summary>
/// Get the query parameters that will be appending onto the search
/// </summary>
public IDictionary<string, string> Parameters
{
get
{
var d = new Dictionary<string, string>();

d.Add("start_date", StartDate.ToString("yyyy-MM-dd"));
d.Add("interval", Interval.ToString().ToLower());
d.Add("amount", Amount.ToString());
d.Add("field_key", FieldKey);

if (FilterId.HasValue)
{
d.Add("filter_id", FilterId.Value.ToString());
}

if (PipelineId.HasValue)
{
d.Add("pipeline_id", PipelineId.Value.ToString());
}

if (UserId.HasValue)
{
d.Add("user_id", UserId.Value.ToString());
}

d.Add("exclude_deals", ((long)ExcludeDeals).ToString());

if (!string.IsNullOrWhiteSpace(TotalsConvertCurrency))
{
d.Add("totals_convert_currency", TotalsConvertCurrency);
}

return d;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Pipedrive
{
public class ValueTotal
public class CurrencyValueTotal
{
public long Value { get; set; }

Expand Down
8 changes: 4 additions & 4 deletions src/Pipedrive.net/Models/Response/Deals/DealSummary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace Pipedrive
public class DealSummary
{
[JsonProperty("values_total")]
[JsonConverter(typeof(ValueTotalConverter))]
public IReadOnlyDictionary<string, ValueTotal> ValuesTotal { get; set; }
[JsonConverter(typeof(CurrencyValueTotalConverter))]
public IReadOnlyDictionary<string, CurrencyValueTotal> ValuesTotal { get; set; }

[JsonProperty("weighted_values_total")]
[JsonConverter(typeof(ValueTotalConverter))]
public IReadOnlyDictionary<string, ValueTotal> WeightedValuesTotal { get; set; }
[JsonConverter(typeof(CurrencyValueTotalConverter))]
public IReadOnlyDictionary<string, CurrencyValueTotal> WeightedValuesTotal { get; set; }

[JsonProperty("total_count")]
public long TotalCount { get; set; }
Expand Down
51 changes: 51 additions & 0 deletions src/Pipedrive.net/Models/Response/Deals/DealTimeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Pipedrive.Internal;

namespace Pipedrive
{
public class DealTimeline
{
[JsonProperty("period_start")]
public DateTime PeriodStart { get; set; }

[JsonProperty("period_end")]
public DateTime PeriodEnd { get; set; }

public IReadOnlyList<DealTimelineDeal> Deals { get; set; } = new List<DealTimelineDeal>();

public DealTimelineTotals Totals { get; set; }
}

public class DealTimelineTotals
{
public long Count { get; set; }

[JsonProperty("values")]
[JsonConverter(typeof(CurrencyValueConverter))]
public IReadOnlyDictionary<string, decimal> Values { get; set; }

[JsonProperty("weighted_values")]
[JsonConverter(typeof(CurrencyValueConverter))]
public IReadOnlyDictionary<string, decimal> WeightedValues { get; set; }

[JsonProperty("open_count")]
public long OpenCount { get; set; }

[JsonProperty("open_values")]
[JsonConverter(typeof(CurrencyValueConverter))]
public IReadOnlyDictionary<string, decimal> OpenValues { get; set; }

[JsonProperty("weighted_open_values")]
[JsonConverter(typeof(CurrencyValueConverter))]
public IReadOnlyDictionary<string, decimal> WeightedOpenValues { get; set; }

[JsonProperty("won_count")]
public long WonCount { get; set; }

[JsonProperty("won_values")]
[JsonConverter(typeof(CurrencyValueConverter))]
public IReadOnlyDictionary<string, decimal> WonValues { get; set; }
}
}
13 changes: 13 additions & 0 deletions src/Pipedrive.net/Models/Response/Deals/DealTimelineDeal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Pipedrive.Internal;

namespace Pipedrive
{
[JsonConverter(typeof(CustomFieldConverter))]
public class DealTimelineDeal : AbstractDeal<long?, long?, long?>, IEntityWithCustomFields
{
[JsonIgnore]
public IDictionary<string, ICustomField> CustomFields { get; set; }
}
}

0 comments on commit b23d116

Please sign in to comment.