diff --git a/.fernignore b/.fernignore index 82ea2627..cc92f21b 100644 --- a/.fernignore +++ b/.fernignore @@ -3,4 +3,8 @@ README.md # Workflows -.github/ \ No newline at end of file +.github/ + +# Version Twekas +src/Merge.Client/Merge.Client.csproj +src/Merge.Client/Merge.cs diff --git a/README.md b/README.md index 64f509c9..818af610 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ of the SDK methods are awaitable! ```csharp using Merge; -using Merge.ATS; +using Merge.Ats; -MergeClient merge = new MergeClient( - "YOUR_API_KEY", "YOUR_ACCOUNT_ID" +Merge merge = new Merge( + "YOUR_API_KEY", "YOUR_ACCOUNT_TOKEN" ) ``` @@ -41,8 +41,8 @@ using more than one Merge API category right now, the SDK provides upgrade-flexi Each category is namespaced: ```csharp -MergeClient merge = new MergeClient( - "YOUR_API_KEY", "YOUR_ACCOUNT_ID" +Merge merge = new Merge( + "YOUR_API_KEY", "YOUR_ACCOUNT_TOKEN" ) merge.ATS. # APIs specific to the ATS Category @@ -54,7 +54,7 @@ merge.HRIS. # APIs specific to the HRIS Category You can override the HttpClient by passing in `ClientOptions`. ```csharp -merge = new MergeClient("YOUR_API_KEY", "YOUR_ACCOUNT_ID", new ClientOptions{ +merge = new Merge("YOUR_API_KEY", "YOUR_ACCOUNT_ID", new ClientOptions{ HttpClient = ... // Override the Http Client BaseURL = ... // Override the Base URL }) @@ -68,7 +68,7 @@ a subclass of MergeException will be thrown: using Merge; try { - merge.ATS.Candidates.Retrieve(...); + merge.Ats.Candidates.Retrieve(...); } catch (MergeException e) { System.Console.WriteLine(e.Message) System.Console.WriteLine(e.StatusCode) @@ -83,18 +83,14 @@ Below are code snippets of how you can use the C# SDK. ```c# using Merge; -using Merge.ATS; +using Merge.Ats; -MergeClient merge = new MergeClient( - "YOUR_API_KEY", - "YOUR_ACCOUNT_ID" -) +Merge merge = new Merge("YOUR_API_KEY", "YOUR_ACCOUNT_TOKEN") -merge.ATS.LinkToken.Create(new EndUserDetailsRequest{ +merge.Ats.LinkToken.Create(new EndUserDetailsRequest{ EndUserEmailAddress = "john.smith@gmail.com", EndUserOrganizationName = "acme", EndUserOriginId = "1234", - Categories = }) ``` @@ -102,13 +98,12 @@ merge.ATS.LinkToken.Create(new EndUserDetailsRequest{ ```c# using Merge; -using Merge.HRIS; +using Merge.Hris; -MergeClient merge = new MergeClient( - "YOUR_API_KEY", - "YOUR_ACCOUNT_ID" +MergeClient merge = new Merge( + "YOUR_API_KEY", "YOUR_ACCOUNT_ID" ) -Employee employee = merge.HRIS.Employees.Retrieve("0958cbc6-6040-430a-848e-aafacbadf4ae", +Employee employee = merge.Hris.Employees.RetrieveAsync("0958cbc6-6040-430a-848e-aafacbadf4ae", new EmployeesRetrieveRequest{ IncludeRemoteData = true } @@ -124,9 +119,6 @@ globally or per-request. var merge = new Merge("...", new ClientOptions{ MaxRetries = 1 // Only retry once }); -merge.ATS.Candidates.Retrieve(new CandidatesRetrieveRequest{ ... }, new RequestOptions { - MaxRetries = 0 // Disable retries -}); ``` ## Timeouts @@ -137,9 +129,6 @@ globally or per-request. var merge = new Merge("...", new ClientOptions{ TimeoutInSeconds = 20 // Lower timeout }); -merge.ATS.Candidates.Retrieve(new Merge{ ... }, new RequestOptions { - TimeoutInSeconds = 90 // Raise timeout -}); ``` ## Contributing diff --git a/src/Merge.Client.Test/TestClient.cs b/src/Merge.Client.Test/TestClient.cs index cf6f7940..db3abedc 100644 --- a/src/Merge.Client.Test/TestClient.cs +++ b/src/Merge.Client.Test/TestClient.cs @@ -1,5 +1,3 @@ namespace Merge.Client.Test; -public class TestClient -{ -} +public class TestClient { } diff --git a/src/Merge.Client.sln b/src/Merge.Client.sln index 4d405db2..11f58625 100644 --- a/src/Merge.Client.sln +++ b/src/Merge.Client.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merge.Client", "Merge.Client\Merge.Client.csproj", "{F270F3CE-3B9F-48B1-8313-0AC0582EA987}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merge.Client", "Merge.Client\Merge.Client.csproj", "{19553BD2-51BE-463B-ABEE-237BADF72B8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merge.Client.Test", "Merge.Client.Test\Merge.Client.Test.csproj", "{7098C0CE-E054-4492-8E05-54E0F6DEFFA7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merge.Client.Test", "Merge.Client.Test\Merge.Client.Test.csproj", "{1B8B8673-78F7-4998-B45C-70EC71615B85}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -16,13 +16,13 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F270F3CE-3B9F-48B1-8313-0AC0582EA987}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F270F3CE-3B9F-48B1-8313-0AC0582EA987}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F270F3CE-3B9F-48B1-8313-0AC0582EA987}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F270F3CE-3B9F-48B1-8313-0AC0582EA987}.Release|Any CPU.Build.0 = Release|Any CPU - {7098C0CE-E054-4492-8E05-54E0F6DEFFA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7098C0CE-E054-4492-8E05-54E0F6DEFFA7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7098C0CE-E054-4492-8E05-54E0F6DEFFA7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7098C0CE-E054-4492-8E05-54E0F6DEFFA7}.Release|Any CPU.Build.0 = Release|Any CPU + {19553BD2-51BE-463B-ABEE-237BADF72B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19553BD2-51BE-463B-ABEE-237BADF72B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19553BD2-51BE-463B-ABEE-237BADF72B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19553BD2-51BE-463B-ABEE-237BADF72B8A}.Release|Any CPU.Build.0 = Release|Any CPU + {1B8B8673-78F7-4998-B45C-70EC71615B85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B8B8673-78F7-4998-B45C-70EC71615B85}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B8B8673-78F7-4998-B45C-70EC71615B85}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B8B8673-78F7-4998-B45C-70EC71615B85}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/src/Merge.Client/Accounting/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Accounting/AccountDetails/AccountDetailsClient.cs index 7696cc42..501aa8be 100644 --- a/src/Merge.Client/Accounting/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Accounting/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/account-details" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Accounting/AccountToken/AccountTokenClient.cs index d8dd5964..08c1b483 100644 --- a/src/Merge.Client/Accounting/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Accounting/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/AccountingClient.cs b/src/Merge.Client/Accounting/AccountingClient.cs new file mode 100644 index 00000000..c8d6edb4 --- /dev/null +++ b/src/Merge.Client/Accounting/AccountingClient.cs @@ -0,0 +1,131 @@ +using Merge.Client; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class AccountingClient +{ + private RawClient _client; + + public AccountingClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + AccountingPeriods = new AccountingPeriodsClient(_client); + Accounts = new AccountsClient(_client); + Addresses = new AddressesClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + Attachments = new AttachmentsClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + BalanceSheets = new BalanceSheetsClient(_client); + CashFlowStatements = new CashFlowStatementsClient(_client); + CompanyInfo = new CompanyInfoClient(_client); + Contacts = new ContactsClient(_client); + CreditNotes = new CreditNotesClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + Expenses = new ExpensesClient(_client); + FieldMapping = new FieldMappingClient(_client); + GenerateKey = new GenerateKeyClient(_client); + IncomeStatements = new IncomeStatementsClient(_client); + Invoices = new InvoicesClient(_client); + Issues = new IssuesClient(_client); + Items = new ItemsClient(_client); + JournalEntries = new JournalEntriesClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Passthrough = new PassthroughClient(_client); + Payments = new PaymentsClient(_client); + PhoneNumbers = new PhoneNumbersClient(_client); + PurchaseOrders = new PurchaseOrdersClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + TaxRates = new TaxRatesClient(_client); + TrackingCategories = new TrackingCategoriesClient(_client); + Transactions = new TransactionsClient(_client); + VendorCredits = new VendorCreditsClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public AccountingPeriodsClient AccountingPeriods { get; } + + public AccountsClient Accounts { get; } + + public AddressesClient Addresses { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AttachmentsClient Attachments { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public BalanceSheetsClient BalanceSheets { get; } + + public CashFlowStatementsClient CashFlowStatements { get; } + + public CompanyInfoClient CompanyInfo { get; } + + public ContactsClient Contacts { get; } + + public CreditNotesClient CreditNotes { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public ExpensesClient Expenses { get; } + + public FieldMappingClient FieldMapping { get; } + + public GenerateKeyClient GenerateKey { get; } + + public IncomeStatementsClient IncomeStatements { get; } + + public InvoicesClient Invoices { get; } + + public IssuesClient Issues { get; } + + public ItemsClient Items { get; } + + public JournalEntriesClient JournalEntries { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public PassthroughClient Passthrough { get; } + + public PaymentsClient Payments { get; } + + public PhoneNumbersClient PhoneNumbers { get; } + + public PurchaseOrdersClient PurchaseOrders { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public TaxRatesClient TaxRates { get; } + + public TrackingCategoriesClient TrackingCategories { get; } + + public TransactionsClient Transactions { get; } + + public VendorCreditsClient VendorCredits { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Accounting/AccountingPeriods/AccountingPeriodsClient.cs b/src/Merge.Client/Accounting/AccountingPeriods/AccountingPeriodsClient.cs index 07e334f1..2f4e6091 100644 --- a/src/Merge.Client/Accounting/AccountingPeriods/AccountingPeriodsClient.cs +++ b/src/Merge.Client/Accounting/AccountingPeriods/AccountingPeriodsClient.cs @@ -1,9 +1,82 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AccountingPeriodsClient { - public async void List(){ + private RawClient _client; + + public AccountingPeriodsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `AccountingPeriod` objects. + /// + public async Task ListAsync(AccountingPeriodsListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/accounting-periods", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `AccountingPeriod` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + AccountingPeriodsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/accounting-periods/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsListRequest.cs b/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsListRequest.cs new file mode 100644 index 00000000..3b4f5920 --- /dev/null +++ b/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsListRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Accounting; + +public class AccountingPeriodsListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsRetrieveRequest.cs b/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsRetrieveRequest.cs new file mode 100644 index 00000000..d7fa2717 --- /dev/null +++ b/src/Merge.Client/Accounting/AccountingPeriods/requests/AccountingPeriodsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Accounting; + +public class AccountingPeriodsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/Accounts/AccountsClient.cs b/src/Merge.Client/Accounting/Accounts/AccountsClient.cs index 57ab8dcc..430ec428 100644 --- a/src/Merge.Client/Accounting/Accounts/AccountsClient.cs +++ b/src/Merge.Client/Accounting/Accounts/AccountsClient.cs @@ -1,13 +1,177 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AccountsClient { - public async void List(){ + private RawClient _client; + + public AccountsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Account` objects. + /// + public async Task ListAsync(AccountsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates an `Account` object with the given values. + /// + public async Task CreateAsync(AccountEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns an `Account` object with the given `id`. + /// + public async Task RetrieveAsync(string id, AccountsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/accounts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Account` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/accounts/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Accounts/requests/AccountEndpointRequest.cs b/src/Merge.Client/Accounting/Accounts/requests/AccountEndpointRequest.cs new file mode 100644 index 00000000..82d5f979 --- /dev/null +++ b/src/Merge.Client/Accounting/Accounts/requests/AccountEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class AccountEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AccountRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Accounts/requests/AccountsListRequest.cs b/src/Merge.Client/Accounting/Accounts/requests/AccountsListRequest.cs new file mode 100644 index 00000000..640a5ccb --- /dev/null +++ b/src/Merge.Client/Accounting/Accounts/requests/AccountsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class AccountsListRequest +{ + /// + /// If provided, will only return accounts for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public AccountsListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public AccountsListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Accounts/requests/AccountsRetrieveRequest.cs b/src/Merge.Client/Accounting/Accounts/requests/AccountsRetrieveRequest.cs new file mode 100644 index 00000000..8a824f69 --- /dev/null +++ b/src/Merge.Client/Accounting/Accounts/requests/AccountsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class AccountsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public AccountsRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public AccountsRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Addresses/AddressesClient.cs b/src/Merge.Client/Accounting/Addresses/AddressesClient.cs index 168add06..bb6eaa6d 100644 --- a/src/Merge.Client/Accounting/Addresses/AddressesClient.cs +++ b/src/Merge.Client/Accounting/Addresses/AddressesClient.cs @@ -1,7 +1,49 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AddressesClient { - public async void Retrieve(){ + private RawClient _client; + + public AddressesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns an `Address` object with the given `id`. + /// + public async Task
RetrieveAsync(string id, AddressesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/addresses/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize
(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Addresses/requests/AddressesRetrieveRequest.cs b/src/Merge.Client/Accounting/Addresses/requests/AddressesRetrieveRequest.cs new file mode 100644 index 00000000..aa658aa7 --- /dev/null +++ b/src/Merge.Client/Accounting/Addresses/requests/AddressesRetrieveRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Accounting; + +public class AddressesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Accounting/AsyncPassthrough/AsyncPassthroughClient.cs index d9bee9cb..99365a3d 100644 --- a/src/Merge.Client/Accounting/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Accounting/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Attachments/AttachmentsClient.cs b/src/Merge.Client/Accounting/Attachments/AttachmentsClient.cs index f855ba17..780e1590 100644 --- a/src/Merge.Client/Accounting/Attachments/AttachmentsClient.cs +++ b/src/Merge.Client/Accounting/Attachments/AttachmentsClient.cs @@ -1,13 +1,158 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AttachmentsClient { - public async void List(){ + private RawClient _client; + + public AttachmentsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `AccountingAttachment` objects. + /// + public async Task ListAsync(AttachmentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates an `AccountingAttachment` object with the given values. + /// + public async Task CreateAsync( + AccountingAttachmentEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns an `AccountingAttachment` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + AttachmentsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/attachments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `AccountingAttachment` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/attachments/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Attachments/requests/AccountingAttachmentEndpointRequest.cs b/src/Merge.Client/Accounting/Attachments/requests/AccountingAttachmentEndpointRequest.cs new file mode 100644 index 00000000..944f4f65 --- /dev/null +++ b/src/Merge.Client/Accounting/Attachments/requests/AccountingAttachmentEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class AccountingAttachmentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AccountingAttachmentRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Attachments/requests/AttachmentsListRequest.cs b/src/Merge.Client/Accounting/Attachments/requests/AttachmentsListRequest.cs new file mode 100644 index 00000000..4b558a6c --- /dev/null +++ b/src/Merge.Client/Accounting/Attachments/requests/AttachmentsListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Accounting; + +public class AttachmentsListRequest +{ + /// + /// If provided, will only return accounting attachments for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/Attachments/requests/AttachmentsRetrieveRequest.cs b/src/Merge.Client/Accounting/Attachments/requests/AttachmentsRetrieveRequest.cs new file mode 100644 index 00000000..a5a4700a --- /dev/null +++ b/src/Merge.Client/Accounting/Attachments/requests/AttachmentsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Accounting; + +public class AttachmentsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Accounting/AuditTrail/AuditTrailClient.cs index cf4cce27..b528797a 100644 --- a/src/Merge.Client/Accounting/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Accounting/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Accounting/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..38b939ad --- /dev/null +++ b/src/Merge.Client/Accounting/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Accounting; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Accounting/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Accounting/AvailableActions/AvailableActionsClient.cs index 8e27017c..df90e5e4 100644 --- a/src/Merge.Client/Accounting/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Accounting/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/available-actions" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/BalanceSheets/BalanceSheetsClient.cs b/src/Merge.Client/Accounting/BalanceSheets/BalanceSheetsClient.cs index 6d5e4cb1..0a1f25ae 100644 --- a/src/Merge.Client/Accounting/BalanceSheets/BalanceSheetsClient.cs +++ b/src/Merge.Client/Accounting/BalanceSheets/BalanceSheetsClient.cs @@ -1,9 +1,111 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class BalanceSheetsClient { - public async void List(){ + private RawClient _client; + + public BalanceSheetsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `BalanceSheet` objects. + /// + public async Task ListAsync(BalanceSheetsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/balance-sheets", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `BalanceSheet` object with the given `id`. + /// + public async Task RetrieveAsync(string id, BalanceSheetsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/balance-sheets/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsListRequest.cs b/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsListRequest.cs new file mode 100644 index 00000000..8e4ca474 --- /dev/null +++ b/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Accounting; + +public class BalanceSheetsListRequest +{ + /// + /// If provided, will only return balance sheets for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsRetrieveRequest.cs b/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsRetrieveRequest.cs new file mode 100644 index 00000000..9d7aa257 --- /dev/null +++ b/src/Merge.Client/Accounting/BalanceSheets/requests/BalanceSheetsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class BalanceSheetsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/CashFlowStatements/CashFlowStatementsClient.cs b/src/Merge.Client/Accounting/CashFlowStatements/CashFlowStatementsClient.cs index e4f21edc..ed32ae96 100644 --- a/src/Merge.Client/Accounting/CashFlowStatements/CashFlowStatementsClient.cs +++ b/src/Merge.Client/Accounting/CashFlowStatements/CashFlowStatementsClient.cs @@ -1,9 +1,116 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class CashFlowStatementsClient { - public async void List(){ + private RawClient _client; + + public CashFlowStatementsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `CashFlowStatement` objects. + /// + public async Task ListAsync( + CashFlowStatementsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/cash-flow-statements", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `CashFlowStatement` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + CashFlowStatementsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/cash-flow-statements/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsListRequest.cs b/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsListRequest.cs new file mode 100644 index 00000000..c9115777 --- /dev/null +++ b/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Accounting; + +public class CashFlowStatementsListRequest +{ + /// + /// If provided, will only return cash flow statements for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsRetrieveRequest.cs b/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsRetrieveRequest.cs new file mode 100644 index 00000000..4ee951a7 --- /dev/null +++ b/src/Merge.Client/Accounting/CashFlowStatements/requests/CashFlowStatementsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class CashFlowStatementsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/CompanyInfo/CompanyInfoClient.cs b/src/Merge.Client/Accounting/CompanyInfo/CompanyInfoClient.cs index e0e4f338..ca14d55c 100644 --- a/src/Merge.Client/Accounting/CompanyInfo/CompanyInfoClient.cs +++ b/src/Merge.Client/Accounting/CompanyInfo/CompanyInfoClient.cs @@ -1,9 +1,107 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class CompanyInfoClient { - public async void List(){ + private RawClient _client; + + public CompanyInfoClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `CompanyInfo` objects. + /// + public async Task ListAsync(CompanyInfoListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/company-info", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `CompanyInfo` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CompanyInfoRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/company-info/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoListRequest.cs b/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoListRequest.cs new file mode 100644 index 00000000..cc37bb4a --- /dev/null +++ b/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoListRequest.cs @@ -0,0 +1,56 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class CompanyInfoListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CompanyInfoListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoRetrieveRequest.cs b/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoRetrieveRequest.cs new file mode 100644 index 00000000..ff12566f --- /dev/null +++ b/src/Merge.Client/Accounting/CompanyInfo/requests/CompanyInfoRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class CompanyInfoRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CompanyInfoRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/Contacts/ContactsClient.cs b/src/Merge.Client/Accounting/Contacts/ContactsClient.cs index f2e5c618..a8ace8aa 100644 --- a/src/Merge.Client/Accounting/Contacts/ContactsClient.cs +++ b/src/Merge.Client/Accounting/Contacts/ContactsClient.cs @@ -1,13 +1,185 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class ContactsClient { - public async void List(){ + private RawClient _client; + + public ContactsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Contact` objects. + /// + public async Task ListAsync(ContactsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IsCustomer != null) + { + _query["is_customer"] = request.IsCustomer; + } + if (request.IsSupplier != null) + { + _query["is_supplier"] = request.IsSupplier; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/contacts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `Contact` object with the given values. + /// + public async Task CreateAsync(ContactEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/contacts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `Contact` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ContactsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/contacts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Contact` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/contacts/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Contacts/requests/ContactEndpointRequest.cs b/src/Merge.Client/Accounting/Contacts/requests/ContactEndpointRequest.cs new file mode 100644 index 00000000..c8d7c895 --- /dev/null +++ b/src/Merge.Client/Accounting/Contacts/requests/ContactEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ContactEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ContactRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Contacts/requests/ContactsListRequest.cs b/src/Merge.Client/Accounting/Contacts/requests/ContactsListRequest.cs new file mode 100644 index 00000000..ca57067f --- /dev/null +++ b/src/Merge.Client/Accounting/Contacts/requests/ContactsListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ContactsListRequest +{ + /// + /// If provided, will only return contacts for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ContactsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return Contacts that are denoted as customers. + /// + public string? IsCustomer { get; init; } + + /// + /// If provided, will only return Contacts that are denoted as suppliers. + /// + public string? IsSupplier { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Contacts/requests/ContactsRetrieveRequest.cs b/src/Merge.Client/Accounting/Contacts/requests/ContactsRetrieveRequest.cs new file mode 100644 index 00000000..f14a90a6 --- /dev/null +++ b/src/Merge.Client/Accounting/Contacts/requests/ContactsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ContactsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ContactsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/CreditNotes/CreditNotesClient.cs b/src/Merge.Client/Accounting/CreditNotes/CreditNotesClient.cs index 98eab5dc..6d88eda9 100644 --- a/src/Merge.Client/Accounting/CreditNotes/CreditNotesClient.cs +++ b/src/Merge.Client/Accounting/CreditNotes/CreditNotesClient.cs @@ -1,9 +1,135 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class CreditNotesClient { - public async void List(){ + private RawClient _client; + + public CreditNotesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `CreditNote` objects. + /// + public async Task ListAsync(CreditNotesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/credit-notes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `CreditNote` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CreditNotesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/credit-notes/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesListRequestExpand.cs b/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesListRequestExpand.cs index 5e95626e..fe5e26e1 100644 --- a/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesListRequestExpand.cs +++ b/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesListRequestExpand.cs @@ -64,19 +64,25 @@ public enum CreditNotesListRequestExpand [EnumMember(Value = "applied_payments,line_items,tracking_categories,company")] AppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact")] AppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company")] AppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories")] @@ -226,25 +232,33 @@ public enum CreditNotesListRequestExpand [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories")] PaymentsAppliedPaymentsLineItemsTrackingCategories, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories")] @@ -268,7 +282,9 @@ public enum CreditNotesListRequestExpand [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company")] PaymentsAppliedPaymentsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,company")] @@ -334,7 +350,9 @@ public enum CreditNotesListRequestExpand [EnumMember(Value = "payments,line_items,tracking_categories,contact,company")] PaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,tracking_categories")] diff --git a/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesRetrieveRequestExpand.cs b/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesRetrieveRequestExpand.cs index 0e111a83..ad73f8d0 100644 --- a/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesRetrieveRequestExpand.cs +++ b/src/Merge.Client/Accounting/CreditNotes/Types/CreditNotesRetrieveRequestExpand.cs @@ -64,19 +64,25 @@ public enum CreditNotesRetrieveRequestExpand [EnumMember(Value = "applied_payments,line_items,tracking_categories,company")] AppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact")] AppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company")] AppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories")] @@ -226,25 +232,33 @@ public enum CreditNotesRetrieveRequestExpand [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories")] PaymentsAppliedPaymentsLineItemsTrackingCategories, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories")] @@ -268,7 +282,9 @@ public enum CreditNotesRetrieveRequestExpand [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company")] PaymentsAppliedPaymentsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,company")] @@ -334,7 +350,9 @@ public enum CreditNotesRetrieveRequestExpand [EnumMember(Value = "payments,line_items,tracking_categories,contact,company")] PaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,tracking_categories")] diff --git a/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesListRequest.cs b/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesListRequest.cs new file mode 100644 index 00000000..ce88c2ca --- /dev/null +++ b/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class CreditNotesListRequest +{ + /// + /// If provided, will only return credit notes for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CreditNotesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public CreditNotesListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public CreditNotesListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesRetrieveRequest.cs b/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesRetrieveRequest.cs new file mode 100644 index 00000000..5b7f6236 --- /dev/null +++ b/src/Merge.Client/Accounting/CreditNotes/requests/CreditNotesRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class CreditNotesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CreditNotesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public CreditNotesRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public CreditNotesRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Accounting/DeleteAccount/DeleteAccountClient.cs index b3ff6614..cc7391e2 100644 --- a/src/Merge.Client/Accounting/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Accounting/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,27 @@ +using Merge.Client; + namespace Merge.Client.Accounting; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/delete-account" + } + ); } } diff --git a/src/Merge.Client/Accounting/Expenses/ExpensesClient.cs b/src/Merge.Client/Accounting/Expenses/ExpensesClient.cs index a08b5dcd..341fad8a 100644 --- a/src/Merge.Client/Accounting/Expenses/ExpensesClient.cs +++ b/src/Merge.Client/Accounting/Expenses/ExpensesClient.cs @@ -1,13 +1,169 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class ExpensesClient { - public async void List(){ + private RawClient _client; + + public ExpensesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Expense` objects. + /// + public async Task ListAsync(ExpensesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/expenses", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates an `Expense` object with the given values. + /// + public async Task CreateAsync(ExpenseEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/expenses", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns an `Expense` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ExpensesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/expenses/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Expense` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/expenses/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Expenses/requests/ExpenseEndpointRequest.cs b/src/Merge.Client/Accounting/Expenses/requests/ExpenseEndpointRequest.cs new file mode 100644 index 00000000..494f866b --- /dev/null +++ b/src/Merge.Client/Accounting/Expenses/requests/ExpenseEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ExpenseEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ExpenseRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Expenses/requests/ExpensesListRequest.cs b/src/Merge.Client/Accounting/Expenses/requests/ExpensesListRequest.cs new file mode 100644 index 00000000..b28ccb0b --- /dev/null +++ b/src/Merge.Client/Accounting/Expenses/requests/ExpensesListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ExpensesListRequest +{ + /// + /// If provided, will only return expenses for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ExpensesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/Expenses/requests/ExpensesRetrieveRequest.cs b/src/Merge.Client/Accounting/Expenses/requests/ExpensesRetrieveRequest.cs new file mode 100644 index 00000000..834fa35a --- /dev/null +++ b/src/Merge.Client/Accounting/Expenses/requests/ExpensesRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ExpensesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ExpensesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Accounting/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..6f0e2b81 --- /dev/null +++ b/src/Merge.Client/Accounting/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,154 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/field-mappings" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/accounting/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/accounting/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/target-fields" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Accounting/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Accounting/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..77cc57eb --- /dev/null +++ b/src/Merge.Client/Accounting/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Accounting; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Accounting/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Accounting/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..2862d5e3 --- /dev/null +++ b/src/Merge.Client/Accounting/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Accounting; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Accounting/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Accounting/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..172102b2 --- /dev/null +++ b/src/Merge.Client/Accounting/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Accounting/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Accounting/ForceResync/ForceResyncClient.cs index b8d36bfb..18a1eb04 100644 --- a/src/Merge.Client/Accounting/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Accounting/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Accounting/GenerateKey/GenerateKeyClient.cs index 5b111b8e..661269d9 100644 --- a/src/Merge.Client/Accounting/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Accounting/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Accounting/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..e46e4940 --- /dev/null +++ b/src/Merge.Client/Accounting/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Accounting; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Accounting/IncomeStatements/IncomeStatementsClient.cs b/src/Merge.Client/Accounting/IncomeStatements/IncomeStatementsClient.cs index 3fb81e8b..37d45ef0 100644 --- a/src/Merge.Client/Accounting/IncomeStatements/IncomeStatementsClient.cs +++ b/src/Merge.Client/Accounting/IncomeStatements/IncomeStatementsClient.cs @@ -1,9 +1,114 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class IncomeStatementsClient { - public async void List(){ + private RawClient _client; + + public IncomeStatementsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `IncomeStatement` objects. + /// + public async Task ListAsync(IncomeStatementsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/income-statements", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `IncomeStatement` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + IncomeStatementsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/income-statements/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsListRequest.cs b/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsListRequest.cs new file mode 100644 index 00000000..a02927c2 --- /dev/null +++ b/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Accounting; + +public class IncomeStatementsListRequest +{ + /// + /// If provided, will only return income statements for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsRetrieveRequest.cs b/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsRetrieveRequest.cs new file mode 100644 index 00000000..33df0b69 --- /dev/null +++ b/src/Merge.Client/Accounting/IncomeStatements/requests/IncomeStatementsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class IncomeStatementsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/Invoices/InvoicesClient.cs b/src/Merge.Client/Accounting/Invoices/InvoicesClient.cs index 54fc4928..16adaccd 100644 --- a/src/Merge.Client/Accounting/Invoices/InvoicesClient.cs +++ b/src/Merge.Client/Accounting/Invoices/InvoicesClient.cs @@ -1,13 +1,246 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class InvoicesClient { - public async void List(){ + private RawClient _client; + + public InvoicesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Invoice` objects. + /// + public async Task ListAsync(InvoicesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.ContactId != null) + { + _query["contact_id"] = request.ContactId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IssueDateAfter != null) + { + _query["issue_date_after"] = request.IssueDateAfter; + } + if (request.IssueDateBefore != null) + { + _query["issue_date_before"] = request.IssueDateBefore; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.Type != null) + { + _query["type"] = request.Type; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/invoices", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates an `Invoice` object with the given values. + /// + public async Task CreateAsync(InvoiceEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/invoices", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Invoice` object with the given `id`. + /// + public async Task RetrieveAsync(string id, InvoicesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/invoices/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Updates an `Invoice` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedInvoiceEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/accounting/v1/invoices/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Invoice` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/invoices/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Invoice` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/invoices/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Invoices/Types/InvoicesListRequestExpand.cs b/src/Merge.Client/Accounting/Invoices/Types/InvoicesListRequestExpand.cs index 9a1106f7..03aac3d5 100644 --- a/src/Merge.Client/Accounting/Invoices/Types/InvoicesListRequestExpand.cs +++ b/src/Merge.Client/Accounting/Invoices/Types/InvoicesListRequestExpand.cs @@ -76,7 +76,9 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "applied_payments,line_items,purchase_orders,contact,company")] AppliedPaymentsLineItemsPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,line_items,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsLineItemsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories")] @@ -88,43 +90,59 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "applied_payments,line_items,tracking_categories,company")] AppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact")] AppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company")] AppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,company")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,purchase_orders")] @@ -184,19 +202,25 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,company")] AppliedPaymentsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,company,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact")] AppliedPaymentsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,contact,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,company")] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "company")] @@ -310,7 +334,9 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "line_items,tracking_categories,purchase_orders,contact,company")] LineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] LineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments")] @@ -376,67 +402,95 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,company")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,company")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories")] PaymentsAppliedPaymentsLineItemsTrackingCategories, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,purchase_orders")] @@ -460,7 +514,9 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "payments,applied_payments,purchase_orders,contact,company")] PaymentsAppliedPaymentsPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories")] @@ -484,31 +540,43 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company")] PaymentsAppliedPaymentsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,company")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,company")] @@ -598,31 +666,41 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "payments,line_items,tracking_categories,contact,company")] PaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders")] PaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,company")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,company")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,purchase_orders")] @@ -694,7 +772,9 @@ public enum InvoicesListRequestExpand [EnumMember(Value = "payments,tracking_categories,purchase_orders,contact,company")] PaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "purchase_orders")] diff --git a/src/Merge.Client/Accounting/Invoices/Types/InvoicesRetrieveRequestExpand.cs b/src/Merge.Client/Accounting/Invoices/Types/InvoicesRetrieveRequestExpand.cs index 7360a967..c49e62f0 100644 --- a/src/Merge.Client/Accounting/Invoices/Types/InvoicesRetrieveRequestExpand.cs +++ b/src/Merge.Client/Accounting/Invoices/Types/InvoicesRetrieveRequestExpand.cs @@ -76,7 +76,9 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "applied_payments,line_items,purchase_orders,contact,company")] AppliedPaymentsLineItemsPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,line_items,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsLineItemsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories")] @@ -88,43 +90,59 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "applied_payments,line_items,tracking_categories,company")] AppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact")] AppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company")] AppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,company")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact")] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,purchase_orders")] @@ -184,19 +202,25 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,company")] AppliedPaymentsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,company,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact")] AppliedPaymentsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,contact,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,company")] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] AppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "company")] @@ -310,7 +334,9 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "line_items,tracking_categories,purchase_orders,contact,company")] LineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] LineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments")] @@ -376,67 +402,95 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,company")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,company")] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories")] PaymentsAppliedPaymentsLineItemsTrackingCategories, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders")] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,purchase_orders")] @@ -460,7 +514,9 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "payments,applied_payments,purchase_orders,contact,company")] PaymentsAppliedPaymentsPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories")] @@ -484,31 +540,43 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company")] PaymentsAppliedPaymentsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,company")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact")] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,applied_payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsAppliedPaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,company")] @@ -598,31 +666,41 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "payments,line_items,tracking_categories,contact,company")] PaymentsLineItemsTrackingCategoriesContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesContactCompanyAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders")] PaymentsLineItemsTrackingCategoriesPurchaseOrders, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,company")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersCompanyAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContact, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,contact,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactAccountingPeriod, [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,company")] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,line_items,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsLineItemsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "payments,purchase_orders")] @@ -694,7 +772,9 @@ public enum InvoicesRetrieveRequestExpand [EnumMember(Value = "payments,tracking_categories,purchase_orders,contact,company")] PaymentsTrackingCategoriesPurchaseOrdersContactCompany, - [EnumMember(Value = "payments,tracking_categories,purchase_orders,contact,company,accounting_period")] + [EnumMember( + Value = "payments,tracking_categories,purchase_orders,contact,company,accounting_period" + )] PaymentsTrackingCategoriesPurchaseOrdersContactCompanyAccountingPeriod, [EnumMember(Value = "purchase_orders")] diff --git a/src/Merge.Client/Accounting/Invoices/requests/InvoiceEndpointRequest.cs b/src/Merge.Client/Accounting/Invoices/requests/InvoiceEndpointRequest.cs new file mode 100644 index 00000000..a444b36c --- /dev/null +++ b/src/Merge.Client/Accounting/Invoices/requests/InvoiceEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class InvoiceEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public InvoiceRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Invoices/requests/InvoicesListRequest.cs b/src/Merge.Client/Accounting/Invoices/requests/InvoicesListRequest.cs new file mode 100644 index 00000000..1df91e5f --- /dev/null +++ b/src/Merge.Client/Accounting/Invoices/requests/InvoicesListRequest.cs @@ -0,0 +1,94 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class InvoicesListRequest +{ + /// + /// If provided, will only return invoices for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return invoices for this contact. + /// + public string? ContactId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public InvoicesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? IssueDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? IssueDateBefore { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return Invoices with this type + /// + /// - `ACCOUNTS_RECEIVABLE` - ACCOUNTS_RECEIVABLE + /// - `ACCOUNTS_PAYABLE` - ACCOUNTS_PAYABLE + /// + public InvoicesListRequestType? Type { get; init; } +} diff --git a/src/Merge.Client/Accounting/Invoices/requests/InvoicesRetrieveRequest.cs b/src/Merge.Client/Accounting/Invoices/requests/InvoicesRetrieveRequest.cs new file mode 100644 index 00000000..dd425a1a --- /dev/null +++ b/src/Merge.Client/Accounting/Invoices/requests/InvoicesRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class InvoicesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public InvoicesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Invoices/requests/PatchedInvoiceEndpointRequest.cs b/src/Merge.Client/Accounting/Invoices/requests/PatchedInvoiceEndpointRequest.cs new file mode 100644 index 00000000..c6400d08 --- /dev/null +++ b/src/Merge.Client/Accounting/Invoices/requests/PatchedInvoiceEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PatchedInvoiceEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public InvoiceRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Issues/IssuesClient.cs b/src/Merge.Client/Accounting/Issues/IssuesClient.cs index fc0a76bb..e3dfdcca 100644 --- a/src/Merge.Client/Accounting/Issues/IssuesClient.cs +++ b/src/Merge.Client/Accounting/Issues/IssuesClient.cs @@ -1,9 +1,109 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/issues/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Accounting/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..196e834e --- /dev/null +++ b/src/Merge.Client/Accounting/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Accounting/Items/ItemsClient.cs b/src/Merge.Client/Accounting/Items/ItemsClient.cs index 43e3e4ff..51907e65 100644 --- a/src/Merge.Client/Accounting/Items/ItemsClient.cs +++ b/src/Merge.Client/Accounting/Items/ItemsClient.cs @@ -1,9 +1,127 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class ItemsClient { - public async void List(){ + private RawClient _client; + + public ItemsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Item` objects. + /// + public async Task ListAsync(ItemsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/items", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `Item` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ItemsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/items/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Items/requests/ItemsListRequest.cs b/src/Merge.Client/Accounting/Items/requests/ItemsListRequest.cs new file mode 100644 index 00000000..bf7200d0 --- /dev/null +++ b/src/Merge.Client/Accounting/Items/requests/ItemsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ItemsListRequest +{ + /// + /// If provided, will only return items for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ItemsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Items/requests/ItemsRetrieveRequest.cs b/src/Merge.Client/Accounting/Items/requests/ItemsRetrieveRequest.cs new file mode 100644 index 00000000..8e7b21f6 --- /dev/null +++ b/src/Merge.Client/Accounting/Items/requests/ItemsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ItemsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ItemsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/JournalEntries/JournalEntriesClient.cs b/src/Merge.Client/Accounting/JournalEntries/JournalEntriesClient.cs index 84ba5ba0..29bcb8f0 100644 --- a/src/Merge.Client/Accounting/JournalEntries/JournalEntriesClient.cs +++ b/src/Merge.Client/Accounting/JournalEntries/JournalEntriesClient.cs @@ -1,13 +1,169 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class JournalEntriesClient { - public async void List(){ + private RawClient _client; + + public JournalEntriesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `JournalEntry` objects. + /// + public async Task ListAsync(JournalEntriesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/journal-entries", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `JournalEntry` object with the given values. + /// + public async Task CreateAsync(JournalEntryEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/journal-entries", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `JournalEntry` object with the given `id`. + /// + public async Task RetrieveAsync(string id, JournalEntriesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/journal-entries/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `JournalEntry` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/journal-entries/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesListRequestExpand.cs b/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesListRequestExpand.cs index 4bb42a6c..a0d036c5 100644 --- a/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesListRequestExpand.cs +++ b/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesListRequestExpand.cs @@ -100,7 +100,9 @@ public enum JournalEntriesListRequestExpand [EnumMember(Value = "lines,payments,applied_payments,tracking_categories,company")] LinesPaymentsAppliedPaymentsTrackingCategoriesCompany, - [EnumMember(Value = "lines,payments,applied_payments,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "lines,payments,applied_payments,tracking_categories,company,accounting_period" + )] LinesPaymentsAppliedPaymentsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "lines,payments,company")] diff --git a/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesRetrieveRequestExpand.cs b/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesRetrieveRequestExpand.cs index 02cea576..ac0c1718 100644 --- a/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesRetrieveRequestExpand.cs +++ b/src/Merge.Client/Accounting/JournalEntries/Types/JournalEntriesRetrieveRequestExpand.cs @@ -100,7 +100,9 @@ public enum JournalEntriesRetrieveRequestExpand [EnumMember(Value = "lines,payments,applied_payments,tracking_categories,company")] LinesPaymentsAppliedPaymentsTrackingCategoriesCompany, - [EnumMember(Value = "lines,payments,applied_payments,tracking_categories,company,accounting_period")] + [EnumMember( + Value = "lines,payments,applied_payments,tracking_categories,company,accounting_period" + )] LinesPaymentsAppliedPaymentsTrackingCategoriesCompanyAccountingPeriod, [EnumMember(Value = "lines,payments,company")] diff --git a/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesListRequest.cs b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesListRequest.cs new file mode 100644 index 00000000..ce06061f --- /dev/null +++ b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class JournalEntriesListRequest +{ + /// + /// If provided, will only return journal entries for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public JournalEntriesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesRetrieveRequest.cs b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesRetrieveRequest.cs new file mode 100644 index 00000000..56419bb3 --- /dev/null +++ b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntriesRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class JournalEntriesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public JournalEntriesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntryEndpointRequest.cs b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntryEndpointRequest.cs new file mode 100644 index 00000000..9e5b9da4 --- /dev/null +++ b/src/Merge.Client/Accounting/JournalEntries/requests/JournalEntryEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class JournalEntryEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public JournalEntryRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Accounting/LinkToken/LinkTokenClient.cs index a8045614..5a5ea18a 100644 --- a/src/Merge.Client/Accounting/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Accounting/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Accounting/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..557d836d --- /dev/null +++ b/src/Merge.Client/Accounting/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Accounting/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Accounting/LinkedAccounts/LinkedAccountsClient.cs index bd51200b..90d32c83 100644 --- a/src/Merge.Client/Accounting/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Accounting/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Accounting/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..c79d5e35 --- /dev/null +++ b/src/Merge.Client/Accounting/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class LinkedAccountsListRequest +{ + /// + /// Options: `accounting`, `ats`, `crm`, `filestorage`, `hris`, `mktg`, `ticketing` + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Accounting/Passthrough/PassthroughClient.cs b/src/Merge.Client/Accounting/Passthrough/PassthroughClient.cs index 0fe99a09..f7deab74 100644 --- a/src/Merge.Client/Accounting/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Accounting/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Payments/PaymentsClient.cs b/src/Merge.Client/Accounting/Payments/PaymentsClient.cs index 723526cf..0f2cf585 100644 --- a/src/Merge.Client/Accounting/Payments/PaymentsClient.cs +++ b/src/Merge.Client/Accounting/Payments/PaymentsClient.cs @@ -1,13 +1,230 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class PaymentsClient { - public async void List(){ + private RawClient _client; + + public PaymentsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Payment` objects. + /// + public async Task ListAsync(PaymentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountId != null) + { + _query["account_id"] = request.AccountId; + } + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.ContactId != null) + { + _query["contact_id"] = request.ContactId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/payments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates a `Payment` object with the given values. + /// + public async Task CreateAsync(PaymentEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/payments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Payment` object with the given `id`. + /// + public async Task RetrieveAsync(string id, PaymentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/payments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Updates a `Payment` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedPaymentEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/accounting/v1/payments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Payment` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/payments/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Payment` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/payments/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Payments/Types/PaymentsListRequestExpand.cs b/src/Merge.Client/Accounting/Payments/Types/PaymentsListRequestExpand.cs index 2feae53a..5e58444a 100644 --- a/src/Merge.Client/Accounting/Payments/Types/PaymentsListRequestExpand.cs +++ b/src/Merge.Client/Accounting/Payments/Types/PaymentsListRequestExpand.cs @@ -151,7 +151,9 @@ public enum PaymentsListRequestExpand [EnumMember(Value = "tracking_categories,applied_to_lines,contact,account,company")] TrackingCategoriesAppliedToLinesContactAccountCompany, - [EnumMember(Value = "tracking_categories,applied_to_lines,contact,account,company,accounting_period")] + [EnumMember( + Value = "tracking_categories,applied_to_lines,contact,account,company,accounting_period" + )] TrackingCategoriesAppliedToLinesContactAccountCompanyAccountingPeriod, [EnumMember(Value = "tracking_categories,applied_to_lines,contact,accounting_period")] diff --git a/src/Merge.Client/Accounting/Payments/Types/PaymentsRetrieveRequestExpand.cs b/src/Merge.Client/Accounting/Payments/Types/PaymentsRetrieveRequestExpand.cs index e76e8440..e54db45b 100644 --- a/src/Merge.Client/Accounting/Payments/Types/PaymentsRetrieveRequestExpand.cs +++ b/src/Merge.Client/Accounting/Payments/Types/PaymentsRetrieveRequestExpand.cs @@ -151,7 +151,9 @@ public enum PaymentsRetrieveRequestExpand [EnumMember(Value = "tracking_categories,applied_to_lines,contact,account,company")] TrackingCategoriesAppliedToLinesContactAccountCompany, - [EnumMember(Value = "tracking_categories,applied_to_lines,contact,account,company,accounting_period")] + [EnumMember( + Value = "tracking_categories,applied_to_lines,contact,account,company,accounting_period" + )] TrackingCategoriesAppliedToLinesContactAccountCompanyAccountingPeriod, [EnumMember(Value = "tracking_categories,applied_to_lines,contact,accounting_period")] diff --git a/src/Merge.Client/Accounting/Payments/requests/PatchedPaymentEndpointRequest.cs b/src/Merge.Client/Accounting/Payments/requests/PatchedPaymentEndpointRequest.cs new file mode 100644 index 00000000..61a3b611 --- /dev/null +++ b/src/Merge.Client/Accounting/Payments/requests/PatchedPaymentEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PatchedPaymentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedPaymentRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Payments/requests/PaymentEndpointRequest.cs b/src/Merge.Client/Accounting/Payments/requests/PaymentEndpointRequest.cs new file mode 100644 index 00000000..b7ea7da8 --- /dev/null +++ b/src/Merge.Client/Accounting/Payments/requests/PaymentEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PaymentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PaymentRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/Payments/requests/PaymentsListRequest.cs b/src/Merge.Client/Accounting/Payments/requests/PaymentsListRequest.cs new file mode 100644 index 00000000..6dcb791e --- /dev/null +++ b/src/Merge.Client/Accounting/Payments/requests/PaymentsListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PaymentsListRequest +{ + /// + /// If provided, will only return payments for this account. + /// + public string? AccountId { get; init; } + + /// + /// If provided, will only return payments for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return payments for this contact. + /// + public string? ContactId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public PaymentsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/Payments/requests/PaymentsRetrieveRequest.cs b/src/Merge.Client/Accounting/Payments/requests/PaymentsRetrieveRequest.cs new file mode 100644 index 00000000..71f6659c --- /dev/null +++ b/src/Merge.Client/Accounting/Payments/requests/PaymentsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PaymentsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public PaymentsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/PhoneNumbers/PhoneNumbersClient.cs b/src/Merge.Client/Accounting/PhoneNumbers/PhoneNumbersClient.cs index caa26b7a..cc6c5847 100644 --- a/src/Merge.Client/Accounting/PhoneNumbers/PhoneNumbersClient.cs +++ b/src/Merge.Client/Accounting/PhoneNumbers/PhoneNumbersClient.cs @@ -1,7 +1,44 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class PhoneNumbersClient { - public async void Retrieve(){ + private RawClient _client; + + public PhoneNumbersClient(RawClient client) + { + _client = client; + } + + /// + /// Returns an `AccountingPhoneNumber` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + PhoneNumbersRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/phone-numbers/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/PhoneNumbers/requests/PhoneNumbersRetrieveRequest.cs b/src/Merge.Client/Accounting/PhoneNumbers/requests/PhoneNumbersRetrieveRequest.cs new file mode 100644 index 00000000..944d074d --- /dev/null +++ b/src/Merge.Client/Accounting/PhoneNumbers/requests/PhoneNumbersRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Accounting; + +public class PhoneNumbersRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/PurchaseOrders/PurchaseOrdersClient.cs b/src/Merge.Client/Accounting/PurchaseOrders/PurchaseOrdersClient.cs index 99775c33..ee1afd87 100644 --- a/src/Merge.Client/Accounting/PurchaseOrders/PurchaseOrdersClient.cs +++ b/src/Merge.Client/Accounting/PurchaseOrders/PurchaseOrdersClient.cs @@ -1,13 +1,185 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class PurchaseOrdersClient { - public async void List(){ + private RawClient _client; + + public PurchaseOrdersClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `PurchaseOrder` objects. + /// + public async Task ListAsync(PurchaseOrdersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IssueDateAfter != null) + { + _query["issue_date_after"] = request.IssueDateAfter; + } + if (request.IssueDateBefore != null) + { + _query["issue_date_before"] = request.IssueDateBefore; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/purchase-orders", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `PurchaseOrder` object with the given values. + /// + public async Task CreateAsync(PurchaseOrderEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/purchase-orders", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `PurchaseOrder` object with the given `id`. + /// + public async Task RetrieveAsync(string id, PurchaseOrdersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/purchase-orders/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `PurchaseOrder` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/purchase-orders/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersListRequestExpand.cs b/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersListRequestExpand.cs index 26228e6b..d4a6fe92 100644 --- a/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersListRequestExpand.cs +++ b/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersListRequestExpand.cs @@ -94,7 +94,9 @@ public enum PurchaseOrdersListRequestExpand [EnumMember(Value = "line_items,tracking_categories,delivery_address,company")] LineItemsTrackingCategoriesDeliveryAddressCompany, - [EnumMember(Value = "line_items,tracking_categories,delivery_address,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,delivery_address,company,accounting_period" + )] LineItemsTrackingCategoriesDeliveryAddressCompanyAccountingPeriod, [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor")] @@ -106,7 +108,9 @@ public enum PurchaseOrdersListRequestExpand [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor,company")] LineItemsTrackingCategoriesDeliveryAddressVendorCompany, - [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,delivery_address,vendor,company,accounting_period" + )] LineItemsTrackingCategoriesDeliveryAddressVendorCompanyAccountingPeriod, [EnumMember(Value = "line_items,tracking_categories,vendor")] diff --git a/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersRetrieveRequestExpand.cs b/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersRetrieveRequestExpand.cs index e0e4ad5e..223e9ff0 100644 --- a/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersRetrieveRequestExpand.cs +++ b/src/Merge.Client/Accounting/PurchaseOrders/Types/PurchaseOrdersRetrieveRequestExpand.cs @@ -94,7 +94,9 @@ public enum PurchaseOrdersRetrieveRequestExpand [EnumMember(Value = "line_items,tracking_categories,delivery_address,company")] LineItemsTrackingCategoriesDeliveryAddressCompany, - [EnumMember(Value = "line_items,tracking_categories,delivery_address,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,delivery_address,company,accounting_period" + )] LineItemsTrackingCategoriesDeliveryAddressCompanyAccountingPeriod, [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor")] @@ -106,7 +108,9 @@ public enum PurchaseOrdersRetrieveRequestExpand [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor,company")] LineItemsTrackingCategoriesDeliveryAddressVendorCompany, - [EnumMember(Value = "line_items,tracking_categories,delivery_address,vendor,company,accounting_period")] + [EnumMember( + Value = "line_items,tracking_categories,delivery_address,vendor,company,accounting_period" + )] LineItemsTrackingCategoriesDeliveryAddressVendorCompanyAccountingPeriod, [EnumMember(Value = "line_items,tracking_categories,vendor")] diff --git a/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrderEndpointRequest.cs b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrderEndpointRequest.cs new file mode 100644 index 00000000..e6f18f86 --- /dev/null +++ b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrderEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PurchaseOrderEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PurchaseOrderRequest Model { get; init; } +} diff --git a/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersListRequest.cs b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersListRequest.cs new file mode 100644 index 00000000..03f42384 --- /dev/null +++ b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PurchaseOrdersListRequest +{ + /// + /// If provided, will only return purchase orders for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public PurchaseOrdersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? IssueDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? IssueDateBefore { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersRetrieveRequest.cs b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersRetrieveRequest.cs new file mode 100644 index 00000000..ede7f2e6 --- /dev/null +++ b/src/Merge.Client/Accounting/PurchaseOrders/requests/PurchaseOrdersRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class PurchaseOrdersRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public PurchaseOrdersRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Accounting/RegenerateKey/RegenerateKeyClient.cs index 8bdd7e4b..690f6dd0 100644 --- a/src/Merge.Client/Accounting/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Accounting/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Accounting/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..df894b1b --- /dev/null +++ b/src/Merge.Client/Accounting/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Accounting; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Accounting/Scopes/ScopesClient.cs b/src/Merge.Client/Accounting/Scopes/ScopesClient.cs new file mode 100644 index 00000000..5cbd901e --- /dev/null +++ b/src/Merge.Client/Accounting/Scopes/ScopesClient.cs @@ -0,0 +1,78 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/default-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Accounting/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Accounting/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..40eb84c4 --- /dev/null +++ b/src/Merge.Client/Accounting/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Accounting/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Accounting/SelectiveSync/SelectiveSyncClient.cs index 4b96fb4e..99c2c807 100644 --- a/src/Merge.Client/Accounting/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Accounting/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/accounting/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Accounting/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..efd4d538 --- /dev/null +++ b/src/Merge.Client/Accounting/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Accounting/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Accounting/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..f3676357 --- /dev/null +++ b/src/Merge.Client/Accounting/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Accounting; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Accounting/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Accounting/SyncStatus/SyncStatusClient.cs index 0c44e747..58804682 100644 --- a/src/Merge.Client/Accounting/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Accounting/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Accounting/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..9a5b206f --- /dev/null +++ b/src/Merge.Client/Accounting/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Accounting/TaxRates/TaxRatesClient.cs b/src/Merge.Client/Accounting/TaxRates/TaxRatesClient.cs index b29b3022..3e4154a5 100644 --- a/src/Merge.Client/Accounting/TaxRates/TaxRatesClient.cs +++ b/src/Merge.Client/Accounting/TaxRates/TaxRatesClient.cs @@ -1,9 +1,111 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class TaxRatesClient { - public async void List(){ + private RawClient _client; + + public TaxRatesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `TaxRate` objects. + /// + public async Task ListAsync(TaxRatesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/tax-rates", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `TaxRate` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TaxRatesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/tax-rates/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesListRequest.cs b/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesListRequest.cs new file mode 100644 index 00000000..6e83cdc8 --- /dev/null +++ b/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Accounting; + +public class TaxRatesListRequest +{ + /// + /// If provided, will only return tax rates for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesRetrieveRequest.cs b/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesRetrieveRequest.cs new file mode 100644 index 00000000..c866feb4 --- /dev/null +++ b/src/Merge.Client/Accounting/TaxRates/requests/TaxRatesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Accounting; + +public class TaxRatesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/TrackingCategories/TrackingCategoriesClient.cs b/src/Merge.Client/Accounting/TrackingCategories/TrackingCategoriesClient.cs index 2cf70448..6d6f109b 100644 --- a/src/Merge.Client/Accounting/TrackingCategories/TrackingCategoriesClient.cs +++ b/src/Merge.Client/Accounting/TrackingCategories/TrackingCategoriesClient.cs @@ -1,9 +1,132 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class TrackingCategoriesClient { - public async void List(){ + private RawClient _client; + + public TrackingCategoriesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `TrackingCategory` objects. + /// + public async Task ListAsync( + TrackingCategoriesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/tracking-categories", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `TrackingCategory` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + TrackingCategoriesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/tracking-categories/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesListRequest.cs b/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesListRequest.cs new file mode 100644 index 00000000..93cf69c4 --- /dev/null +++ b/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesListRequest.cs @@ -0,0 +1,69 @@ +namespace Merge.Client.Accounting; + +public class TrackingCategoriesListRequest +{ + /// + /// If provided, will only return tracking categories for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesRetrieveRequest.cs b/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesRetrieveRequest.cs new file mode 100644 index 00000000..59c36c19 --- /dev/null +++ b/src/Merge.Client/Accounting/TrackingCategories/requests/TrackingCategoriesRetrieveRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Accounting; + +public class TrackingCategoriesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Accounting/Transactions/TransactionsClient.cs b/src/Merge.Client/Accounting/Transactions/TransactionsClient.cs index 4a94056f..fb29adf2 100644 --- a/src/Merge.Client/Accounting/Transactions/TransactionsClient.cs +++ b/src/Merge.Client/Accounting/Transactions/TransactionsClient.cs @@ -1,9 +1,119 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class TransactionsClient { - public async void List(){ + private RawClient _client; + + public TransactionsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Transaction` objects. + /// + public async Task ListAsync(TransactionsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/transactions", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Transaction` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TransactionsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/transactions/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/Transactions/requests/TransactionsListRequest.cs b/src/Merge.Client/Accounting/Transactions/requests/TransactionsListRequest.cs new file mode 100644 index 00000000..0af483c0 --- /dev/null +++ b/src/Merge.Client/Accounting/Transactions/requests/TransactionsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class TransactionsListRequest +{ + /// + /// If provided, will only return accounting transactions for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TransactionsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/Transactions/requests/TransactionsRetrieveRequest.cs b/src/Merge.Client/Accounting/Transactions/requests/TransactionsRetrieveRequest.cs new file mode 100644 index 00000000..79ac2ee1 --- /dev/null +++ b/src/Merge.Client/Accounting/Transactions/requests/TransactionsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class TransactionsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TransactionsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/Account.cs b/src/Merge.Client/Accounting/Types/Account.cs index 05c18633..e9313a66 100644 --- a/src/Merge.Client/Accounting/Types/Account.cs +++ b/src/Merge.Client/Accounting/Types/Account.cs @@ -14,6 +14,15 @@ public class Account [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The account's name. /// @@ -28,7 +37,7 @@ public class Account /// /// The account's broadest grouping. - /// + /// /// - `ASSET` - ASSET /// - `EQUITY` - EQUITY /// - `EXPENSE` - EXPENSE @@ -46,7 +55,7 @@ public class Account /// /// The account's status. - /// + /// /// - `ACTIVE` - ACTIVE /// - `PENDING` - PENDING /// - `INACTIVE` - INACTIVE @@ -62,7 +71,7 @@ public class Account /// /// The account's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -397,15 +406,6 @@ public class Account [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Accounting/Types/AccountDetailsAndActions.cs index c08ecf49..b038475b 100644 --- a/src/Merge.Client/Accounting/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Accounting/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Accounting/Types/AccountIntegration.cs b/src/Merge.Client/Accounting/Types/AccountIntegration.cs index a4643788..bdad051d 100644 --- a/src/Merge.Client/Accounting/Types/AccountIntegration.cs +++ b/src/Merge.Client/Accounting/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/AccountRequest.cs b/src/Merge.Client/Accounting/Types/AccountRequest.cs index 020e5f17..b70d3103 100644 --- a/src/Merge.Client/Accounting/Types/AccountRequest.cs +++ b/src/Merge.Client/Accounting/Types/AccountRequest.cs @@ -19,7 +19,7 @@ public class AccountRequest /// /// The account's broadest grouping. - /// + /// /// - `ASSET` - ASSET /// - `EQUITY` - EQUITY /// - `EXPENSE` - EXPENSE @@ -37,7 +37,7 @@ public class AccountRequest /// /// The account's status. - /// + /// /// - `ACTIVE` - ACTIVE /// - `PENDING` - PENDING /// - `INACTIVE` - INACTIVE @@ -53,7 +53,7 @@ public class AccountRequest /// /// The account's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/AccountingAttachment.cs b/src/Merge.Client/Accounting/Types/AccountingAttachment.cs index 650674ab..30209594 100644 --- a/src/Merge.Client/Accounting/Types/AccountingAttachment.cs +++ b/src/Merge.Client/Accounting/Types/AccountingAttachment.cs @@ -14,6 +14,15 @@ public class AccountingAttachment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The attachment's name. /// @@ -38,15 +47,6 @@ public class AccountingAttachment [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/AccountingPeriod.cs b/src/Merge.Client/Accounting/Types/AccountingPeriod.cs index 0616bf5a..aa942fc0 100644 --- a/src/Merge.Client/Accounting/Types/AccountingPeriod.cs +++ b/src/Merge.Client/Accounting/Types/AccountingPeriod.cs @@ -5,6 +5,18 @@ namespace Merge.Client.Accounting; public class AccountingPeriod { + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// Beginning date of the period /// @@ -25,16 +37,4 @@ public class AccountingPeriod /// [JsonPropertyName("name")] public string? Name { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/AccountingPhoneNumber.cs b/src/Merge.Client/Accounting/Types/AccountingPhoneNumber.cs index f3e5a722..c7e4bcb1 100644 --- a/src/Merge.Client/Accounting/Types/AccountingPhoneNumber.cs +++ b/src/Merge.Client/Accounting/Types/AccountingPhoneNumber.cs @@ -4,6 +4,15 @@ namespace Merge.Client.Accounting; public class AccountingPhoneNumber { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The phone number. /// @@ -15,13 +24,4 @@ public class AccountingPhoneNumber /// [JsonPropertyName("type")] public string? Type { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/Address.cs b/src/Merge.Client/Accounting/Types/Address.cs index 3f647523..3c80cffc 100644 --- a/src/Merge.Client/Accounting/Types/Address.cs +++ b/src/Merge.Client/Accounting/Types/Address.cs @@ -5,9 +5,18 @@ namespace Merge.Client.Accounting; public class Address { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The address type. - /// + /// /// - `BILLING` - BILLING /// - `SHIPPING` - SHIPPING /// @@ -43,7 +52,7 @@ public class Address /// /// The address's country. - /// + /// /// - `AF` - Afghanistan /// - `AX` - Åland Islands /// - `AL` - Albania @@ -302,13 +311,4 @@ public class Address /// [JsonPropertyName("zip_code")] public string? ZipCode { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/AddressRequest.cs b/src/Merge.Client/Accounting/Types/AddressRequest.cs index f4d901b6..ad2a4772 100644 --- a/src/Merge.Client/Accounting/Types/AddressRequest.cs +++ b/src/Merge.Client/Accounting/Types/AddressRequest.cs @@ -7,7 +7,7 @@ public class AddressRequest { /// /// The address type. - /// + /// /// - `BILLING` - BILLING /// - `SHIPPING` - SHIPPING /// @@ -40,7 +40,7 @@ public class AddressRequest /// /// The address's country. - /// + /// /// - `AF` - Afghanistan /// - `AX` - Åland Islands /// - `AL` - Albania diff --git a/src/Merge.Client/Accounting/Types/AdvancedMetadata.cs b/src/Merge.Client/Accounting/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..95fde5e3 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/AuditLogEvent.cs b/src/Merge.Client/Accounting/Types/AuditLogEvent.cs index 3ca3760e..f25c03f9 100644 --- a/src/Merge.Client/Accounting/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Accounting/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Accounting/Types/BalanceSheet.cs b/src/Merge.Client/Accounting/Types/BalanceSheet.cs index f1c75e6b..3ae2f928 100644 --- a/src/Merge.Client/Accounting/Types/BalanceSheet.cs +++ b/src/Merge.Client/Accounting/Types/BalanceSheet.cs @@ -15,6 +15,15 @@ public class BalanceSheet [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The balance sheet's name. /// @@ -23,7 +32,7 @@ public class BalanceSheet /// /// The balance sheet's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -373,15 +382,6 @@ public class BalanceSheet [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/CashFlowStatement.cs b/src/Merge.Client/Accounting/Types/CashFlowStatement.cs index 1c1dfb9c..036194b0 100644 --- a/src/Merge.Client/Accounting/Types/CashFlowStatement.cs +++ b/src/Merge.Client/Accounting/Types/CashFlowStatement.cs @@ -15,6 +15,15 @@ public class CashFlowStatement [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The cash flow statement's name. /// @@ -23,7 +32,7 @@ public class CashFlowStatement /// /// The cash flow statement's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -385,15 +394,6 @@ public class CashFlowStatement [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/CommonModelScopeApi.cs b/src/Merge.Client/Accounting/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..a03d1c65 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/CompanyInfo.cs b/src/Merge.Client/Accounting/Types/CompanyInfo.cs index af1ef1da..0b7a8284 100644 --- a/src/Merge.Client/Accounting/Types/CompanyInfo.cs +++ b/src/Merge.Client/Accounting/Types/CompanyInfo.cs @@ -14,6 +14,15 @@ public class CompanyInfo [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The company's name. /// @@ -46,7 +55,7 @@ public class CompanyInfo /// /// The currency set in the company's accounting platform. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -381,15 +390,6 @@ public class CompanyInfo [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/ConditionSchema.cs b/src/Merge.Client/Accounting/Types/ConditionSchema.cs index 295494b3..388d5dc1 100644 --- a/src/Merge.Client/Accounting/Types/ConditionSchema.cs +++ b/src/Merge.Client/Accounting/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Accounting/Types/Contact.cs b/src/Merge.Client/Accounting/Types/Contact.cs index c5567c07..86607746 100644 --- a/src/Merge.Client/Accounting/Types/Contact.cs +++ b/src/Merge.Client/Accounting/Types/Contact.cs @@ -15,6 +15,15 @@ public class Contact [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The contact's name. /// @@ -47,7 +56,7 @@ public class Contact /// /// The contact's status - /// + /// /// - `ACTIVE` - ACTIVE /// - `ARCHIVED` - ARCHIVED /// @@ -90,15 +99,6 @@ public class Contact [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/ContactRequest.cs b/src/Merge.Client/Accounting/Types/ContactRequest.cs index cf6d768f..85dec372 100644 --- a/src/Merge.Client/Accounting/Types/ContactRequest.cs +++ b/src/Merge.Client/Accounting/Types/ContactRequest.cs @@ -38,7 +38,7 @@ public class ContactRequest /// /// The contact's status - /// + /// /// - `ACTIVE` - ACTIVE /// - `ARCHIVED` - ARCHIVED /// diff --git a/src/Merge.Client/Accounting/Types/CreditNote.cs b/src/Merge.Client/Accounting/Types/CreditNote.cs index 5bde5cb1..1562ac32 100644 --- a/src/Merge.Client/Accounting/Types/CreditNote.cs +++ b/src/Merge.Client/Accounting/Types/CreditNote.cs @@ -15,6 +15,15 @@ public class CreditNote [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The credit note's transaction date. /// @@ -23,7 +32,7 @@ public class CreditNote /// /// The credit note's status. - /// + /// /// - `SUBMITTED` - SUBMITTED /// - `AUTHORIZED` - AUTHORIZED /// - `PAID` - PAID @@ -75,7 +84,7 @@ public class CreditNote /// /// The credit note's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -422,15 +431,6 @@ public class CreditNote [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/CreditNoteLineItem.cs b/src/Merge.Client/Accounting/Types/CreditNoteLineItem.cs index 3550cbc2..281bc576 100644 --- a/src/Merge.Client/Accounting/Types/CreditNoteLineItem.cs +++ b/src/Merge.Client/Accounting/Types/CreditNoteLineItem.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class CreditNoteLineItem { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("item")] public OneOf? Item { get; init; } @@ -75,27 +93,9 @@ public class CreditNoteLineItem [JsonPropertyName("company")] public OneOf? Company { get; init; } - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - /// /// Indicates whether or not this object has been deleted in the third party platform. /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/DataPassthroughRequest.cs b/src/Merge.Client/Accounting/Types/DataPassthroughRequest.cs index 8355cb63..1db60a47 100644 --- a/src/Merge.Client/Accounting/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Accounting/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Accounting/Types/EventTypeEnum.cs b/src/Merge.Client/Accounting/Types/EventTypeEnum.cs index 4baafdd9..69053e3b 100644 --- a/src/Merge.Client/Accounting/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Accounting/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Accounting/Types/Expense.cs b/src/Merge.Client/Accounting/Types/Expense.cs index b3b23cda..cd77e841 100644 --- a/src/Merge.Client/Accounting/Types/Expense.cs +++ b/src/Merge.Client/Accounting/Types/Expense.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class Expense { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// When the transaction occurred. /// @@ -50,7 +68,7 @@ public class Expense /// /// The expense's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -397,24 +415,6 @@ public class Expense [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/ExpenseLine.cs b/src/Merge.Client/Accounting/Types/ExpenseLine.cs index 4c9fe504..f63964ed 100644 --- a/src/Merge.Client/Accounting/Types/ExpenseLine.cs +++ b/src/Merge.Client/Accounting/Types/ExpenseLine.cs @@ -1,17 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class ExpenseLine { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The line's item. /// @@ -38,7 +50,7 @@ public class ExpenseLine /// /// The expense line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -378,16 +390,4 @@ public class ExpenseLine /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/ExpenseLineRequest.cs b/src/Merge.Client/Accounting/Types/ExpenseLineRequest.cs index 52bfba2d..fab9554a 100644 --- a/src/Merge.Client/Accounting/Types/ExpenseLineRequest.cs +++ b/src/Merge.Client/Accounting/Types/ExpenseLineRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -38,7 +38,7 @@ public class ExpenseLineRequest /// /// The expense line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/ExpenseRequest.cs b/src/Merge.Client/Accounting/Types/ExpenseRequest.cs index 08839ac8..dc8a32c9 100644 --- a/src/Merge.Client/Accounting/Types/ExpenseRequest.cs +++ b/src/Merge.Client/Accounting/Types/ExpenseRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -44,7 +44,7 @@ public class ExpenseRequest /// /// The expense's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Accounting/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..8530045f --- /dev/null +++ b/src/Merge.Client/Accounting/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Accounting/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..0037c442 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("AccountingAttachment")] + public List? AccountingAttachment { get; init; } + + [JsonPropertyName("BalanceSheet")] + public List? BalanceSheet { get; init; } + + [JsonPropertyName("CashFlowStatement")] + public List? CashFlowStatement { get; init; } + + [JsonPropertyName("CompanyInfo")] + public List? CompanyInfo { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("IncomeStatement")] + public List? IncomeStatement { get; init; } + + [JsonPropertyName("CreditNote")] + public List? CreditNote { get; init; } + + [JsonPropertyName("Item")] + public List? Item { get; init; } + + [JsonPropertyName("PurchaseOrder")] + public List? PurchaseOrder { get; init; } + + [JsonPropertyName("TrackingCategory")] + public List? TrackingCategory { get; init; } + + [JsonPropertyName("JournalEntry")] + public List? JournalEntry { get; init; } + + [JsonPropertyName("TaxRate")] + public List? TaxRate { get; init; } + + [JsonPropertyName("Invoice")] + public List? Invoice { get; init; } + + [JsonPropertyName("Payment")] + public List? Payment { get; init; } + + [JsonPropertyName("Expense")] + public List? Expense { get; init; } + + [JsonPropertyName("VendorCredit")] + public List? VendorCredit { get; init; } + + [JsonPropertyName("Transaction")] + public List? Transaction { get; init; } + + [JsonPropertyName("GeneralLedgerTransaction")] + public List? GeneralLedgerTransaction { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Accounting/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..89c8d8d6 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..bb8c54b9 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..3dde8daf --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..ab85b153 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("AccountingAttachment")] + public List? AccountingAttachment { get; init; } + + [JsonPropertyName("BalanceSheet")] + public List? BalanceSheet { get; init; } + + [JsonPropertyName("CashFlowStatement")] + public List? CashFlowStatement { get; init; } + + [JsonPropertyName("CompanyInfo")] + public List? CompanyInfo { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("IncomeStatement")] + public List? IncomeStatement { get; init; } + + [JsonPropertyName("CreditNote")] + public List? CreditNote { get; init; } + + [JsonPropertyName("Item")] + public List? Item { get; init; } + + [JsonPropertyName("PurchaseOrder")] + public List? PurchaseOrder { get; init; } + + [JsonPropertyName("TrackingCategory")] + public List? TrackingCategory { get; init; } + + [JsonPropertyName("JournalEntry")] + public List? JournalEntry { get; init; } + + [JsonPropertyName("TaxRate")] + public List? TaxRate { get; init; } + + [JsonPropertyName("Invoice")] + public List? Invoice { get; init; } + + [JsonPropertyName("Payment")] + public List? Payment { get; init; } + + [JsonPropertyName("Expense")] + public List? Expense { get; init; } + + [JsonPropertyName("VendorCredit")] + public List? VendorCredit { get; init; } + + [JsonPropertyName("Transaction")] + public List? Transaction { get; init; } + + [JsonPropertyName("GeneralLedgerTransaction")] + public List? GeneralLedgerTransaction { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..b662c022 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Accounting/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..0423ed3d --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Accounting/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..ad3fbba4 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Accounting/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..8f0a9aa9 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/IncomeStatement.cs b/src/Merge.Client/Accounting/Types/IncomeStatement.cs index 9e7045a3..33b24be5 100644 --- a/src/Merge.Client/Accounting/Types/IncomeStatement.cs +++ b/src/Merge.Client/Accounting/Types/IncomeStatement.cs @@ -15,6 +15,15 @@ public class IncomeStatement [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The income statement's name. /// @@ -23,7 +32,7 @@ public class IncomeStatement /// /// The income statement's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -388,15 +397,6 @@ public class IncomeStatement [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..497f1fa3 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..f810d0ff --- /dev/null +++ b/src/Merge.Client/Accounting/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/Invoice.cs b/src/Merge.Client/Accounting/Types/Invoice.cs index 257eb133..41e3fcac 100644 --- a/src/Merge.Client/Accounting/Types/Invoice.cs +++ b/src/Merge.Client/Accounting/Types/Invoice.cs @@ -10,8 +10,23 @@ public class Invoice public string? Id { get; init; } /// - /// Whether the invoice is an accounts receivable or accounts payable. If `type` is `accounts_payable`, the invoice is a bill. If `type` is `accounts_receivable`, it is an invoice. - /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + + /// + /// Whether the invoice is an accounts receivable or accounts payable. If `type` is `ACCOUNTS_PAYABLE`, the invoice is a bill. If `type` is `ACCOUNTS_RECEIVABLE`, it is an invoice. + /// /// - `ACCOUNTS_RECEIVABLE` - ACCOUNTS_RECEIVABLE /// - `ACCOUNTS_PAYABLE` - ACCOUNTS_PAYABLE /// @@ -62,7 +77,7 @@ public class Invoice /// /// The invoice's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -393,7 +408,7 @@ public class Invoice /// /// The status of the invoice. - /// + /// /// - `PAID` - PAID /// - `DRAFT` - DRAFT /// - `SUBMITTED` - SUBMITTED @@ -458,21 +473,6 @@ public class Invoice [JsonPropertyName("purchase_orders")] public List?>? PurchaseOrders { get; init; } - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/InvoiceLineItem.cs b/src/Merge.Client/Accounting/Types/InvoiceLineItem.cs index 9ad7e912..5f1989de 100644 --- a/src/Merge.Client/Accounting/Types/InvoiceLineItem.cs +++ b/src/Merge.Client/Accounting/Types/InvoiceLineItem.cs @@ -6,12 +6,24 @@ namespace Merge.Client.Accounting; public class InvoiceLineItem { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The line item's description. /// @@ -38,7 +50,7 @@ public class InvoiceLineItem /// /// The line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -379,18 +391,6 @@ public class InvoiceLineItem [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/InvoiceLineItemRequest.cs b/src/Merge.Client/Accounting/Types/InvoiceLineItemRequest.cs index e9620721..d75e256d 100644 --- a/src/Merge.Client/Accounting/Types/InvoiceLineItemRequest.cs +++ b/src/Merge.Client/Accounting/Types/InvoiceLineItemRequest.cs @@ -38,7 +38,7 @@ public class InvoiceLineItemRequest /// /// The line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/InvoiceRequest.cs b/src/Merge.Client/Accounting/Types/InvoiceRequest.cs index 45300945..cf580c1f 100644 --- a/src/Merge.Client/Accounting/Types/InvoiceRequest.cs +++ b/src/Merge.Client/Accounting/Types/InvoiceRequest.cs @@ -7,8 +7,8 @@ namespace Merge.Client.Accounting; public class InvoiceRequest { /// - /// Whether the invoice is an accounts receivable or accounts payable. If `type` is `accounts_payable`, the invoice is a bill. If `type` is `accounts_receivable`, it is an invoice. - /// + /// Whether the invoice is an accounts receivable or accounts payable. If `type` is `ACCOUNTS_PAYABLE`, the invoice is a bill. If `type` is `ACCOUNTS_RECEIVABLE`, it is an invoice. + /// /// - `ACCOUNTS_RECEIVABLE` - ACCOUNTS_RECEIVABLE /// - `ACCOUNTS_PAYABLE` - ACCOUNTS_PAYABLE /// @@ -53,7 +53,7 @@ public class InvoiceRequest /// /// The status of the invoice. - /// + /// /// - `PAID` - PAID /// - `DRAFT` - DRAFT /// - `SUBMITTED` - SUBMITTED @@ -72,7 +72,7 @@ public class InvoiceRequest /// /// The invoice's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/Issue.cs b/src/Merge.Client/Accounting/Types/Issue.cs index 184dac69..0819fa29 100644 --- a/src/Merge.Client/Accounting/Types/Issue.cs +++ b/src/Merge.Client/Accounting/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Accounting/Types/Item.cs b/src/Merge.Client/Accounting/Types/Item.cs index 95cb0c94..ff9ce1bd 100644 --- a/src/Merge.Client/Accounting/Types/Item.cs +++ b/src/Merge.Client/Accounting/Types/Item.cs @@ -15,6 +15,15 @@ public class Item [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The item's name. /// @@ -23,7 +32,7 @@ public class Item /// /// The item's status. - /// + /// /// - `ACTIVE` - ACTIVE /// - `ARCHIVED` - ARCHIVED /// @@ -72,15 +81,6 @@ public class Item [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/JournalEntry.cs b/src/Merge.Client/Accounting/Types/JournalEntry.cs index 5bd5a1df..20f515df 100644 --- a/src/Merge.Client/Accounting/Types/JournalEntry.cs +++ b/src/Merge.Client/Accounting/Types/JournalEntry.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class JournalEntry { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The journal entry's transaction date. /// @@ -44,7 +62,7 @@ public class JournalEntry /// /// The journal's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -384,7 +402,7 @@ public class JournalEntry /// /// The journal's posting status. - /// + /// /// - `UNPOSTED` - UNPOSTED /// - `POSTED` - POSTED /// @@ -397,24 +415,6 @@ public class JournalEntry [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/JournalEntryRequest.cs b/src/Merge.Client/Accounting/Types/JournalEntryRequest.cs index 82b8ab8c..863b29bd 100644 --- a/src/Merge.Client/Accounting/Types/JournalEntryRequest.cs +++ b/src/Merge.Client/Accounting/Types/JournalEntryRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -26,7 +26,7 @@ public class JournalEntryRequest /// /// The journal's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -363,7 +363,7 @@ public class JournalEntryRequest /// /// The journal's posting status. - /// + /// /// - `UNPOSTED` - UNPOSTED /// - `POSTED` - POSTED /// diff --git a/src/Merge.Client/Accounting/Types/JournalLine.cs b/src/Merge.Client/Accounting/Types/JournalLine.cs index c4a9193e..b418bc92 100644 --- a/src/Merge.Client/Accounting/Types/JournalLine.cs +++ b/src/Merge.Client/Accounting/Types/JournalLine.cs @@ -1,17 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class JournalLine { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("account")] public OneOf? Account { get; init; } @@ -29,7 +41,7 @@ public class JournalLine /// /// The journal line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -366,16 +378,4 @@ public class JournalLine /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/JournalLineRequest.cs b/src/Merge.Client/Accounting/Types/JournalLineRequest.cs index b655fa44..20ce7fc8 100644 --- a/src/Merge.Client/Accounting/Types/JournalLineRequest.cs +++ b/src/Merge.Client/Accounting/Types/JournalLineRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -29,7 +29,7 @@ public class JournalLineRequest /// /// The journal line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/LinkedAccountCondition.cs b/src/Merge.Client/Accounting/Types/LinkedAccountCondition.cs index 463163a1..431acd1a 100644 --- a/src/Merge.Client/Accounting/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Accounting/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Accounting/Types/LinkedAccountConditionRequest.cs index 4b153276..b4da31ff 100644 --- a/src/Merge.Client/Accounting/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Accounting/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Accounting; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Accounting/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Accounting/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..b21ebee5 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Accounting/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..8ab11db1 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Accounting/Types/MultipartFormFieldRequest.cs index a90bc345..7440182f 100644 --- a/src/Merge.Client/Accounting/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Accounting/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Accounting/Types/PatchedPaymentRequest.cs b/src/Merge.Client/Accounting/Types/PatchedPaymentRequest.cs new file mode 100644 index 00000000..b0367a08 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/PatchedPaymentRequest.cs @@ -0,0 +1,378 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; +using OneOf; + +namespace Merge.Client.Accounting; + +public class PatchedPaymentRequest +{ + /// + /// The payment's transaction date. + /// + [JsonPropertyName("transaction_date")] + public DateTime? TransactionDate { get; init; } + + /// + /// The supplier, or customer involved in the payment. + /// + [JsonPropertyName("contact")] + public OneOf? Contact { get; init; } + + /// + /// The supplier’s or customer’s account in which the payment is made. + /// + [JsonPropertyName("account")] + public OneOf? Account { get; init; } + + /// + /// The payment's currency. + /// + /// - `XUA` - ADB Unit of Account + /// - `AFN` - Afghan Afghani + /// - `AFA` - Afghan Afghani (1927–2002) + /// - `ALL` - Albanian Lek + /// - `ALK` - Albanian Lek (1946–1965) + /// - `DZD` - Algerian Dinar + /// - `ADP` - Andorran Peseta + /// - `AOA` - Angolan Kwanza + /// - `AOK` - Angolan Kwanza (1977–1991) + /// - `AON` - Angolan New Kwanza (1990–2000) + /// - `AOR` - Angolan Readjusted Kwanza (1995–1999) + /// - `ARA` - Argentine Austral + /// - `ARS` - Argentine Peso + /// - `ARM` - Argentine Peso (1881–1970) + /// - `ARP` - Argentine Peso (1983–1985) + /// - `ARL` - Argentine Peso Ley (1970–1983) + /// - `AMD` - Armenian Dram + /// - `AWG` - Aruban Florin + /// - `AUD` - Australian Dollar + /// - `ATS` - Austrian Schilling + /// - `AZN` - Azerbaijani Manat + /// - `AZM` - Azerbaijani Manat (1993–2006) + /// - `BSD` - Bahamian Dollar + /// - `BHD` - Bahraini Dinar + /// - `BDT` - Bangladeshi Taka + /// - `BBD` - Barbadian Dollar + /// - `BYN` - Belarusian Ruble + /// - `BYB` - Belarusian Ruble (1994–1999) + /// - `BYR` - Belarusian Ruble (2000–2016) + /// - `BEF` - Belgian Franc + /// - `BEC` - Belgian Franc (convertible) + /// - `BEL` - Belgian Franc (financial) + /// - `BZD` - Belize Dollar + /// - `BMD` - Bermudan Dollar + /// - `BTN` - Bhutanese Ngultrum + /// - `BOB` - Bolivian Boliviano + /// - `BOL` - Bolivian Boliviano (1863–1963) + /// - `BOV` - Bolivian Mvdol + /// - `BOP` - Bolivian Peso + /// - `BAM` - Bosnia-Herzegovina Convertible Mark + /// - `BAD` - Bosnia-Herzegovina Dinar (1992–1994) + /// - `BAN` - Bosnia-Herzegovina New Dinar (1994–1997) + /// - `BWP` - Botswanan Pula + /// - `BRC` - Brazilian Cruzado (1986–1989) + /// - `BRZ` - Brazilian Cruzeiro (1942–1967) + /// - `BRE` - Brazilian Cruzeiro (1990–1993) + /// - `BRR` - Brazilian Cruzeiro (1993–1994) + /// - `BRN` - Brazilian New Cruzado (1989–1990) + /// - `BRB` - Brazilian New Cruzeiro (1967–1986) + /// - `BRL` - Brazilian Real + /// - `GBP` - British Pound + /// - `BND` - Brunei Dollar + /// - `BGL` - Bulgarian Hard Lev + /// - `BGN` - Bulgarian Lev + /// - `BGO` - Bulgarian Lev (1879–1952) + /// - `BGM` - Bulgarian Socialist Lev + /// - `BUK` - Burmese Kyat + /// - `BIF` - Burundian Franc + /// - `XPF` - CFP Franc + /// - `KHR` - Cambodian Riel + /// - `CAD` - Canadian Dollar + /// - `CVE` - Cape Verdean Escudo + /// - `KYD` - Cayman Islands Dollar + /// - `XAF` - Central African CFA Franc + /// - `CLE` - Chilean Escudo + /// - `CLP` - Chilean Peso + /// - `CLF` - Chilean Unit of Account (UF) + /// - `CNX` - Chinese People’s Bank Dollar + /// - `CNY` - Chinese Yuan + /// - `CNH` - Chinese Yuan (offshore) + /// - `COP` - Colombian Peso + /// - `COU` - Colombian Real Value Unit + /// - `KMF` - Comorian Franc + /// - `CDF` - Congolese Franc + /// - `CRC` - Costa Rican Colón + /// - `HRD` - Croatian Dinar + /// - `HRK` - Croatian Kuna + /// - `CUC` - Cuban Convertible Peso + /// - `CUP` - Cuban Peso + /// - `CYP` - Cypriot Pound + /// - `CZK` - Czech Koruna + /// - `CSK` - Czechoslovak Hard Koruna + /// - `DKK` - Danish Krone + /// - `DJF` - Djiboutian Franc + /// - `DOP` - Dominican Peso + /// - `NLG` - Dutch Guilder + /// - `XCD` - East Caribbean Dollar + /// - `DDM` - East German Mark + /// - `ECS` - Ecuadorian Sucre + /// - `ECV` - Ecuadorian Unit of Constant Value + /// - `EGP` - Egyptian Pound + /// - `GQE` - Equatorial Guinean Ekwele + /// - `ERN` - Eritrean Nakfa + /// - `EEK` - Estonian Kroon + /// - `ETB` - Ethiopian Birr + /// - `EUR` - Euro + /// - `XBA` - European Composite Unit + /// - `XEU` - European Currency Unit + /// - `XBB` - European Monetary Unit + /// - `XBC` - European Unit of Account (XBC) + /// - `XBD` - European Unit of Account (XBD) + /// - `FKP` - Falkland Islands Pound + /// - `FJD` - Fijian Dollar + /// - `FIM` - Finnish Markka + /// - `FRF` - French Franc + /// - `XFO` - French Gold Franc + /// - `XFU` - French UIC-Franc + /// - `GMD` - Gambian Dalasi + /// - `GEK` - Georgian Kupon Larit + /// - `GEL` - Georgian Lari + /// - `DEM` - German Mark + /// - `GHS` - Ghanaian Cedi + /// - `GHC` - Ghanaian Cedi (1979–2007) + /// - `GIP` - Gibraltar Pound + /// - `XAU` - Gold + /// - `GRD` - Greek Drachma + /// - `GTQ` - Guatemalan Quetzal + /// - `GWP` - Guinea-Bissau Peso + /// - `GNF` - Guinean Franc + /// - `GNS` - Guinean Syli + /// - `GYD` - Guyanaese Dollar + /// - `HTG` - Haitian Gourde + /// - `HNL` - Honduran Lempira + /// - `HKD` - Hong Kong Dollar + /// - `HUF` - Hungarian Forint + /// - `IMP` - IMP + /// - `ISK` - Icelandic Króna + /// - `ISJ` - Icelandic Króna (1918–1981) + /// - `INR` - Indian Rupee + /// - `IDR` - Indonesian Rupiah + /// - `IRR` - Iranian Rial + /// - `IQD` - Iraqi Dinar + /// - `IEP` - Irish Pound + /// - `ILS` - Israeli New Shekel + /// - `ILP` - Israeli Pound + /// - `ILR` - Israeli Shekel (1980–1985) + /// - `ITL` - Italian Lira + /// - `JMD` - Jamaican Dollar + /// - `JPY` - Japanese Yen + /// - `JOD` - Jordanian Dinar + /// - `KZT` - Kazakhstani Tenge + /// - `KES` - Kenyan Shilling + /// - `KWD` - Kuwaiti Dinar + /// - `KGS` - Kyrgystani Som + /// - `LAK` - Laotian Kip + /// - `LVL` - Latvian Lats + /// - `LVR` - Latvian Ruble + /// - `LBP` - Lebanese Pound + /// - `LSL` - Lesotho Loti + /// - `LRD` - Liberian Dollar + /// - `LYD` - Libyan Dinar + /// - `LTL` - Lithuanian Litas + /// - `LTT` - Lithuanian Talonas + /// - `LUL` - Luxembourg Financial Franc + /// - `LUC` - Luxembourgian Convertible Franc + /// - `LUF` - Luxembourgian Franc + /// - `MOP` - Macanese Pataca + /// - `MKD` - Macedonian Denar + /// - `MKN` - Macedonian Denar (1992–1993) + /// - `MGA` - Malagasy Ariary + /// - `MGF` - Malagasy Franc + /// - `MWK` - Malawian Kwacha + /// - `MYR` - Malaysian Ringgit + /// - `MVR` - Maldivian Rufiyaa + /// - `MVP` - Maldivian Rupee (1947–1981) + /// - `MLF` - Malian Franc + /// - `MTL` - Maltese Lira + /// - `MTP` - Maltese Pound + /// - `MRU` - Mauritanian Ouguiya + /// - `MRO` - Mauritanian Ouguiya (1973–2017) + /// - `MUR` - Mauritian Rupee + /// - `MXV` - Mexican Investment Unit + /// - `MXN` - Mexican Peso + /// - `MXP` - Mexican Silver Peso (1861–1992) + /// - `MDC` - Moldovan Cupon + /// - `MDL` - Moldovan Leu + /// - `MCF` - Monegasque Franc + /// - `MNT` - Mongolian Tugrik + /// - `MAD` - Moroccan Dirham + /// - `MAF` - Moroccan Franc + /// - `MZE` - Mozambican Escudo + /// - `MZN` - Mozambican Metical + /// - `MZM` - Mozambican Metical (1980–2006) + /// - `MMK` - Myanmar Kyat + /// - `NAD` - Namibian Dollar + /// - `NPR` - Nepalese Rupee + /// - `ANG` - Netherlands Antillean Guilder + /// - `TWD` - New Taiwan Dollar + /// - `NZD` - New Zealand Dollar + /// - `NIO` - Nicaraguan Córdoba + /// - `NIC` - Nicaraguan Córdoba (1988–1991) + /// - `NGN` - Nigerian Naira + /// - `KPW` - North Korean Won + /// - `NOK` - Norwegian Krone + /// - `OMR` - Omani Rial + /// - `PKR` - Pakistani Rupee + /// - `XPD` - Palladium + /// - `PAB` - Panamanian Balboa + /// - `PGK` - Papua New Guinean Kina + /// - `PYG` - Paraguayan Guarani + /// - `PEI` - Peruvian Inti + /// - `PEN` - Peruvian Sol + /// - `PES` - Peruvian Sol (1863–1965) + /// - `PHP` - Philippine Peso + /// - `XPT` - Platinum + /// - `PLN` - Polish Zloty + /// - `PLZ` - Polish Zloty (1950–1995) + /// - `PTE` - Portuguese Escudo + /// - `GWE` - Portuguese Guinea Escudo + /// - `QAR` - Qatari Rial + /// - `XRE` - RINET Funds + /// - `RHD` - Rhodesian Dollar + /// - `RON` - Romanian Leu + /// - `ROL` - Romanian Leu (1952–2006) + /// - `RUB` - Russian Ruble + /// - `RUR` - Russian Ruble (1991–1998) + /// - `RWF` - Rwandan Franc + /// - `SVC` - Salvadoran Colón + /// - `WST` - Samoan Tala + /// - `SAR` - Saudi Riyal + /// - `RSD` - Serbian Dinar + /// - `CSD` - Serbian Dinar (2002–2006) + /// - `SCR` - Seychellois Rupee + /// - `SLL` - Sierra Leonean Leone + /// - `XAG` - Silver + /// - `SGD` - Singapore Dollar + /// - `SKK` - Slovak Koruna + /// - `SIT` - Slovenian Tolar + /// - `SBD` - Solomon Islands Dollar + /// - `SOS` - Somali Shilling + /// - `ZAR` - South African Rand + /// - `ZAL` - South African Rand (financial) + /// - `KRH` - South Korean Hwan (1953–1962) + /// - `KRW` - South Korean Won + /// - `KRO` - South Korean Won (1945–1953) + /// - `SSP` - South Sudanese Pound + /// - `SUR` - Soviet Rouble + /// - `ESP` - Spanish Peseta + /// - `ESA` - Spanish Peseta (A account) + /// - `ESB` - Spanish Peseta (convertible account) + /// - `XDR` - Special Drawing Rights + /// - `LKR` - Sri Lankan Rupee + /// - `SHP` - St. Helena Pound + /// - `XSU` - Sucre + /// - `SDD` - Sudanese Dinar (1992–2007) + /// - `SDG` - Sudanese Pound + /// - `SDP` - Sudanese Pound (1957–1998) + /// - `SRD` - Surinamese Dollar + /// - `SRG` - Surinamese Guilder + /// - `SZL` - Swazi Lilangeni + /// - `SEK` - Swedish Krona + /// - `CHF` - Swiss Franc + /// - `SYP` - Syrian Pound + /// - `STN` - São Tomé & Príncipe Dobra + /// - `STD` - São Tomé & Príncipe Dobra (1977–2017) + /// - `TVD` - TVD + /// - `TJR` - Tajikistani Ruble + /// - `TJS` - Tajikistani Somoni + /// - `TZS` - Tanzanian Shilling + /// - `XTS` - Testing Currency Code + /// - `THB` - Thai Baht + /// - `XXX` - The codes assigned for transactions where no currency is involved + /// - `TPE` - Timorese Escudo + /// - `TOP` - Tongan Paʻanga + /// - `TTD` - Trinidad & Tobago Dollar + /// - `TND` - Tunisian Dinar + /// - `TRY` - Turkish Lira + /// - `TRL` - Turkish Lira (1922–2005) + /// - `TMT` - Turkmenistani Manat + /// - `TMM` - Turkmenistani Manat (1993–2009) + /// - `USD` - US Dollar + /// - `USN` - US Dollar (Next day) + /// - `USS` - US Dollar (Same day) + /// - `UGX` - Ugandan Shilling + /// - `UGS` - Ugandan Shilling (1966–1987) + /// - `UAH` - Ukrainian Hryvnia + /// - `UAK` - Ukrainian Karbovanets + /// - `AED` - United Arab Emirates Dirham + /// - `UYW` - Uruguayan Nominal Wage Index Unit + /// - `UYU` - Uruguayan Peso + /// - `UYP` - Uruguayan Peso (1975–1993) + /// - `UYI` - Uruguayan Peso (Indexed Units) + /// - `UZS` - Uzbekistani Som + /// - `VUV` - Vanuatu Vatu + /// - `VES` - Venezuelan Bolívar + /// - `VEB` - Venezuelan Bolívar (1871–2008) + /// - `VEF` - Venezuelan Bolívar (2008–2018) + /// - `VND` - Vietnamese Dong + /// - `VNN` - Vietnamese Dong (1978–1985) + /// - `CHE` - WIR Euro + /// - `CHW` - WIR Franc + /// - `XOF` - West African CFA Franc + /// - `YDD` - Yemeni Dinar + /// - `YER` - Yemeni Rial + /// - `YUN` - Yugoslavian Convertible Dinar (1990–1992) + /// - `YUD` - Yugoslavian Hard Dinar (1966–1990) + /// - `YUM` - Yugoslavian New Dinar (1994–2002) + /// - `YUR` - Yugoslavian Reformed Dinar (1992–1993) + /// - `ZWN` - ZWN + /// - `ZRN` - Zairean New Zaire (1993–1998) + /// - `ZRZ` - Zairean Zaire (1971–1993) + /// - `ZMW` - Zambian Kwacha + /// - `ZMK` - Zambian Kwacha (1968–2012) + /// - `ZWD` - Zimbabwean Dollar (1980–2008) + /// - `ZWR` - Zimbabwean Dollar (2008) + /// - `ZWL` - Zimbabwean Dollar (2009) + /// + [JsonPropertyName("currency")] + public CurrencyEnum? Currency { get; init; } + + /// + /// The payment's exchange rate. + /// + [JsonPropertyName("exchange_rate")] + public string? ExchangeRate { get; init; } + + /// + /// The company the payment belongs to. + /// + [JsonPropertyName("company")] + public OneOf? Company { get; init; } + + /// + /// The total amount of money being paid to the supplier, or customer, after taxes. + /// + [JsonPropertyName("total_amount")] + public double? TotalAmount { get; init; } + + [JsonPropertyName("tracking_categories")] + public List?>? TrackingCategories { get; init; } + + /// + /// The accounting period that the Payment was generated in. + /// + [JsonPropertyName("accounting_period")] + public OneOf? AccountingPeriod { get; init; } + + /// + /// A list of “Payment Applied to Lines” objects. + /// + [JsonPropertyName("applied_to_lines")] + public List>? AppliedToLines { get; init; } + + [JsonPropertyName("integration_params")] + public Dictionary? IntegrationParams { get; init; } + + [JsonPropertyName("linked_account_params")] + public Dictionary? LinkedAccountParams { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/Payment.cs b/src/Merge.Client/Accounting/Types/Payment.cs index e319d7ce..05733707 100644 --- a/src/Merge.Client/Accounting/Types/Payment.cs +++ b/src/Merge.Client/Accounting/Types/Payment.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -15,6 +15,15 @@ public class Payment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The payment's transaction date. /// @@ -35,7 +44,7 @@ public class Payment /// /// The payment's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -391,15 +400,6 @@ public class Payment [JsonPropertyName("applied_to_lines")] public List>? AppliedToLines { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/PaymentLineItem.cs b/src/Merge.Client/Accounting/Types/PaymentLineItem.cs index 4f3bdeee..3f3844d4 100644 --- a/src/Merge.Client/Accounting/Types/PaymentLineItem.cs +++ b/src/Merge.Client/Accounting/Types/PaymentLineItem.cs @@ -4,6 +4,24 @@ namespace Merge.Client.Accounting; public class PaymentLineItem { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The amount being applied to the transaction. /// @@ -16,12 +34,6 @@ public class PaymentLineItem [JsonPropertyName("applied_date")] public DateTime? AppliedDate { get; init; } - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - /// /// The Merge ID of the transaction the payment portion is being applied to. /// @@ -33,16 +45,4 @@ public class PaymentLineItem /// [JsonPropertyName("related_object_type")] public string? RelatedObjectType { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/PaymentLineItemRequest.cs b/src/Merge.Client/Accounting/Types/PaymentLineItemRequest.cs index 6eac47c2..948f7271 100644 --- a/src/Merge.Client/Accounting/Types/PaymentLineItemRequest.cs +++ b/src/Merge.Client/Accounting/Types/PaymentLineItemRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Accounting; public class PaymentLineItemRequest { + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + /// /// The amount being applied to the transaction. /// @@ -16,12 +22,6 @@ public class PaymentLineItemRequest [JsonPropertyName("applied_date")] public DateTime? AppliedDate { get; init; } - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - /// /// The Merge ID of the transaction the payment portion is being applied to. /// diff --git a/src/Merge.Client/Accounting/Types/PaymentRequest.cs b/src/Merge.Client/Accounting/Types/PaymentRequest.cs index 0f935721..fc1abb24 100644 --- a/src/Merge.Client/Accounting/Types/PaymentRequest.cs +++ b/src/Merge.Client/Accounting/Types/PaymentRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -26,7 +26,7 @@ public class PaymentRequest /// /// The payment's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/PurchaseOrder.cs b/src/Merge.Client/Accounting/Types/PurchaseOrder.cs index 8f601267..90c44294 100644 --- a/src/Merge.Client/Accounting/Types/PurchaseOrder.cs +++ b/src/Merge.Client/Accounting/Types/PurchaseOrder.cs @@ -6,9 +6,27 @@ namespace Merge.Client.Accounting; public class PurchaseOrder { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The purchase order's status. - /// + /// /// - `DRAFT` - DRAFT /// - `SUBMITTED` - SUBMITTED /// - `AUTHORIZED` - AUTHORIZED @@ -74,7 +92,7 @@ public class PurchaseOrder /// /// The purchase order's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -421,24 +439,6 @@ public class PurchaseOrder [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/PurchaseOrderLineItem.cs b/src/Merge.Client/Accounting/Types/PurchaseOrderLineItem.cs index d039fc9d..1e8abb58 100644 --- a/src/Merge.Client/Accounting/Types/PurchaseOrderLineItem.cs +++ b/src/Merge.Client/Accounting/Types/PurchaseOrderLineItem.cs @@ -1,17 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class PurchaseOrderLineItem { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// A description of the good being purchased. /// @@ -65,7 +77,7 @@ public class PurchaseOrderLineItem /// /// The purchase order line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -393,16 +405,4 @@ public class PurchaseOrderLineItem /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/PurchaseOrderLineItemRequest.cs b/src/Merge.Client/Accounting/Types/PurchaseOrderLineItemRequest.cs index fff1fb3d..edd8d79d 100644 --- a/src/Merge.Client/Accounting/Types/PurchaseOrderLineItemRequest.cs +++ b/src/Merge.Client/Accounting/Types/PurchaseOrderLineItemRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -65,7 +65,7 @@ public class PurchaseOrderLineItemRequest /// /// The purchase order line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/PurchaseOrderRequest.cs b/src/Merge.Client/Accounting/Types/PurchaseOrderRequest.cs index f95b8800..b68e1fa1 100644 --- a/src/Merge.Client/Accounting/Types/PurchaseOrderRequest.cs +++ b/src/Merge.Client/Accounting/Types/PurchaseOrderRequest.cs @@ -8,7 +8,7 @@ public class PurchaseOrderRequest { /// /// The purchase order's status. - /// + /// /// - `DRAFT` - DRAFT /// - `SUBMITTED` - SUBMITTED /// - `AUTHORIZED` - AUTHORIZED @@ -68,7 +68,7 @@ public class PurchaseOrderRequest /// /// The purchase order's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) diff --git a/src/Merge.Client/Accounting/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Accounting/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..d82ebc20 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Accounting; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/RemoteFieldApi.cs b/src/Merge.Client/Accounting/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..9c466df8 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Accounting/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..ab697e98 --- /dev/null +++ b/src/Merge.Client/Accounting/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Serialization; +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("AccountingAttachment")] + public List? AccountingAttachment { get; init; } + + [JsonPropertyName("BalanceSheet")] + public List? BalanceSheet { get; init; } + + [JsonPropertyName("CashFlowStatement")] + public List? CashFlowStatement { get; init; } + + [JsonPropertyName("CompanyInfo")] + public List? CompanyInfo { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("IncomeStatement")] + public List? IncomeStatement { get; init; } + + [JsonPropertyName("CreditNote")] + public List? CreditNote { get; init; } + + [JsonPropertyName("Item")] + public List? Item { get; init; } + + [JsonPropertyName("PurchaseOrder")] + public List? PurchaseOrder { get; init; } + + [JsonPropertyName("TrackingCategory")] + public List? TrackingCategory { get; init; } + + [JsonPropertyName("JournalEntry")] + public List? JournalEntry { get; init; } + + [JsonPropertyName("TaxRate")] + public List? TaxRate { get; init; } + + [JsonPropertyName("Invoice")] + public List? Invoice { get; init; } + + [JsonPropertyName("Payment")] + public List? Payment { get; init; } + + [JsonPropertyName("Expense")] + public List? Expense { get; init; } + + [JsonPropertyName("VendorCredit")] + public List? VendorCredit { get; init; } + + [JsonPropertyName("Transaction")] + public List? Transaction { get; init; } + + [JsonPropertyName("GeneralLedgerTransaction")] + public List? GeneralLedgerTransaction { get; init; } +} diff --git a/src/Merge.Client/Accounting/Types/ReportItem.cs b/src/Merge.Client/Accounting/Types/ReportItem.cs index 262fa885..22f127e6 100644 --- a/src/Merge.Client/Accounting/Types/ReportItem.cs +++ b/src/Merge.Client/Accounting/Types/ReportItem.cs @@ -10,6 +10,15 @@ public class ReportItem [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The report item's name. /// @@ -30,13 +39,4 @@ public class ReportItem /// [JsonPropertyName("company")] public string? Company { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/TaxRate.cs b/src/Merge.Client/Accounting/Types/TaxRate.cs index 2be7a01e..ea8a5d1c 100644 --- a/src/Merge.Client/Accounting/Types/TaxRate.cs +++ b/src/Merge.Client/Accounting/Types/TaxRate.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class TaxRate { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The tax rate's description. /// @@ -36,24 +54,6 @@ public class TaxRate [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/TrackingCategory.cs b/src/Merge.Client/Accounting/Types/TrackingCategory.cs index 4f833e62..05bc13a0 100644 --- a/src/Merge.Client/Accounting/Types/TrackingCategory.cs +++ b/src/Merge.Client/Accounting/Types/TrackingCategory.cs @@ -6,6 +6,24 @@ namespace Merge.Client.Accounting; public class TrackingCategory { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The tracking category's name. /// @@ -14,7 +32,7 @@ public class TrackingCategory /// /// The tracking category's status. - /// + /// /// - `ACTIVE` - ACTIVE /// - `ARCHIVED` - ARCHIVED /// @@ -23,7 +41,7 @@ public class TrackingCategory /// /// The tracking category’s type. - /// + /// /// - `CLASS` - CLASS /// - `DEPARTMENT` - DEPARTMENT /// @@ -48,24 +66,6 @@ public class TrackingCategory [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/Transaction.cs b/src/Merge.Client/Accounting/Types/Transaction.cs index ac1be8e5..e00601b8 100644 --- a/src/Merge.Client/Accounting/Types/Transaction.cs +++ b/src/Merge.Client/Accounting/Types/Transaction.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class Transaction { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The type of transaction, which can by any transaction object not already included in Merge’s common model. /// @@ -44,7 +62,7 @@ public class Transaction /// /// The transaction's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -385,24 +403,6 @@ public class Transaction [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/TransactionLineItem.cs b/src/Merge.Client/Accounting/Types/TransactionLineItem.cs index 87d83a36..96957818 100644 --- a/src/Merge.Client/Accounting/Types/TransactionLineItem.cs +++ b/src/Merge.Client/Accounting/Types/TransactionLineItem.cs @@ -1,17 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class TransactionLineItem { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// An internal note used by the business to clarify purpose of the transaction. /// @@ -65,7 +77,7 @@ public class TransactionLineItem /// /// The line item's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -393,16 +405,4 @@ public class TransactionLineItem /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/Types/VendorCredit.cs b/src/Merge.Client/Accounting/Types/VendorCredit.cs index 3db9098e..95678ad4 100644 --- a/src/Merge.Client/Accounting/Types/VendorCredit.cs +++ b/src/Merge.Client/Accounting/Types/VendorCredit.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; @@ -15,6 +15,15 @@ public class VendorCredit [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The vendor credit's number. /// @@ -41,7 +50,7 @@ public class VendorCredit /// /// The vendor credit's currency. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -382,15 +391,6 @@ public class VendorCredit [JsonPropertyName("accounting_period")] public OneOf? AccountingPeriod { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Accounting/Types/VendorCreditLine.cs b/src/Merge.Client/Accounting/Types/VendorCreditLine.cs index f6320d9c..77c01e5a 100644 --- a/src/Merge.Client/Accounting/Types/VendorCreditLine.cs +++ b/src/Merge.Client/Accounting/Types/VendorCreditLine.cs @@ -1,17 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Accounting; +using OneOf; namespace Merge.Client.Accounting; public class VendorCreditLine { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The full value of the credit. /// @@ -59,16 +71,4 @@ public class VendorCreditLine /// [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Accounting/VendorCredits/VendorCreditsClient.cs b/src/Merge.Client/Accounting/VendorCredits/VendorCreditsClient.cs index e8d2aef4..458b28a9 100644 --- a/src/Merge.Client/Accounting/VendorCredits/VendorCreditsClient.cs +++ b/src/Merge.Client/Accounting/VendorCredits/VendorCreditsClient.cs @@ -1,9 +1,119 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class VendorCreditsClient { - public async void List(){ + private RawClient _client; + + public VendorCreditsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `VendorCredit` objects. + /// + public async Task ListAsync(VendorCreditsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TransactionDateAfter != null) + { + _query["transaction_date_after"] = request.TransactionDateAfter; + } + if (request.TransactionDateBefore != null) + { + _query["transaction_date_before"] = request.TransactionDateBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/vendor-credits", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `VendorCredit` object with the given `id`. + /// + public async Task RetrieveAsync(string id, VendorCreditsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/accounting/v1/vendor-credits/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsListRequest.cs b/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsListRequest.cs new file mode 100644 index 00000000..21305713 --- /dev/null +++ b/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class VendorCreditsListRequest +{ + /// + /// If provided, will only return vendor credits for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public VendorCreditsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? TransactionDateAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? TransactionDateBefore { get; init; } +} diff --git a/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsRetrieveRequest.cs b/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsRetrieveRequest.cs new file mode 100644 index 00000000..bd87f772 --- /dev/null +++ b/src/Merge.Client/Accounting/VendorCredits/requests/VendorCreditsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Accounting; + +namespace Merge.Client.Accounting; + +public class VendorCreditsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public VendorCreditsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Accounting/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Accounting/WebhookReceivers/WebhookReceiversClient.cs index 76d1c8d8..9c15ebf0 100644 --- a/src/Merge.Client/Accounting/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Accounting/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Accounting; + namespace Merge.Client.Accounting; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/accounting/v1/webhook-receivers" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/accounting/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Accounting/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Accounting/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..87d024d8 --- /dev/null +++ b/src/Merge.Client/Accounting/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Accounting; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +} diff --git a/src/Merge.Client/Ats/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Ats/AccountDetails/AccountDetailsClient.cs index 4d9fd3b5..802cf1a0 100644 --- a/src/Merge.Client/Ats/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Ats/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,31 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/account-details" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Ats/AccountToken/AccountTokenClient.cs index f9d0e50f..663f43d2 100644 --- a/src/Merge.Client/Ats/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Ats/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Activities/ActivitiesClient.cs b/src/Merge.Client/Ats/Activities/ActivitiesClient.cs index 1d4c3b13..88505628 100644 --- a/src/Merge.Client/Ats/Activities/ActivitiesClient.cs +++ b/src/Merge.Client/Ats/Activities/ActivitiesClient.cs @@ -1,13 +1,177 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class ActivitiesClient { - public async void List(){ + private RawClient _client; + + public ActivitiesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Activity` objects. + /// + public async Task ListAsync(ActivitiesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.UserId != null) + { + _query["user_id"] = request.UserId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/activities", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates an `Activity` object with the given values. + /// + public async Task CreateAsync(ActivityEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/activities", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns an `Activity` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ActivitiesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/activities/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Activity` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/activities/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Activities/requests/ActivitiesListRequest.cs b/src/Merge.Client/Ats/Activities/requests/ActivitiesListRequest.cs new file mode 100644 index 00000000..c020009b --- /dev/null +++ b/src/Merge.Client/Ats/Activities/requests/ActivitiesListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ActivitiesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public ActivitiesListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public ActivitiesListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return activities done by this user. + /// + public string? UserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Activities/requests/ActivitiesRetrieveRequest.cs b/src/Merge.Client/Ats/Activities/requests/ActivitiesRetrieveRequest.cs new file mode 100644 index 00000000..a59223ca --- /dev/null +++ b/src/Merge.Client/Ats/Activities/requests/ActivitiesRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ActivitiesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public ActivitiesRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public ActivitiesRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Activities/requests/ActivityEndpointRequest.cs b/src/Merge.Client/Ats/Activities/requests/ActivityEndpointRequest.cs new file mode 100644 index 00000000..6bb6ce06 --- /dev/null +++ b/src/Merge.Client/Ats/Activities/requests/ActivityEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ActivityEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ActivityRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Applications/ApplicationsClient.cs b/src/Merge.Client/Ats/Applications/ApplicationsClient.cs index 04d0b0a1..4a302aa2 100644 --- a/src/Merge.Client/Ats/Applications/ApplicationsClient.cs +++ b/src/Merge.Client/Ats/Applications/ApplicationsClient.cs @@ -1,15 +1,222 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class ApplicationsClient { - public async void List(){ + private RawClient _client; + + public ApplicationsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Application` objects. + /// + public async Task ListAsync(ApplicationsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CandidateId != null) + { + _query["candidate_id"] = request.CandidateId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.CreditedToId != null) + { + _query["credited_to_id"] = request.CreditedToId; + } + if (request.CurrentStageId != null) + { + _query["current_stage_id"] = request.CurrentStageId; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.JobId != null) + { + _query["job_id"] = request.JobId; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RejectReasonId != null) + { + _query["reject_reason_id"] = request.RejectReasonId; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.Source != null) + { + _query["source"] = request.Source; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/applications", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates an `Application` object with the given values. + /// + public async Task CreateAsync(ApplicationEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/applications", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Application` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ApplicationsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/applications/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void ChangeStageCreate(){ + + /// + /// Updates the `current_stage` field of an `Application` object + /// + public async Task ChangeStageCreateAsync( + string id, + UpdateApplicationStageRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/ats/v1/applications/{id}/change-stage", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Application` POSTs. + /// + public async Task MetaPostRetrieveAsync( + ApplicationsMetaPostRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.ApplicationRemoteTemplateId != null) + { + _query["application_remote_template_id"] = request.ApplicationRemoteTemplateId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/applications/meta/post", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Applications/Types/ApplicationsListRequestExpand.cs b/src/Merge.Client/Ats/Applications/Types/ApplicationsListRequestExpand.cs index a07020dc..4da3cca5 100644 --- a/src/Merge.Client/Ats/Applications/Types/ApplicationsListRequestExpand.cs +++ b/src/Merge.Client/Ats/Applications/Types/ApplicationsListRequestExpand.cs @@ -94,6 +94,102 @@ public enum ApplicationsListRequestExpand [EnumMember(Value = "job,reject_reason")] JobRejectReason, + [EnumMember(Value = "offers")] + Offers, + + [EnumMember(Value = "offers,candidate")] + OffersCandidate, + + [EnumMember(Value = "offers,candidate,credited_to")] + OffersCandidateCreditedTo, + + [EnumMember(Value = "offers,candidate,credited_to,current_stage")] + OffersCandidateCreditedToCurrentStage, + + [EnumMember(Value = "offers,candidate,credited_to,current_stage,reject_reason")] + OffersCandidateCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,credited_to,reject_reason")] + OffersCandidateCreditedToRejectReason, + + [EnumMember(Value = "offers,candidate,current_stage")] + OffersCandidateCurrentStage, + + [EnumMember(Value = "offers,candidate,current_stage,reject_reason")] + OffersCandidateCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job")] + OffersCandidateJob, + + [EnumMember(Value = "offers,candidate,job,credited_to")] + OffersCandidateJobCreditedTo, + + [EnumMember(Value = "offers,candidate,job,credited_to,current_stage")] + OffersCandidateJobCreditedToCurrentStage, + + [EnumMember(Value = "offers,candidate,job,credited_to,current_stage,reject_reason")] + OffersCandidateJobCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job,credited_to,reject_reason")] + OffersCandidateJobCreditedToRejectReason, + + [EnumMember(Value = "offers,candidate,job,current_stage")] + OffersCandidateJobCurrentStage, + + [EnumMember(Value = "offers,candidate,job,current_stage,reject_reason")] + OffersCandidateJobCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job,reject_reason")] + OffersCandidateJobRejectReason, + + [EnumMember(Value = "offers,candidate,reject_reason")] + OffersCandidateRejectReason, + + [EnumMember(Value = "offers,credited_to")] + OffersCreditedTo, + + [EnumMember(Value = "offers,credited_to,current_stage")] + OffersCreditedToCurrentStage, + + [EnumMember(Value = "offers,credited_to,current_stage,reject_reason")] + OffersCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,credited_to,reject_reason")] + OffersCreditedToRejectReason, + + [EnumMember(Value = "offers,current_stage")] + OffersCurrentStage, + + [EnumMember(Value = "offers,current_stage,reject_reason")] + OffersCurrentStageRejectReason, + + [EnumMember(Value = "offers,job")] + OffersJob, + + [EnumMember(Value = "offers,job,credited_to")] + OffersJobCreditedTo, + + [EnumMember(Value = "offers,job,credited_to,current_stage")] + OffersJobCreditedToCurrentStage, + + [EnumMember(Value = "offers,job,credited_to,current_stage,reject_reason")] + OffersJobCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,job,credited_to,reject_reason")] + OffersJobCreditedToRejectReason, + + [EnumMember(Value = "offers,job,current_stage")] + OffersJobCurrentStage, + + [EnumMember(Value = "offers,job,current_stage,reject_reason")] + OffersJobCurrentStageRejectReason, + + [EnumMember(Value = "offers,job,reject_reason")] + OffersJobRejectReason, + + [EnumMember(Value = "offers,reject_reason")] + OffersRejectReason, + [EnumMember(Value = "reject_reason")] RejectReason } diff --git a/src/Merge.Client/Ats/Applications/Types/ApplicationsRetrieveRequestExpand.cs b/src/Merge.Client/Ats/Applications/Types/ApplicationsRetrieveRequestExpand.cs index d5bd6c31..dfc676ce 100644 --- a/src/Merge.Client/Ats/Applications/Types/ApplicationsRetrieveRequestExpand.cs +++ b/src/Merge.Client/Ats/Applications/Types/ApplicationsRetrieveRequestExpand.cs @@ -94,6 +94,102 @@ public enum ApplicationsRetrieveRequestExpand [EnumMember(Value = "job,reject_reason")] JobRejectReason, + [EnumMember(Value = "offers")] + Offers, + + [EnumMember(Value = "offers,candidate")] + OffersCandidate, + + [EnumMember(Value = "offers,candidate,credited_to")] + OffersCandidateCreditedTo, + + [EnumMember(Value = "offers,candidate,credited_to,current_stage")] + OffersCandidateCreditedToCurrentStage, + + [EnumMember(Value = "offers,candidate,credited_to,current_stage,reject_reason")] + OffersCandidateCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,credited_to,reject_reason")] + OffersCandidateCreditedToRejectReason, + + [EnumMember(Value = "offers,candidate,current_stage")] + OffersCandidateCurrentStage, + + [EnumMember(Value = "offers,candidate,current_stage,reject_reason")] + OffersCandidateCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job")] + OffersCandidateJob, + + [EnumMember(Value = "offers,candidate,job,credited_to")] + OffersCandidateJobCreditedTo, + + [EnumMember(Value = "offers,candidate,job,credited_to,current_stage")] + OffersCandidateJobCreditedToCurrentStage, + + [EnumMember(Value = "offers,candidate,job,credited_to,current_stage,reject_reason")] + OffersCandidateJobCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job,credited_to,reject_reason")] + OffersCandidateJobCreditedToRejectReason, + + [EnumMember(Value = "offers,candidate,job,current_stage")] + OffersCandidateJobCurrentStage, + + [EnumMember(Value = "offers,candidate,job,current_stage,reject_reason")] + OffersCandidateJobCurrentStageRejectReason, + + [EnumMember(Value = "offers,candidate,job,reject_reason")] + OffersCandidateJobRejectReason, + + [EnumMember(Value = "offers,candidate,reject_reason")] + OffersCandidateRejectReason, + + [EnumMember(Value = "offers,credited_to")] + OffersCreditedTo, + + [EnumMember(Value = "offers,credited_to,current_stage")] + OffersCreditedToCurrentStage, + + [EnumMember(Value = "offers,credited_to,current_stage,reject_reason")] + OffersCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,credited_to,reject_reason")] + OffersCreditedToRejectReason, + + [EnumMember(Value = "offers,current_stage")] + OffersCurrentStage, + + [EnumMember(Value = "offers,current_stage,reject_reason")] + OffersCurrentStageRejectReason, + + [EnumMember(Value = "offers,job")] + OffersJob, + + [EnumMember(Value = "offers,job,credited_to")] + OffersJobCreditedTo, + + [EnumMember(Value = "offers,job,credited_to,current_stage")] + OffersJobCreditedToCurrentStage, + + [EnumMember(Value = "offers,job,credited_to,current_stage,reject_reason")] + OffersJobCreditedToCurrentStageRejectReason, + + [EnumMember(Value = "offers,job,credited_to,reject_reason")] + OffersJobCreditedToRejectReason, + + [EnumMember(Value = "offers,job,current_stage")] + OffersJobCurrentStage, + + [EnumMember(Value = "offers,job,current_stage,reject_reason")] + OffersJobCurrentStageRejectReason, + + [EnumMember(Value = "offers,job,reject_reason")] + OffersJobRejectReason, + + [EnumMember(Value = "offers,reject_reason")] + OffersRejectReason, + [EnumMember(Value = "reject_reason")] RejectReason } diff --git a/src/Merge.Client/Ats/Applications/requests/ApplicationEndpointRequest.cs b/src/Merge.Client/Ats/Applications/requests/ApplicationEndpointRequest.cs new file mode 100644 index 00000000..58c5d9bb --- /dev/null +++ b/src/Merge.Client/Ats/Applications/requests/ApplicationEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ApplicationEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ApplicationRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Applications/requests/ApplicationsListRequest.cs b/src/Merge.Client/Ats/Applications/requests/ApplicationsListRequest.cs new file mode 100644 index 00000000..7a59e42c --- /dev/null +++ b/src/Merge.Client/Ats/Applications/requests/ApplicationsListRequest.cs @@ -0,0 +1,86 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ApplicationsListRequest +{ + /// + /// If provided, will only return applications for this candidate. + /// + public string? CandidateId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// If provided, will only return applications credited to this user. + /// + public string? CreditedToId { get; init; } + + /// + /// If provided, will only return applications at this interview stage. + /// + public string? CurrentStageId { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ApplicationsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return applications for this job. + /// + public string? JobId { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return applications with this reject reason. + /// + public string? RejectReasonId { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return applications with this source. + /// + public string? Source { get; init; } +} diff --git a/src/Merge.Client/Ats/Applications/requests/ApplicationsMetaPostRetrieveRequest.cs b/src/Merge.Client/Ats/Applications/requests/ApplicationsMetaPostRetrieveRequest.cs new file mode 100644 index 00000000..13a6bc07 --- /dev/null +++ b/src/Merge.Client/Ats/Applications/requests/ApplicationsMetaPostRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class ApplicationsMetaPostRetrieveRequest +{ + /// + /// The template ID associated with the nested application in the request. + /// + public string? ApplicationRemoteTemplateId { get; init; } +} diff --git a/src/Merge.Client/Ats/Applications/requests/ApplicationsRetrieveRequest.cs b/src/Merge.Client/Ats/Applications/requests/ApplicationsRetrieveRequest.cs new file mode 100644 index 00000000..b44123fb --- /dev/null +++ b/src/Merge.Client/Ats/Applications/requests/ApplicationsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ApplicationsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ApplicationsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Applications/requests/UpdateApplicationStageRequest.cs b/src/Merge.Client/Ats/Applications/requests/UpdateApplicationStageRequest.cs new file mode 100644 index 00000000..fa943677 --- /dev/null +++ b/src/Merge.Client/Ats/Applications/requests/UpdateApplicationStageRequest.cs @@ -0,0 +1,21 @@ +namespace Merge.Client.Ats; + +public class UpdateApplicationStageRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + /// + /// The interview stage to move the application to. + /// + public string? JobInterviewStage { get; init; } + + public string? RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Ats/AsyncPassthrough/AsyncPassthroughClient.cs index 3aa8a511..28a5fc89 100644 --- a/src/Merge.Client/Ats/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Ats/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/AtsClient.cs b/src/Merge.Client/Ats/AtsClient.cs new file mode 100644 index 00000000..b237c8eb --- /dev/null +++ b/src/Merge.Client/Ats/AtsClient.cs @@ -0,0 +1,116 @@ +using Merge.Client; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class AtsClient +{ + private RawClient _client; + + public AtsClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + Activities = new ActivitiesClient(_client); + Applications = new ApplicationsClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + Attachments = new AttachmentsClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + Candidates = new CandidatesClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + Departments = new DepartmentsClient(_client); + Eeocs = new EeocsClient(_client); + FieldMapping = new FieldMappingClient(_client); + GenerateKey = new GenerateKeyClient(_client); + Interviews = new InterviewsClient(_client); + Issues = new IssuesClient(_client); + JobInterviewStages = new JobInterviewStagesClient(_client); + JobPostings = new JobPostingsClient(_client); + Jobs = new JobsClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Offers = new OffersClient(_client); + Offices = new OfficesClient(_client); + Passthrough = new PassthroughClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + RejectReasons = new RejectReasonsClient(_client); + Scorecards = new ScorecardsClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + Tags = new TagsClient(_client); + Users = new UsersClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public ActivitiesClient Activities { get; } + + public ApplicationsClient Applications { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AttachmentsClient Attachments { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public CandidatesClient Candidates { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public DepartmentsClient Departments { get; } + + public EeocsClient Eeocs { get; } + + public FieldMappingClient FieldMapping { get; } + + public GenerateKeyClient GenerateKey { get; } + + public InterviewsClient Interviews { get; } + + public IssuesClient Issues { get; } + + public JobInterviewStagesClient JobInterviewStages { get; } + + public JobPostingsClient JobPostings { get; } + + public JobsClient Jobs { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public OffersClient Offers { get; } + + public OfficesClient Offices { get; } + + public PassthroughClient Passthrough { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public RejectReasonsClient RejectReasons { get; } + + public ScorecardsClient Scorecards { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public TagsClient Tags { get; } + + public UsersClient Users { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Ats/Attachments/AttachmentsClient.cs b/src/Merge.Client/Ats/Attachments/AttachmentsClient.cs index fda6bc72..16a938d5 100644 --- a/src/Merge.Client/Ats/Attachments/AttachmentsClient.cs +++ b/src/Merge.Client/Ats/Attachments/AttachmentsClient.cs @@ -1,13 +1,177 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AttachmentsClient { - public async void List(){ + private RawClient _client; + + public AttachmentsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Attachment` objects. + /// + public async Task ListAsync(AttachmentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CandidateId != null) + { + _query["candidate_id"] = request.CandidateId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates an `Attachment` object with the given values. + /// + public async Task CreateAsync(AttachmentEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns an `Attachment` object with the given `id`. + /// + public async Task RetrieveAsync(string id, AttachmentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/attachments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Attachment` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/attachments/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Attachments/requests/AttachmentEndpointRequest.cs b/src/Merge.Client/Ats/Attachments/requests/AttachmentEndpointRequest.cs new file mode 100644 index 00000000..062b1a27 --- /dev/null +++ b/src/Merge.Client/Ats/Attachments/requests/AttachmentEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class AttachmentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AttachmentRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Attachments/requests/AttachmentsListRequest.cs b/src/Merge.Client/Ats/Attachments/requests/AttachmentsListRequest.cs new file mode 100644 index 00000000..c20006bc --- /dev/null +++ b/src/Merge.Client/Ats/Attachments/requests/AttachmentsListRequest.cs @@ -0,0 +1,69 @@ +namespace Merge.Client.Ats; + +public class AttachmentsListRequest +{ + /// + /// If provided, will only return attachments for this candidate. + /// + public string? CandidateId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Attachments/requests/AttachmentsRetrieveRequest.cs b/src/Merge.Client/Ats/Attachments/requests/AttachmentsRetrieveRequest.cs new file mode 100644 index 00000000..b19a43be --- /dev/null +++ b/src/Merge.Client/Ats/Attachments/requests/AttachmentsRetrieveRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Ats; + +public class AttachmentsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Ats/AuditTrail/AuditTrailClient.cs index c9a8561d..2381f0fd 100644 --- a/src/Merge.Client/Ats/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Ats/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Ats/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..0e8f41eb --- /dev/null +++ b/src/Merge.Client/Ats/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Ats; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Ats/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Ats/AvailableActions/AvailableActionsClient.cs index d2486a44..814bc946 100644 --- a/src/Merge.Client/Ats/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Ats/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,31 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/available-actions" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Candidates/CandidatesClient.cs b/src/Merge.Client/Ats/Candidates/CandidatesClient.cs index 5e79a21e..4c38fded 100644 --- a/src/Merge.Client/Ats/Candidates/CandidatesClient.cs +++ b/src/Merge.Client/Ats/Candidates/CandidatesClient.cs @@ -1,19 +1,241 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class CandidatesClient { - public async void List(){ + private RawClient _client; + + public CandidatesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Candidate` objects. + /// + public async Task ListAsync(CandidatesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmailAddresses != null) + { + _query["email_addresses"] = request.EmailAddresses; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.FirstName != null) + { + _query["first_name"] = request.FirstName; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.LastName != null) + { + _query["last_name"] = request.LastName; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.Tags != null) + { + _query["tags"] = request.Tags; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/candidates", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `Candidate` object with the given values. + /// + public async Task CreateAsync(CandidateEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/candidates", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Candidate` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CandidatesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/candidates/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Updates a `Candidate` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedCandidateEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/ats/v1/candidates/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void IgnoreCreate(){ + + /// + /// Ignores a specific row based on the `model_id` in the url. These records will have their properties set to null, and will not be updated in future syncs. The "reason" and "message" fields in the request body will be stored for audit purposes. + /// + public async void IgnoreCreateAsync(string modelId, IgnoreCommonModelRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/ats/v1/candidates/ignore/{modelId}", + Body = request + } + ); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns metadata for `Candidate` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/candidates/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Candidate` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/candidates/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Candidates/requests/CandidateEndpointRequest.cs b/src/Merge.Client/Ats/Candidates/requests/CandidateEndpointRequest.cs new file mode 100644 index 00000000..99780189 --- /dev/null +++ b/src/Merge.Client/Ats/Candidates/requests/CandidateEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class CandidateEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public CandidateRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Candidates/requests/CandidatesListRequest.cs b/src/Merge.Client/Ats/Candidates/requests/CandidatesListRequest.cs new file mode 100644 index 00000000..dc4d9a40 --- /dev/null +++ b/src/Merge.Client/Ats/Candidates/requests/CandidatesListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class CandidatesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return candidates with these email addresses; multiple addresses can be separated by commas. + /// + public string? EmailAddresses { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CandidatesListRequestExpand? Expand { get; init; } + + /// + /// If provided, will only return candidates with this first name. + /// + public string? FirstName { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return candidates with this last name. + /// + public string? LastName { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return candidates with these tags; multiple tags can be separated by commas. + /// + public string? Tags { get; init; } +} diff --git a/src/Merge.Client/Ats/Candidates/requests/CandidatesRetrieveRequest.cs b/src/Merge.Client/Ats/Candidates/requests/CandidatesRetrieveRequest.cs new file mode 100644 index 00000000..c041c4e6 --- /dev/null +++ b/src/Merge.Client/Ats/Candidates/requests/CandidatesRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class CandidatesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CandidatesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Candidates/requests/IgnoreCommonModelRequest.cs b/src/Merge.Client/Ats/Candidates/requests/IgnoreCommonModelRequest.cs new file mode 100644 index 00000000..94e0fc78 --- /dev/null +++ b/src/Merge.Client/Ats/Candidates/requests/IgnoreCommonModelRequest.cs @@ -0,0 +1,10 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class IgnoreCommonModelRequest +{ + public ReasonEnum Reason { get; init; } + + public string? Message { get; init; } +} diff --git a/src/Merge.Client/Ats/Candidates/requests/PatchedCandidateEndpointRequest.cs b/src/Merge.Client/Ats/Candidates/requests/PatchedCandidateEndpointRequest.cs new file mode 100644 index 00000000..b2938ced --- /dev/null +++ b/src/Merge.Client/Ats/Candidates/requests/PatchedCandidateEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class PatchedCandidateEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedCandidateRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Ats/DeleteAccount/DeleteAccountClient.cs index 2ef43ec0..94047ff8 100644 --- a/src/Merge.Client/Ats/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Ats/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,23 @@ +using Merge.Client; + namespace Merge.Client.Ats; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Post, Path = "/ats/v1/delete-account" } + ); } } diff --git a/src/Merge.Client/Ats/Departments/DepartmentsClient.cs b/src/Merge.Client/Ats/Departments/DepartmentsClient.cs index 6c7cdbbf..a62226d2 100644 --- a/src/Merge.Client/Ats/Departments/DepartmentsClient.cs +++ b/src/Merge.Client/Ats/Departments/DepartmentsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class DepartmentsClient { - public async void List(){ + private RawClient _client; + + public DepartmentsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Department` objects. + /// + public async Task ListAsync(DepartmentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/departments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Department` object with the given `id`. + /// + public async Task RetrieveAsync(string id, DepartmentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/departments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Departments/requests/DepartmentsListRequest.cs b/src/Merge.Client/Ats/Departments/requests/DepartmentsListRequest.cs new file mode 100644 index 00000000..ba89c818 --- /dev/null +++ b/src/Merge.Client/Ats/Departments/requests/DepartmentsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ats; + +public class DepartmentsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ats/Departments/requests/DepartmentsRetrieveRequest.cs b/src/Merge.Client/Ats/Departments/requests/DepartmentsRetrieveRequest.cs new file mode 100644 index 00000000..a7b83539 --- /dev/null +++ b/src/Merge.Client/Ats/Departments/requests/DepartmentsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class DepartmentsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Eeocs/EeocsClient.cs b/src/Merge.Client/Ats/Eeocs/EeocsClient.cs index f25fc231..9e1652ce 100644 --- a/src/Merge.Client/Ats/Eeocs/EeocsClient.cs +++ b/src/Merge.Client/Ats/Eeocs/EeocsClient.cs @@ -1,9 +1,127 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class EeocsClient { - public async void List(){ + private RawClient _client; + + public EeocsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `EEOC` objects. + /// + public async Task ListAsync(EeocsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CandidateId != null) + { + _query["candidate_id"] = request.CandidateId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/eeocs", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `EEOC` object with the given `id`. + /// + public async Task RetrieveAsync(string id, EeocsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/eeocs/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Eeocs/requests/EeocsListRequest.cs b/src/Merge.Client/Ats/Eeocs/requests/EeocsListRequest.cs new file mode 100644 index 00000000..5c0ad910 --- /dev/null +++ b/src/Merge.Client/Ats/Eeocs/requests/EeocsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class EeocsListRequest +{ + /// + /// If provided, will only return EEOC info for this candidate. + /// + public string? CandidateId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EeocsListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EeocsListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Eeocs/requests/EeocsRetrieveRequest.cs b/src/Merge.Client/Ats/Eeocs/requests/EeocsRetrieveRequest.cs new file mode 100644 index 00000000..0bd4f87a --- /dev/null +++ b/src/Merge.Client/Ats/Eeocs/requests/EeocsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class EeocsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EeocsRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EeocsRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Ats/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..0e1ccb71 --- /dev/null +++ b/src/Merge.Client/Ats/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,146 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/field-mappings" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/ats/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/ats/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/target-fields" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Ats/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Ats/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..5ba952c9 --- /dev/null +++ b/src/Merge.Client/Ats/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Ats; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Ats/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Ats/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..0f0477c9 --- /dev/null +++ b/src/Merge.Client/Ats/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Ats; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Ats/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Ats/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..a143488d --- /dev/null +++ b/src/Merge.Client/Ats/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ats; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Ats/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Ats/ForceResync/ForceResyncClient.cs index 19f499fd..c4c92008 100644 --- a/src/Merge.Client/Ats/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Ats/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Ats/GenerateKey/GenerateKeyClient.cs index a312d16b..51bb547a 100644 --- a/src/Merge.Client/Ats/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Ats/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Ats/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..04ae8ca8 --- /dev/null +++ b/src/Merge.Client/Ats/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Ats/Interviews/InterviewsClient.cs b/src/Merge.Client/Ats/Interviews/InterviewsClient.cs index a864a56d..a10e74dc 100644 --- a/src/Merge.Client/Ats/Interviews/InterviewsClient.cs +++ b/src/Merge.Client/Ats/Interviews/InterviewsClient.cs @@ -1,13 +1,194 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class InterviewsClient { - public async void List(){ + private RawClient _client; + + public InterviewsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `ScheduledInterview` objects. + /// + public async Task ListAsync(InterviewsListRequest request) + { + var _query = new Dictionary() { }; + if (request.ApplicationId != null) + { + _query["application_id"] = request.ApplicationId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.JobId != null) + { + _query["job_id"] = request.JobId; + } + if (request.JobInterviewStageId != null) + { + _query["job_interview_stage_id"] = request.JobInterviewStageId; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OrganizerId != null) + { + _query["organizer_id"] = request.OrganizerId; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/interviews", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `ScheduledInterview` object with the given values. + /// + public async Task CreateAsync( + ScheduledInterviewEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/interviews", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `ScheduledInterview` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + InterviewsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/interviews/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `ScheduledInterview` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/interviews/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Interviews/requests/InterviewsListRequest.cs b/src/Merge.Client/Ats/Interviews/requests/InterviewsListRequest.cs new file mode 100644 index 00000000..79e1438e --- /dev/null +++ b/src/Merge.Client/Ats/Interviews/requests/InterviewsListRequest.cs @@ -0,0 +1,86 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class InterviewsListRequest +{ + /// + /// If provided, will only return interviews for this application. + /// + public string? ApplicationId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public InterviewsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, wll only return interviews organized for this job. + /// + public string? JobId { get; init; } + + /// + /// If provided, will only return interviews at this stage. + /// + public string? JobInterviewStageId { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return interviews organized by this user. + /// + public string? OrganizerId { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Interviews/requests/InterviewsRetrieveRequest.cs b/src/Merge.Client/Ats/Interviews/requests/InterviewsRetrieveRequest.cs new file mode 100644 index 00000000..0f9f7b6d --- /dev/null +++ b/src/Merge.Client/Ats/Interviews/requests/InterviewsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class InterviewsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public InterviewsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Interviews/requests/ScheduledInterviewEndpointRequest.cs b/src/Merge.Client/Ats/Interviews/requests/ScheduledInterviewEndpointRequest.cs new file mode 100644 index 00000000..f4a551e0 --- /dev/null +++ b/src/Merge.Client/Ats/Interviews/requests/ScheduledInterviewEndpointRequest.cs @@ -0,0 +1,20 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ScheduledInterviewEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ScheduledInterviewRequest Model { get; init; } + + public string RemoteUserId { get; init; } +} diff --git a/src/Merge.Client/Ats/Issues/IssuesClient.cs b/src/Merge.Client/Ats/Issues/IssuesClient.cs index d6dd267f..abce766b 100644 --- a/src/Merge.Client/Ats/Issues/IssuesClient.cs +++ b/src/Merge.Client/Ats/Issues/IssuesClient.cs @@ -1,9 +1,105 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = $"/ats/v1/issues/{id}" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Ats/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..c20151a3 --- /dev/null +++ b/src/Merge.Client/Ats/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Ats/JobInterviewStages/JobInterviewStagesClient.cs b/src/Merge.Client/Ats/JobInterviewStages/JobInterviewStagesClient.cs index 66daafcd..444d1084 100644 --- a/src/Merge.Client/Ats/JobInterviewStages/JobInterviewStagesClient.cs +++ b/src/Merge.Client/Ats/JobInterviewStages/JobInterviewStagesClient.cs @@ -1,9 +1,116 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class JobInterviewStagesClient { - public async void List(){ + private RawClient _client; + + public JobInterviewStagesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `JobInterviewStage` objects. + /// + public async Task ListAsync( + JobInterviewStagesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.JobId != null) + { + _query["job_id"] = request.JobId; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/job-interview-stages", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `JobInterviewStage` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + JobInterviewStagesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/job-interview-stages/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesListRequest.cs b/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesListRequest.cs new file mode 100644 index 00000000..857b2579 --- /dev/null +++ b/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Ats; + +public class JobInterviewStagesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return interview stages for this job. + /// + public string? JobId { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesRetrieveRequest.cs b/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesRetrieveRequest.cs new file mode 100644 index 00000000..1ebeb01c --- /dev/null +++ b/src/Merge.Client/Ats/JobInterviewStages/requests/JobInterviewStagesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ats; + +public class JobInterviewStagesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/JobPostings/JobPostingsClient.cs b/src/Merge.Client/Ats/JobPostings/JobPostingsClient.cs new file mode 100644 index 00000000..bbf37c38 --- /dev/null +++ b/src/Merge.Client/Ats/JobPostings/JobPostingsClient.cs @@ -0,0 +1,103 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class JobPostingsClient +{ + private RawClient _client; + + public JobPostingsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `JobPosting` objects. + /// + public async Task ListAsync(JobPostingsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/job-postings", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `JobPosting` object with the given `id`. + /// + public async Task RetrieveAsync(string id, JobPostingsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/job-postings/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Ats/JobPostings/Types/JobPostingsListRequestStatus.cs b/src/Merge.Client/Ats/JobPostings/Types/JobPostingsListRequestStatus.cs new file mode 100644 index 00000000..8376ef3e --- /dev/null +++ b/src/Merge.Client/Ats/JobPostings/Types/JobPostingsListRequestStatus.cs @@ -0,0 +1,21 @@ +using System.Runtime.Serialization; + +namespace Merge.Client.Ats; + +public enum JobPostingsListRequestStatus +{ + [EnumMember(Value = "CLOSED")] + Closed, + + [EnumMember(Value = "DRAFT")] + Draft, + + [EnumMember(Value = "INTERNAL")] + Internal, + + [EnumMember(Value = "PENDING")] + Pending, + + [EnumMember(Value = "PUBLISHED")] + Published +} diff --git a/src/Merge.Client/Ats/JobPostings/requests/JobPostingsListRequest.cs b/src/Merge.Client/Ats/JobPostings/requests/JobPostingsListRequest.cs new file mode 100644 index 00000000..44bb3bf2 --- /dev/null +++ b/src/Merge.Client/Ats/JobPostings/requests/JobPostingsListRequest.cs @@ -0,0 +1,62 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class JobPostingsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return Job Postings with this status. Options: ('PUBLISHED', 'CLOSED', 'DRAFT', 'INTERNAL', 'PENDING') + /// + /// - `PUBLISHED` - PUBLISHED + /// - `CLOSED` - CLOSED + /// - `DRAFT` - DRAFT + /// - `INTERNAL` - INTERNAL + /// - `PENDING` - PENDING + /// + public JobPostingsListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Ats/JobPostings/requests/JobPostingsRetrieveRequest.cs b/src/Merge.Client/Ats/JobPostings/requests/JobPostingsRetrieveRequest.cs new file mode 100644 index 00000000..f4375e21 --- /dev/null +++ b/src/Merge.Client/Ats/JobPostings/requests/JobPostingsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class JobPostingsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Jobs/JobsClient.cs b/src/Merge.Client/Ats/Jobs/JobsClient.cs index 3fbeca9d..d48dfafb 100644 --- a/src/Merge.Client/Ats/Jobs/JobsClient.cs +++ b/src/Merge.Client/Ats/Jobs/JobsClient.cs @@ -1,11 +1,180 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class JobsClient { - public async void List(){ + private RawClient _client; + + public JobsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Job` objects. + /// + public async Task ListAsync(JobsListRequest request) + { + var _query = new Dictionary() { }; + if (request.Code != null) + { + _query["code"] = request.Code; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Offices != null) + { + _query["offices"] = request.Offices; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/jobs", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Job` object with the given `id`. + /// + public async Task RetrieveAsync(string id, JobsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/jobs/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void ScreeningQuestionsList(){ + + /// + /// Returns a list of `ScreeningQuestion` objects. + /// + public async Task ScreeningQuestionsListAsync( + string jobId, + JobsScreeningQuestionsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/jobs/{jobId}/screening-questions", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Jobs/Types/JobsListRequestExpand.cs b/src/Merge.Client/Ats/Jobs/Types/JobsListRequestExpand.cs index 485d5347..722a0530 100644 --- a/src/Merge.Client/Ats/Jobs/Types/JobsListRequestExpand.cs +++ b/src/Merge.Client/Ats/Jobs/Types/JobsListRequestExpand.cs @@ -10,18 +10,42 @@ public enum JobsListRequestExpand [EnumMember(Value = "departments,hiring_managers")] DepartmentsHiringManagers, + [EnumMember(Value = "departments,hiring_managers,job_postings")] + DepartmentsHiringManagersJobPostings, + + [EnumMember(Value = "departments,hiring_managers,job_postings,recruiters")] + DepartmentsHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "departments,hiring_managers,recruiters")] DepartmentsHiringManagersRecruiters, + [EnumMember(Value = "departments,job_postings")] + DepartmentsJobPostings, + + [EnumMember(Value = "departments,job_postings,recruiters")] + DepartmentsJobPostingsRecruiters, + [EnumMember(Value = "departments,offices")] DepartmentsOffices, [EnumMember(Value = "departments,offices,hiring_managers")] DepartmentsOfficesHiringManagers, + [EnumMember(Value = "departments,offices,hiring_managers,job_postings")] + DepartmentsOfficesHiringManagersJobPostings, + + [EnumMember(Value = "departments,offices,hiring_managers,job_postings,recruiters")] + DepartmentsOfficesHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "departments,offices,hiring_managers,recruiters")] DepartmentsOfficesHiringManagersRecruiters, + [EnumMember(Value = "departments,offices,job_postings")] + DepartmentsOfficesJobPostings, + + [EnumMember(Value = "departments,offices,job_postings,recruiters")] + DepartmentsOfficesJobPostingsRecruiters, + [EnumMember(Value = "departments,offices,recruiters")] DepartmentsOfficesRecruiters, @@ -31,18 +55,42 @@ public enum JobsListRequestExpand [EnumMember(Value = "hiring_managers")] HiringManagers, + [EnumMember(Value = "hiring_managers,job_postings")] + HiringManagersJobPostings, + + [EnumMember(Value = "hiring_managers,job_postings,recruiters")] + HiringManagersJobPostingsRecruiters, + [EnumMember(Value = "hiring_managers,recruiters")] HiringManagersRecruiters, + [EnumMember(Value = "job_postings")] + JobPostings, + + [EnumMember(Value = "job_postings,recruiters")] + JobPostingsRecruiters, + [EnumMember(Value = "offices")] Offices, [EnumMember(Value = "offices,hiring_managers")] OfficesHiringManagers, + [EnumMember(Value = "offices,hiring_managers,job_postings")] + OfficesHiringManagersJobPostings, + + [EnumMember(Value = "offices,hiring_managers,job_postings,recruiters")] + OfficesHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "offices,hiring_managers,recruiters")] OfficesHiringManagersRecruiters, + [EnumMember(Value = "offices,job_postings")] + OfficesJobPostings, + + [EnumMember(Value = "offices,job_postings,recruiters")] + OfficesJobPostingsRecruiters, + [EnumMember(Value = "offices,recruiters")] OfficesRecruiters, diff --git a/src/Merge.Client/Ats/Jobs/Types/JobsRetrieveRequestExpand.cs b/src/Merge.Client/Ats/Jobs/Types/JobsRetrieveRequestExpand.cs index 0d9cf900..1ee8a6da 100644 --- a/src/Merge.Client/Ats/Jobs/Types/JobsRetrieveRequestExpand.cs +++ b/src/Merge.Client/Ats/Jobs/Types/JobsRetrieveRequestExpand.cs @@ -10,18 +10,42 @@ public enum JobsRetrieveRequestExpand [EnumMember(Value = "departments,hiring_managers")] DepartmentsHiringManagers, + [EnumMember(Value = "departments,hiring_managers,job_postings")] + DepartmentsHiringManagersJobPostings, + + [EnumMember(Value = "departments,hiring_managers,job_postings,recruiters")] + DepartmentsHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "departments,hiring_managers,recruiters")] DepartmentsHiringManagersRecruiters, + [EnumMember(Value = "departments,job_postings")] + DepartmentsJobPostings, + + [EnumMember(Value = "departments,job_postings,recruiters")] + DepartmentsJobPostingsRecruiters, + [EnumMember(Value = "departments,offices")] DepartmentsOffices, [EnumMember(Value = "departments,offices,hiring_managers")] DepartmentsOfficesHiringManagers, + [EnumMember(Value = "departments,offices,hiring_managers,job_postings")] + DepartmentsOfficesHiringManagersJobPostings, + + [EnumMember(Value = "departments,offices,hiring_managers,job_postings,recruiters")] + DepartmentsOfficesHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "departments,offices,hiring_managers,recruiters")] DepartmentsOfficesHiringManagersRecruiters, + [EnumMember(Value = "departments,offices,job_postings")] + DepartmentsOfficesJobPostings, + + [EnumMember(Value = "departments,offices,job_postings,recruiters")] + DepartmentsOfficesJobPostingsRecruiters, + [EnumMember(Value = "departments,offices,recruiters")] DepartmentsOfficesRecruiters, @@ -31,18 +55,42 @@ public enum JobsRetrieveRequestExpand [EnumMember(Value = "hiring_managers")] HiringManagers, + [EnumMember(Value = "hiring_managers,job_postings")] + HiringManagersJobPostings, + + [EnumMember(Value = "hiring_managers,job_postings,recruiters")] + HiringManagersJobPostingsRecruiters, + [EnumMember(Value = "hiring_managers,recruiters")] HiringManagersRecruiters, + [EnumMember(Value = "job_postings")] + JobPostings, + + [EnumMember(Value = "job_postings,recruiters")] + JobPostingsRecruiters, + [EnumMember(Value = "offices")] Offices, [EnumMember(Value = "offices,hiring_managers")] OfficesHiringManagers, + [EnumMember(Value = "offices,hiring_managers,job_postings")] + OfficesHiringManagersJobPostings, + + [EnumMember(Value = "offices,hiring_managers,job_postings,recruiters")] + OfficesHiringManagersJobPostingsRecruiters, + [EnumMember(Value = "offices,hiring_managers,recruiters")] OfficesHiringManagersRecruiters, + [EnumMember(Value = "offices,job_postings")] + OfficesJobPostings, + + [EnumMember(Value = "offices,job_postings,recruiters")] + OfficesJobPostingsRecruiters, + [EnumMember(Value = "offices,recruiters")] OfficesRecruiters, diff --git a/src/Merge.Client/Ats/Jobs/requests/JobsListRequest.cs b/src/Merge.Client/Ats/Jobs/requests/JobsListRequest.cs new file mode 100644 index 00000000..22935211 --- /dev/null +++ b/src/Merge.Client/Ats/Jobs/requests/JobsListRequest.cs @@ -0,0 +1,87 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class JobsListRequest +{ + /// + /// If provided, will only return jobs with this code. + /// + public string? Code { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public JobsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return jobs for this office; multiple offices can be separated by commas. + /// + public string? Offices { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return jobs with this status. Options: ('OPEN', 'CLOSED', 'DRAFT', 'ARCHIVED', 'PENDING') + /// + /// - `OPEN` - OPEN + /// - `CLOSED` - CLOSED + /// - `DRAFT` - DRAFT + /// - `ARCHIVED` - ARCHIVED + /// - `PENDING` - PENDING + /// + public JobsListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Ats/Jobs/requests/JobsRetrieveRequest.cs b/src/Merge.Client/Ats/Jobs/requests/JobsRetrieveRequest.cs new file mode 100644 index 00000000..67e22736 --- /dev/null +++ b/src/Merge.Client/Ats/Jobs/requests/JobsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class JobsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public JobsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Jobs/requests/JobsScreeningQuestionsListRequest.cs b/src/Merge.Client/Ats/Jobs/requests/JobsScreeningQuestionsListRequest.cs new file mode 100644 index 00000000..76b755b5 --- /dev/null +++ b/src/Merge.Client/Ats/Jobs/requests/JobsScreeningQuestionsListRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class JobsScreeningQuestionsListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public JobsScreeningQuestionsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ats/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Ats/LinkToken/LinkTokenClient.cs index 3bed81da..f6ad78c4 100644 --- a/src/Merge.Client/Ats/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Ats/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Ats/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..dca626c8 --- /dev/null +++ b/src/Merge.Client/Ats/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Ats/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Ats/LinkedAccounts/LinkedAccountsClient.cs index e82c5b08..cce15f18 100644 --- a/src/Merge.Client/Ats/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Ats/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Ats/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..935d0055 --- /dev/null +++ b/src/Merge.Client/Ats/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class LinkedAccountsListRequest +{ + /// + /// Options: `accounting`, `ats`, `crm`, `filestorage`, `hris`, `mktg`, `ticketing` + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Ats/Offers/OffersClient.cs b/src/Merge.Client/Ats/Offers/OffersClient.cs index 9f0b8a66..3aee35e0 100644 --- a/src/Merge.Client/Ats/Offers/OffersClient.cs +++ b/src/Merge.Client/Ats/Offers/OffersClient.cs @@ -1,9 +1,131 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class OffersClient { - public async void List(){ + private RawClient _client; + + public OffersClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Offer` objects. + /// + public async Task ListAsync(OffersListRequest request) + { + var _query = new Dictionary() { }; + if (request.ApplicationId != null) + { + _query["application_id"] = request.ApplicationId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.CreatorId != null) + { + _query["creator_id"] = request.CreatorId; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/offers", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `Offer` object with the given `id`. + /// + public async Task RetrieveAsync(string id, OffersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/offers/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Offers/requests/OffersListRequest.cs b/src/Merge.Client/Ats/Offers/requests/OffersListRequest.cs new file mode 100644 index 00000000..efcb30d7 --- /dev/null +++ b/src/Merge.Client/Ats/Offers/requests/OffersListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class OffersListRequest +{ + /// + /// If provided, will only return offers for this application. + /// + public string? ApplicationId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// If provided, will only return offers created by this user. + /// + public string? CreatorId { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public OffersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Offers/requests/OffersRetrieveRequest.cs b/src/Merge.Client/Ats/Offers/requests/OffersRetrieveRequest.cs new file mode 100644 index 00000000..0a9acfda --- /dev/null +++ b/src/Merge.Client/Ats/Offers/requests/OffersRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class OffersRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public OffersRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Offices/OfficesClient.cs b/src/Merge.Client/Ats/Offices/OfficesClient.cs index 0551aaa2..a5b0461d 100644 --- a/src/Merge.Client/Ats/Offices/OfficesClient.cs +++ b/src/Merge.Client/Ats/Offices/OfficesClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class OfficesClient { - public async void List(){ + private RawClient _client; + + public OfficesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Office` objects. + /// + public async Task ListAsync(OfficesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/offices", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `Office` object with the given `id`. + /// + public async Task RetrieveAsync(string id, OfficesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/offices/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Offices/requests/OfficesListRequest.cs b/src/Merge.Client/Ats/Offices/requests/OfficesListRequest.cs new file mode 100644 index 00000000..6e2cb763 --- /dev/null +++ b/src/Merge.Client/Ats/Offices/requests/OfficesListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ats; + +public class OfficesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ats/Offices/requests/OfficesRetrieveRequest.cs b/src/Merge.Client/Ats/Offices/requests/OfficesRetrieveRequest.cs new file mode 100644 index 00000000..072dd78f --- /dev/null +++ b/src/Merge.Client/Ats/Offices/requests/OfficesRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class OfficesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Passthrough/PassthroughClient.cs b/src/Merge.Client/Ats/Passthrough/PassthroughClient.cs index d0cd1545..5e7e0c46 100644 --- a/src/Merge.Client/Ats/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Ats/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Ats/RegenerateKey/RegenerateKeyClient.cs index 4c14557b..023aac79 100644 --- a/src/Merge.Client/Ats/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Ats/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Ats/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..5d28dea5 --- /dev/null +++ b/src/Merge.Client/Ats/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Ats/RejectReasons/RejectReasonsClient.cs b/src/Merge.Client/Ats/RejectReasons/RejectReasonsClient.cs index a30b5d70..ba49e3bd 100644 --- a/src/Merge.Client/Ats/RejectReasons/RejectReasonsClient.cs +++ b/src/Merge.Client/Ats/RejectReasons/RejectReasonsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class RejectReasonsClient { - public async void List(){ + private RawClient _client; + + public RejectReasonsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `RejectReason` objects. + /// + public async Task ListAsync(RejectReasonsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/reject-reasons", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `RejectReason` object with the given `id`. + /// + public async Task RetrieveAsync(string id, RejectReasonsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/reject-reasons/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsListRequest.cs b/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsListRequest.cs new file mode 100644 index 00000000..babb3000 --- /dev/null +++ b/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ats; + +public class RejectReasonsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsRetrieveRequest.cs b/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsRetrieveRequest.cs new file mode 100644 index 00000000..44ecbcb9 --- /dev/null +++ b/src/Merge.Client/Ats/RejectReasons/requests/RejectReasonsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ats; + +public class RejectReasonsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Scopes/ScopesClient.cs b/src/Merge.Client/Ats/Scopes/ScopesClient.cs new file mode 100644 index 00000000..3b1acb8a --- /dev/null +++ b/src/Merge.Client/Ats/Scopes/ScopesClient.cs @@ -0,0 +1,74 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/default-scopes" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Ats/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Ats/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..f9c3eb10 --- /dev/null +++ b/src/Merge.Client/Ats/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Ats/Scorecards/ScorecardsClient.cs b/src/Merge.Client/Ats/Scorecards/ScorecardsClient.cs index 731954f5..106f301c 100644 --- a/src/Merge.Client/Ats/Scorecards/ScorecardsClient.cs +++ b/src/Merge.Client/Ats/Scorecards/ScorecardsClient.cs @@ -1,9 +1,135 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class ScorecardsClient { - public async void List(){ + private RawClient _client; + + public ScorecardsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Scorecard` objects. + /// + public async Task ListAsync(ScorecardsListRequest request) + { + var _query = new Dictionary() { }; + if (request.ApplicationId != null) + { + _query["application_id"] = request.ApplicationId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.InterviewId != null) + { + _query["interview_id"] = request.InterviewId; + } + if (request.InterviewerId != null) + { + _query["interviewer_id"] = request.InterviewerId; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/scorecards", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Scorecard` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ScorecardsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/scorecards/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Scorecards/requests/ScorecardsListRequest.cs b/src/Merge.Client/Ats/Scorecards/requests/ScorecardsListRequest.cs new file mode 100644 index 00000000..ec48774e --- /dev/null +++ b/src/Merge.Client/Ats/Scorecards/requests/ScorecardsListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ScorecardsListRequest +{ + /// + /// If provided, will only return scorecards for this application. + /// + public string? ApplicationId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ScorecardsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return scorecards for this interview. + /// + public string? InterviewId { get; init; } + + /// + /// If provided, will only return scorecards for this interviewer. + /// + public string? InterviewerId { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Scorecards/requests/ScorecardsRetrieveRequest.cs b/src/Merge.Client/Ats/Scorecards/requests/ScorecardsRetrieveRequest.cs new file mode 100644 index 00000000..8196ef26 --- /dev/null +++ b/src/Merge.Client/Ats/Scorecards/requests/ScorecardsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ScorecardsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ScorecardsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Ats/SelectiveSync/SelectiveSyncClient.cs index 5ae4d573..3bcbc790 100644 --- a/src/Merge.Client/Ats/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Ats/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/ats/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Ats/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..214a692e --- /dev/null +++ b/src/Merge.Client/Ats/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Ats/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Ats/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..7a35bebd --- /dev/null +++ b/src/Merge.Client/Ats/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Ats; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ats/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Ats/SyncStatus/SyncStatusClient.cs index ee457a71..a4c10d2d 100644 --- a/src/Merge.Client/Ats/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Ats/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Ats/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..521164fc --- /dev/null +++ b/src/Merge.Client/Ats/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ats; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ats/Tags/TagsClient.cs b/src/Merge.Client/Ats/Tags/TagsClient.cs index 8c3c3c63..1282cc3a 100644 --- a/src/Merge.Client/Ats/Tags/TagsClient.cs +++ b/src/Merge.Client/Ats/Tags/TagsClient.cs @@ -1,7 +1,73 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class TagsClient { - public async void List(){ + private RawClient _client; + + public TagsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Tag` objects. + /// + public async Task ListAsync(TagsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/tags", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Tags/requests/TagsListRequest.cs b/src/Merge.Client/Ats/Tags/requests/TagsListRequest.cs new file mode 100644 index 00000000..aa6f9e0f --- /dev/null +++ b/src/Merge.Client/Ats/Tags/requests/TagsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ats; + +public class TagsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Ats/Types/AccountDetailsAndActions.cs index de0392de..ddf246d2 100644 --- a/src/Merge.Client/Ats/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Ats/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Ats/Types/AccountIntegration.cs b/src/Merge.Client/Ats/Types/AccountIntegration.cs index 84c0e0c4..e99d5e76 100644 --- a/src/Merge.Client/Ats/Types/AccountIntegration.cs +++ b/src/Merge.Client/Ats/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Ats/Types/Activity.cs b/src/Merge.Client/Ats/Types/Activity.cs index 9150dd0d..0f70c4af 100644 --- a/src/Merge.Client/Ats/Types/Activity.cs +++ b/src/Merge.Client/Ats/Types/Activity.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class Activity [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user that performed the action. /// @@ -29,7 +38,7 @@ public class Activity /// /// The activity's type. - /// + /// /// - `NOTE` - NOTE /// - `EMAIL` - EMAIL /// - `OTHER` - OTHER @@ -51,7 +60,7 @@ public class Activity /// /// The activity's visibility. - /// + /// /// - `ADMIN_ONLY` - ADMIN_ONLY /// - `PUBLIC` - PUBLIC /// - `PRIVATE` - PRIVATE @@ -71,15 +80,6 @@ public class Activity [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/ActivityRequest.cs b/src/Merge.Client/Ats/Types/ActivityRequest.cs index 5bd3bb5e..8ec3240e 100644 --- a/src/Merge.Client/Ats/Types/ActivityRequest.cs +++ b/src/Merge.Client/Ats/Types/ActivityRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -14,7 +14,7 @@ public class ActivityRequest /// /// The activity's type. - /// + /// /// - `NOTE` - NOTE /// - `EMAIL` - EMAIL /// - `OTHER` - OTHER @@ -36,7 +36,7 @@ public class ActivityRequest /// /// The activity's visibility. - /// + /// /// - `ADMIN_ONLY` - ADMIN_ONLY /// - `PUBLIC` - PUBLIC /// - `PRIVATE` - PRIVATE diff --git a/src/Merge.Client/Ats/Types/AdvancedMetadata.cs b/src/Merge.Client/Ats/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..bbca9b90 --- /dev/null +++ b/src/Merge.Client/Ats/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/Application.cs b/src/Merge.Client/Ats/Types/Application.cs index c06d0c87..f1f3bfbb 100644 --- a/src/Merge.Client/Ats/Types/Application.cs +++ b/src/Merge.Client/Ats/Types/Application.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class Application [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The candidate applying. /// @@ -39,6 +48,9 @@ public class Application [JsonPropertyName("rejected_at")] public DateTime? RejectedAt { get; init; } + [JsonPropertyName("offers")] + public List?>? Offers { get; init; } + /// /// The application's source. /// @@ -66,15 +78,6 @@ public class Application [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/ApplicationRequest.cs b/src/Merge.Client/Ats/Types/ApplicationRequest.cs index d99b38e8..6ed8fe2f 100644 --- a/src/Merge.Client/Ats/Types/ApplicationRequest.cs +++ b/src/Merge.Client/Ats/Types/ApplicationRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -30,6 +30,9 @@ public class ApplicationRequest [JsonPropertyName("rejected_at")] public DateTime? RejectedAt { get; init; } + [JsonPropertyName("offers")] + public List?>? Offers { get; init; } + /// /// The application's source. /// diff --git a/src/Merge.Client/Ats/Types/Attachment.cs b/src/Merge.Client/Ats/Types/Attachment.cs index 2a2d21ed..72c8b6ab 100644 --- a/src/Merge.Client/Ats/Types/Attachment.cs +++ b/src/Merge.Client/Ats/Types/Attachment.cs @@ -14,6 +14,15 @@ public class Attachment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The attachment's name. /// @@ -27,14 +36,14 @@ public class Attachment public string? FileUrl { get; init; } /// - /// + /// /// [JsonPropertyName("candidate")] public string? Candidate { get; init; } /// /// The attachment's type. - /// + /// /// - `RESUME` - RESUME /// - `COVER_LETTER` - COVER_LETTER /// - `OFFER_LETTER` - OFFER_LETTER @@ -46,15 +55,6 @@ public class Attachment [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/AttachmentRequest.cs b/src/Merge.Client/Ats/Types/AttachmentRequest.cs index 351d3fdf..fce42510 100644 --- a/src/Merge.Client/Ats/Types/AttachmentRequest.cs +++ b/src/Merge.Client/Ats/Types/AttachmentRequest.cs @@ -18,14 +18,14 @@ public class AttachmentRequest public string? FileUrl { get; init; } /// - /// + /// /// [JsonPropertyName("candidate")] public string? Candidate { get; init; } /// /// The attachment's type. - /// + /// /// - `RESUME` - RESUME /// - `COVER_LETTER` - COVER_LETTER /// - `OFFER_LETTER` - OFFER_LETTER diff --git a/src/Merge.Client/Ats/Types/AuditLogEvent.cs b/src/Merge.Client/Ats/Types/AuditLogEvent.cs index 2e6d0479..610188ec 100644 --- a/src/Merge.Client/Ats/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Ats/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Ats/Types/Candidate.cs b/src/Merge.Client/Ats/Types/Candidate.cs index fb082a46..5d07af6a 100644 --- a/src/Merge.Client/Ats/Types/Candidate.cs +++ b/src/Merge.Client/Ats/Types/Candidate.cs @@ -15,6 +15,15 @@ public class Candidate [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The candidate's first name. /// @@ -105,15 +114,6 @@ public class Candidate [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/CommonModelScopeApi.cs b/src/Merge.Client/Ats/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..bfed74ec --- /dev/null +++ b/src/Merge.Client/Ats/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/ConditionSchema.cs b/src/Merge.Client/Ats/Types/ConditionSchema.cs index 0b46361c..6ad5af6e 100644 --- a/src/Merge.Client/Ats/Types/ConditionSchema.cs +++ b/src/Merge.Client/Ats/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Ats/Types/DataPassthroughRequest.cs b/src/Merge.Client/Ats/Types/DataPassthroughRequest.cs index 431ee21b..75e8f970 100644 --- a/src/Merge.Client/Ats/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Ats/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Ats/Types/Department.cs b/src/Merge.Client/Ats/Types/Department.cs index 2e8f013c..48ad6a2c 100644 --- a/src/Merge.Client/Ats/Types/Department.cs +++ b/src/Merge.Client/Ats/Types/Department.cs @@ -14,6 +14,15 @@ public class Department [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The department's name. /// @@ -26,15 +35,6 @@ public class Department [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/Eeoc.cs b/src/Merge.Client/Ats/Types/Eeoc.cs index 724f8b70..4e326135 100644 --- a/src/Merge.Client/Ats/Types/Eeoc.cs +++ b/src/Merge.Client/Ats/Types/Eeoc.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class Eeoc [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The candidate being represented. /// @@ -29,7 +38,7 @@ public class Eeoc /// /// The candidate's race. - /// + /// /// - `AMERICAN_INDIAN_OR_ALASKAN_NATIVE` - AMERICAN_INDIAN_OR_ALASKAN_NATIVE /// - `ASIAN` - ASIAN /// - `BLACK_OR_AFRICAN_AMERICAN` - BLACK_OR_AFRICAN_AMERICAN @@ -44,7 +53,7 @@ public class Eeoc /// /// The candidate's gender. - /// + /// /// - `MALE` - MALE /// - `FEMALE` - FEMALE /// - `NON-BINARY` - NON-BINARY @@ -56,7 +65,7 @@ public class Eeoc /// /// The candidate's veteran status. - /// + /// /// - `I_AM_NOT_A_PROTECTED_VETERAN` - I_AM_NOT_A_PROTECTED_VETERAN /// - `I_IDENTIFY_AS_ONE_OR_MORE_OF_THE_CLASSIFICATIONS_OF_A_PROTECTED_VETERAN` - I_IDENTIFY_AS_ONE_OR_MORE_OF_THE_CLASSIFICATIONS_OF_A_PROTECTED_VETERAN /// - `I_DONT_WISH_TO_ANSWER` - I_DONT_WISH_TO_ANSWER @@ -66,7 +75,7 @@ public class Eeoc /// /// The candidate's disability status. - /// + /// /// - `YES_I_HAVE_A_DISABILITY_OR_PREVIOUSLY_HAD_A_DISABILITY` - YES_I_HAVE_A_DISABILITY_OR_PREVIOUSLY_HAD_A_DISABILITY /// - `NO_I_DONT_HAVE_A_DISABILITY` - NO_I_DONT_HAVE_A_DISABILITY /// - `I_DONT_WISH_TO_ANSWER` - I_DONT_WISH_TO_ANSWER @@ -80,15 +89,6 @@ public class Eeoc [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/EmailAddress.cs b/src/Merge.Client/Ats/Types/EmailAddress.cs index 59fd686c..4c1d6b94 100644 --- a/src/Merge.Client/Ats/Types/EmailAddress.cs +++ b/src/Merge.Client/Ats/Types/EmailAddress.cs @@ -5,6 +5,15 @@ namespace Merge.Client.Ats; public class EmailAddress { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The email address. /// @@ -13,20 +22,11 @@ public class EmailAddress /// /// The type of email address. - /// + /// /// - `PERSONAL` - PERSONAL /// - `WORK` - WORK /// - `OTHER` - OTHER /// [JsonPropertyName("email_address_type")] public EmailAddressTypeEnum? EmailAddressType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Ats/Types/EmailAddressRequest.cs b/src/Merge.Client/Ats/Types/EmailAddressRequest.cs index 24452ae8..3e6e497f 100644 --- a/src/Merge.Client/Ats/Types/EmailAddressRequest.cs +++ b/src/Merge.Client/Ats/Types/EmailAddressRequest.cs @@ -13,7 +13,7 @@ public class EmailAddressRequest /// /// The type of email address. - /// + /// /// - `PERSONAL` - PERSONAL /// - `WORK` - WORK /// - `OTHER` - OTHER diff --git a/src/Merge.Client/Ats/Types/EventTypeEnum.cs b/src/Merge.Client/Ats/Types/EventTypeEnum.cs index 7672e4a2..1e842c7f 100644 --- a/src/Merge.Client/Ats/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Ats/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Ats/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Ats/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..85fbbc82 --- /dev/null +++ b/src/Merge.Client/Ats/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Ats/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..b9093d34 --- /dev/null +++ b/src/Merge.Client/Ats/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("Activity")] + public List? Activity { get; init; } + + [JsonPropertyName("Application")] + public List? Application { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Candidate")] + public List? Candidate { get; init; } + + [JsonPropertyName("Department")] + public List? Department { get; init; } + + [JsonPropertyName("EEOC")] + public List? Eeoc { get; init; } + + [JsonPropertyName("ScheduledInterview")] + public List? ScheduledInterview { get; init; } + + [JsonPropertyName("Job")] + public List? Job { get; init; } + + [JsonPropertyName("JobPosting")] + public List? JobPosting { get; init; } + + [JsonPropertyName("JobInterviewStage")] + public List? JobInterviewStage { get; init; } + + [JsonPropertyName("Offer")] + public List? Offer { get; init; } + + [JsonPropertyName("Office")] + public List? Office { get; init; } + + [JsonPropertyName("RejectReason")] + public List? RejectReason { get; init; } + + [JsonPropertyName("Scorecard")] + public List? Scorecard { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("RemoteUser")] + public List? RemoteUser { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Ats/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..deb70f29 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..e4d31456 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..5554c8a9 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..51df202b --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("Activity")] + public List? Activity { get; init; } + + [JsonPropertyName("Application")] + public List? Application { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Candidate")] + public List? Candidate { get; init; } + + [JsonPropertyName("Department")] + public List? Department { get; init; } + + [JsonPropertyName("EEOC")] + public List? Eeoc { get; init; } + + [JsonPropertyName("ScheduledInterview")] + public List? ScheduledInterview { get; init; } + + [JsonPropertyName("Job")] + public List? Job { get; init; } + + [JsonPropertyName("JobPosting")] + public List? JobPosting { get; init; } + + [JsonPropertyName("JobInterviewStage")] + public List? JobInterviewStage { get; init; } + + [JsonPropertyName("Offer")] + public List? Offer { get; init; } + + [JsonPropertyName("Office")] + public List? Office { get; init; } + + [JsonPropertyName("RejectReason")] + public List? RejectReason { get; init; } + + [JsonPropertyName("Scorecard")] + public List? Scorecard { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("RemoteUser")] + public List? RemoteUser { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..b0b80905 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Ats/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..03c0c744 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Ats/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..494c724b --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Ats/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..a8403b09 --- /dev/null +++ b/src/Merge.Client/Ats/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..d0c8b279 --- /dev/null +++ b/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..e83cb529 --- /dev/null +++ b/src/Merge.Client/Ats/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/Issue.cs b/src/Merge.Client/Ats/Types/Issue.cs index 9ddcdc91..a02587eb 100644 --- a/src/Merge.Client/Ats/Types/Issue.cs +++ b/src/Merge.Client/Ats/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Ats/Types/Job.cs b/src/Merge.Client/Ats/Types/Job.cs index c8e7f947..039f15ab 100644 --- a/src/Merge.Client/Ats/Types/Job.cs +++ b/src/Merge.Client/Ats/Types/Job.cs @@ -15,6 +15,15 @@ public class Job [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The job's name. /// @@ -35,7 +44,7 @@ public class Job /// /// The job's status. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// - `DRAFT` - DRAFT @@ -45,6 +54,22 @@ public class Job [JsonPropertyName("status")] public JobStatusEnum? Status { get; init; } + /// + /// The job's type. + /// + /// - `POSTING` - POSTING + /// - `REQUISITION` - REQUISITION + /// - `PROFILE` - PROFILE + /// + [JsonPropertyName("type")] + public JobTypeEnum? Type { get; init; } + + /// + /// IDs of `JobPosting` objects that serve as job postings for this `Job`. + /// + [JsonPropertyName("job_postings")] + public List? JobPostings { get; init; } + [JsonPropertyName("job_posting_urls")] public List? JobPostingUrls { get; init; } @@ -96,15 +121,6 @@ public class Job [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/JobInterviewStage.cs b/src/Merge.Client/Ats/Types/JobInterviewStage.cs index 6e3025f6..bf7e9e89 100644 --- a/src/Merge.Client/Ats/Types/JobInterviewStage.cs +++ b/src/Merge.Client/Ats/Types/JobInterviewStage.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class JobInterviewStage [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// Standard stage names are offered by ATS systems but can be modified by users. /// @@ -39,15 +48,6 @@ public class JobInterviewStage [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/JobPosting.cs b/src/Merge.Client/Ats/Types/JobPosting.cs new file mode 100644 index 00000000..bf80182d --- /dev/null +++ b/src/Merge.Client/Ats/Types/JobPosting.cs @@ -0,0 +1,92 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; +using OneOf; + +namespace Merge.Client.Ats; + +public class JobPosting +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + + /// + /// The job posting’s title. + /// + [JsonPropertyName("title")] + public string? Title { get; init; } + + /// + /// The Url object is used to represent hyperlinks for a candidate to apply to a given job. + /// + [JsonPropertyName("job_posting_urls")] + public List>? JobPostingUrls { get; init; } + + /// + /// ID of `Job` object for this `JobPosting`. + /// + [JsonPropertyName("job")] + public OneOf? Job { get; init; } + + /// + /// The job posting's status. + /// + /// - `PUBLISHED` - PUBLISHED + /// - `CLOSED` - CLOSED + /// - `DRAFT` - DRAFT + /// - `INTERNAL` - INTERNAL + /// - `PENDING` - PENDING + /// + [JsonPropertyName("status")] + public JobPostingStatusEnum? Status { get; init; } + + /// + /// The job posting’s content. + /// + [JsonPropertyName("content")] + public string? Content { get; init; } + + /// + /// When the third party's job posting was created. + /// + [JsonPropertyName("remote_created_at")] + public DateTime? RemoteCreatedAt { get; init; } + + /// + /// When the third party's job posting was updated. + /// + [JsonPropertyName("remote_updated_at")] + public DateTime? RemoteUpdatedAt { get; init; } + + /// + /// Indicates whether the job posting is internal or external. + /// + [JsonPropertyName("is_internal")] + public bool? IsInternal { get; init; } + + /// + /// Indicates whether or not this object has been deleted in the third party platform. + /// + [JsonPropertyName("remote_was_deleted")] + public bool? RemoteWasDeleted { get; init; } + + [JsonPropertyName("field_mappings")] + public Dictionary? FieldMappings { get; init; } + + [JsonPropertyName("remote_data")] + public List? RemoteData { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/JobPostingStatusEnum.cs b/src/Merge.Client/Ats/Types/JobPostingStatusEnum.cs new file mode 100644 index 00000000..7a14256b --- /dev/null +++ b/src/Merge.Client/Ats/Types/JobPostingStatusEnum.cs @@ -0,0 +1,21 @@ +using System.Runtime.Serialization; + +namespace Merge.Client.Ats; + +public enum JobPostingStatusEnum +{ + [EnumMember(Value = "PUBLISHED")] + Published, + + [EnumMember(Value = "CLOSED")] + Closed, + + [EnumMember(Value = "DRAFT")] + Draft, + + [EnumMember(Value = "INTERNAL")] + Internal, + + [EnumMember(Value = "PENDING")] + Pending +} diff --git a/src/Merge.Client/Ats/Types/JobTypeEnum.cs b/src/Merge.Client/Ats/Types/JobTypeEnum.cs new file mode 100644 index 00000000..fcdf1cfc --- /dev/null +++ b/src/Merge.Client/Ats/Types/JobTypeEnum.cs @@ -0,0 +1,15 @@ +using System.Runtime.Serialization; + +namespace Merge.Client.Ats; + +public enum JobTypeEnum +{ + [EnumMember(Value = "POSTING")] + Posting, + + [EnumMember(Value = "REQUISITION")] + Requisition, + + [EnumMember(Value = "PROFILE")] + Profile +} diff --git a/src/Merge.Client/Ats/Types/LinkedAccountCondition.cs b/src/Merge.Client/Ats/Types/LinkedAccountCondition.cs index 26afefb4..3904f7dd 100644 --- a/src/Merge.Client/Ats/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Ats/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Ats/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Ats/Types/LinkedAccountConditionRequest.cs index 8dd1c334..c6724fc0 100644 --- a/src/Merge.Client/Ats/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Ats/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Ats; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Ats/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Ats/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..3b23c8de --- /dev/null +++ b/src/Merge.Client/Ats/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Ats/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..37a1ae39 --- /dev/null +++ b/src/Merge.Client/Ats/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Ats/Types/MultipartFormFieldRequest.cs index cd84aa68..69efe2e4 100644 --- a/src/Merge.Client/Ats/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Ats/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Ats/Types/Offer.cs b/src/Merge.Client/Ats/Types/Offer.cs index ebe8ac81..20a92af6 100644 --- a/src/Merge.Client/Ats/Types/Offer.cs +++ b/src/Merge.Client/Ats/Types/Offer.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class Offer [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The application who is receiving the offer. /// @@ -53,7 +62,7 @@ public class Offer /// /// The offer's status. - /// + /// /// - `DRAFT` - DRAFT /// - `APPROVAL-SENT` - APPROVAL-SENT /// - `APPROVED` - APPROVED @@ -73,15 +82,6 @@ public class Offer [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/Office.cs b/src/Merge.Client/Ats/Types/Office.cs index 896a6954..e6e52db9 100644 --- a/src/Merge.Client/Ats/Types/Office.cs +++ b/src/Merge.Client/Ats/Types/Office.cs @@ -14,6 +14,15 @@ public class Office [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The office's name. /// @@ -32,15 +41,6 @@ public class Office [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/PaginatedJobPostingList.cs b/src/Merge.Client/Ats/Types/PaginatedJobPostingList.cs new file mode 100644 index 00000000..b335fc7d --- /dev/null +++ b/src/Merge.Client/Ats/Types/PaginatedJobPostingList.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class PaginatedJobPostingList +{ + [JsonPropertyName("next")] + public string? Next { get; init; } + + [JsonPropertyName("previous")] + public string? Previous { get; init; } + + [JsonPropertyName("results")] + public List? Results { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/PhoneNumber.cs b/src/Merge.Client/Ats/Types/PhoneNumber.cs index fa36f7fe..236fe1de 100644 --- a/src/Merge.Client/Ats/Types/PhoneNumber.cs +++ b/src/Merge.Client/Ats/Types/PhoneNumber.cs @@ -5,6 +5,15 @@ namespace Merge.Client.Ats; public class PhoneNumber { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The phone number. /// @@ -13,7 +22,7 @@ public class PhoneNumber /// /// The type of phone number. - /// + /// /// - `HOME` - HOME /// - `WORK` - WORK /// - `MOBILE` - MOBILE @@ -22,13 +31,4 @@ public class PhoneNumber /// [JsonPropertyName("phone_number_type")] public PhoneNumberTypeEnum? PhoneNumberType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Ats/Types/PhoneNumberRequest.cs b/src/Merge.Client/Ats/Types/PhoneNumberRequest.cs index 4ae8a02c..288587a6 100644 --- a/src/Merge.Client/Ats/Types/PhoneNumberRequest.cs +++ b/src/Merge.Client/Ats/Types/PhoneNumberRequest.cs @@ -13,7 +13,7 @@ public class PhoneNumberRequest /// /// The type of phone number. - /// + /// /// - `HOME` - HOME /// - `WORK` - WORK /// - `MOBILE` - MOBILE diff --git a/src/Merge.Client/Ats/Types/RejectReason.cs b/src/Merge.Client/Ats/Types/RejectReason.cs index 1265753f..e2e93ca9 100644 --- a/src/Merge.Client/Ats/Types/RejectReason.cs +++ b/src/Merge.Client/Ats/Types/RejectReason.cs @@ -14,6 +14,15 @@ public class RejectReason [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The rejection reason’s name. /// @@ -26,15 +35,6 @@ public class RejectReason [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Ats/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..d44a2406 --- /dev/null +++ b/src/Merge.Client/Ats/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ats; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/RemoteFieldApi.cs b/src/Merge.Client/Ats/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..e114d090 --- /dev/null +++ b/src/Merge.Client/Ats/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Ats/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..e9e7b55b --- /dev/null +++ b/src/Merge.Client/Ats/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ats; + +namespace Merge.Client.Ats; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("Activity")] + public List? Activity { get; init; } + + [JsonPropertyName("Application")] + public List? Application { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Candidate")] + public List? Candidate { get; init; } + + [JsonPropertyName("Department")] + public List? Department { get; init; } + + [JsonPropertyName("EEOC")] + public List? Eeoc { get; init; } + + [JsonPropertyName("ScheduledInterview")] + public List? ScheduledInterview { get; init; } + + [JsonPropertyName("Job")] + public List? Job { get; init; } + + [JsonPropertyName("JobPosting")] + public List? JobPosting { get; init; } + + [JsonPropertyName("JobInterviewStage")] + public List? JobInterviewStage { get; init; } + + [JsonPropertyName("Offer")] + public List? Offer { get; init; } + + [JsonPropertyName("Office")] + public List? Office { get; init; } + + [JsonPropertyName("RejectReason")] + public List? RejectReason { get; init; } + + [JsonPropertyName("Scorecard")] + public List? Scorecard { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("RemoteUser")] + public List? RemoteUser { get; init; } +} diff --git a/src/Merge.Client/Ats/Types/RemoteUser.cs b/src/Merge.Client/Ats/Types/RemoteUser.cs index 3d3a484d..a12a0d65 100644 --- a/src/Merge.Client/Ats/Types/RemoteUser.cs +++ b/src/Merge.Client/Ats/Types/RemoteUser.cs @@ -14,6 +14,15 @@ public class RemoteUser [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user's first name. /// @@ -46,7 +55,7 @@ public class RemoteUser /// /// The user's role. - /// + /// /// - `SUPER_ADMIN` - SUPER_ADMIN /// - `ADMIN` - ADMIN /// - `TEAM_MEMBER` - TEAM_MEMBER @@ -62,15 +71,6 @@ public class RemoteUser [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/ScheduledInterview.cs b/src/Merge.Client/Ats/Types/ScheduledInterview.cs index 6e2fc066..b26d2f7f 100644 --- a/src/Merge.Client/Ats/Types/ScheduledInterview.cs +++ b/src/Merge.Client/Ats/Types/ScheduledInterview.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class ScheduledInterview [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The application being interviewed. /// @@ -71,7 +80,7 @@ public class ScheduledInterview /// /// The interview's status. - /// + /// /// - `SCHEDULED` - SCHEDULED /// - `AWAITING_FEEDBACK` - AWAITING_FEEDBACK /// - `COMPLETE` - COMPLETE @@ -85,15 +94,6 @@ public class ScheduledInterview [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/ScheduledInterviewRequest.cs b/src/Merge.Client/Ats/Types/ScheduledInterviewRequest.cs index 34f17760..efede1d1 100644 --- a/src/Merge.Client/Ats/Types/ScheduledInterviewRequest.cs +++ b/src/Merge.Client/Ats/Types/ScheduledInterviewRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -50,7 +50,7 @@ public class ScheduledInterviewRequest /// /// The interview's status. - /// + /// /// - `SCHEDULED` - SCHEDULED /// - `AWAITING_FEEDBACK` - AWAITING_FEEDBACK /// - `COMPLETE` - COMPLETE diff --git a/src/Merge.Client/Ats/Types/Scorecard.cs b/src/Merge.Client/Ats/Types/Scorecard.cs index 564b070b..f7a1d641 100644 --- a/src/Merge.Client/Ats/Types/Scorecard.cs +++ b/src/Merge.Client/Ats/Types/Scorecard.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class Scorecard [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The application being scored. /// @@ -47,7 +56,7 @@ public class Scorecard /// /// The inteviewer's recommendation. - /// + /// /// - `DEFINITELY_NO` - DEFINITELY_NO /// - `NO` - NO /// - `YES` - YES @@ -63,15 +72,6 @@ public class Scorecard [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/ScreeningQuestion.cs b/src/Merge.Client/Ats/Types/ScreeningQuestion.cs index e561fb9c..eb531781 100644 --- a/src/Merge.Client/Ats/Types/ScreeningQuestion.cs +++ b/src/Merge.Client/Ats/Types/ScreeningQuestion.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ats; +using OneOf; namespace Merge.Client.Ats; @@ -15,6 +15,15 @@ public class ScreeningQuestion [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The job associated with the screening question. /// @@ -35,7 +44,7 @@ public class ScreeningQuestion /// /// The data type for the screening question. - /// + /// /// - `DATE` - DATE /// - `FILE` - FILE /// - `SINGLE_SELECT` - SINGLE_SELECT @@ -46,7 +55,7 @@ public class ScreeningQuestion /// - `BOOLEAN` - BOOLEAN /// [JsonPropertyName("type")] - public TypeEnum? Type { get; init; } + public ScreeningQuestionTypeEnum? Type { get; init; } /// /// Whether or not the screening question is required. @@ -56,13 +65,4 @@ public class ScreeningQuestion [JsonPropertyName("options")] public List? Options { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Ats/Types/ScreeningQuestionOption.cs b/src/Merge.Client/Ats/Types/ScreeningQuestionOption.cs index c1d9d09c..86875d74 100644 --- a/src/Merge.Client/Ats/Types/ScreeningQuestionOption.cs +++ b/src/Merge.Client/Ats/Types/ScreeningQuestionOption.cs @@ -4,21 +4,15 @@ namespace Merge.Client.Ats; public class ScreeningQuestionOption { + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The third-party API ID of the matching object. /// [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } - /// - /// Available response options - /// - [JsonPropertyName("label")] - public string? Label { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - [JsonPropertyName("created_at")] public DateTime? CreatedAt { get; init; } @@ -27,4 +21,10 @@ public class ScreeningQuestionOption /// [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + + /// + /// Available response options + /// + [JsonPropertyName("label")] + public string? Label { get; init; } } diff --git a/src/Merge.Client/Ats/Types/TypeEnum.cs b/src/Merge.Client/Ats/Types/ScreeningQuestionTypeEnum.cs similarity index 93% rename from src/Merge.Client/Ats/Types/TypeEnum.cs rename to src/Merge.Client/Ats/Types/ScreeningQuestionTypeEnum.cs index 180f43b9..a6ad54f9 100644 --- a/src/Merge.Client/Ats/Types/TypeEnum.cs +++ b/src/Merge.Client/Ats/Types/ScreeningQuestionTypeEnum.cs @@ -2,7 +2,7 @@ namespace Merge.Client.Ats; -public enum TypeEnum +public enum ScreeningQuestionTypeEnum { [EnumMember(Value = "DATE")] Date, diff --git a/src/Merge.Client/Ats/Types/Tag.cs b/src/Merge.Client/Ats/Types/Tag.cs index 0c722207..bacffe4b 100644 --- a/src/Merge.Client/Ats/Types/Tag.cs +++ b/src/Merge.Client/Ats/Types/Tag.cs @@ -10,6 +10,15 @@ public class Tag [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The tag's name. /// @@ -22,15 +31,6 @@ public class Tag [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ats/Types/Url.cs b/src/Merge.Client/Ats/Types/Url.cs index ee50facc..13abbcec 100644 --- a/src/Merge.Client/Ats/Types/Url.cs +++ b/src/Merge.Client/Ats/Types/Url.cs @@ -5,6 +5,15 @@ namespace Merge.Client.Ats; public class Url { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The site's url. /// @@ -13,7 +22,7 @@ public class Url /// /// The type of site. - /// + /// /// - `PERSONAL` - PERSONAL /// - `COMPANY` - COMPANY /// - `PORTFOLIO` - PORTFOLIO @@ -24,13 +33,4 @@ public class Url /// [JsonPropertyName("url_type")] public UrlTypeEnum? UrlType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Ats/Types/UrlRequest.cs b/src/Merge.Client/Ats/Types/UrlRequest.cs index f55f1f34..14a681cf 100644 --- a/src/Merge.Client/Ats/Types/UrlRequest.cs +++ b/src/Merge.Client/Ats/Types/UrlRequest.cs @@ -13,7 +13,7 @@ public class UrlRequest /// /// The type of site. - /// + /// /// - `PERSONAL` - PERSONAL /// - `COMPANY` - COMPANY /// - `PORTFOLIO` - PORTFOLIO diff --git a/src/Merge.Client/Ats/Users/UsersClient.cs b/src/Merge.Client/Ats/Users/UsersClient.cs index c3d92948..f1209378 100644 --- a/src/Merge.Client/Ats/Users/UsersClient.cs +++ b/src/Merge.Client/Ats/Users/UsersClient.cs @@ -1,9 +1,119 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class UsersClient { - public async void List(){ + private RawClient _client; + + public UsersClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `RemoteUser` objects. + /// + public async Task ListAsync(UsersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Email != null) + { + _query["email"] = request.Email; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ats/v1/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `RemoteUser` object with the given `id`. + /// + public async Task RetrieveAsync(string id, UsersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ats/v1/users/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/Users/requests/UsersListRequest.cs b/src/Merge.Client/Ats/Users/requests/UsersListRequest.cs new file mode 100644 index 00000000..86d40c43 --- /dev/null +++ b/src/Merge.Client/Ats/Users/requests/UsersListRequest.cs @@ -0,0 +1,64 @@ +namespace Merge.Client.Ats; + +public class UsersListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return remote users with the given email address + /// + public string? Email { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/Users/requests/UsersRetrieveRequest.cs b/src/Merge.Client/Ats/Users/requests/UsersRetrieveRequest.cs new file mode 100644 index 00000000..581b79e2 --- /dev/null +++ b/src/Merge.Client/Ats/Users/requests/UsersRetrieveRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Ats; + +public class UsersRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ats/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Ats/WebhookReceivers/WebhookReceiversClient.cs index ac330dbb..f07035e6 100644 --- a/src/Merge.Client/Ats/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Ats/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,52 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ats; + namespace Merge.Client.Ats; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/ats/v1/webhook-receivers" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ats/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ats/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Ats/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..8c0378ce --- /dev/null +++ b/src/Merge.Client/Ats/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Ats; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +} diff --git a/src/Merge.Client/Core/ClientOptions.cs b/src/Merge.Client/Core/ClientOptions.cs new file mode 100644 index 00000000..e992a7d8 --- /dev/null +++ b/src/Merge.Client/Core/ClientOptions.cs @@ -0,0 +1,24 @@ +namespace Merge.Client; + +public partial class ClientOptions +{ + /// + /// The Base URL for the API. + /// + public string? BaseUrl { get; init; } + + /// + /// The http client used to make requests. + /// + public HttpClient HttpClient { get; init; } = new HttpClient(); + + /// + /// The http client used to make requests. + /// + public int MaxRetries { get; init; } = 2; + + /// + /// The timeout for the request in seconds. + /// + public int TimeoutInSeconds { get; init; } = 30; +} diff --git a/src/Merge.Client/Core/RawClient.cs b/src/Merge.Client/Core/RawClient.cs new file mode 100644 index 00000000..be67e572 --- /dev/null +++ b/src/Merge.Client/Core/RawClient.cs @@ -0,0 +1,121 @@ +using System.Text; +using System.Text.Json; + +namespace Merge.Client; + +#nullable enable + +/// +/// Utility class for making raw HTTP requests to the API. +/// +public class RawClient +{ + /// + /// The http client used to make requests. + /// + private readonly ClientOptions _clientOptions; + + /// + /// Global headers to be sent with every request. + /// + private readonly Dictionary _headers; + + public RawClient(Dictionary headers, ClientOptions clientOptions) + { + _clientOptions = clientOptions; + _headers = headers; + } + + public async Task MakeRequestAsync(ApiRequest request) + { + var httpRequest = new HttpRequestMessage( + request.Method, + this.BuildUrl(request.Path, request.Query) + ); + if (request.ContentType != null) + { + request.Headers.Add("Content-Type", request.ContentType); + } + // Add global headers to the request + foreach (var (key, value) in _headers) + { + httpRequest.Headers.Add(key, value); + } + // Add request headers to the request + foreach (var (key, value) in request.Headers) + { + httpRequest.Headers.Add(key, value); + } + // Add the request body to the request + if (request.Body != null) + { + httpRequest.Content = new StringContent( + JsonSerializer.Serialize(request.Body), + Encoding.UTF8, + "application/json" + ); + } + // Send the request + HttpResponseMessage response = await _clientOptions.HttpClient.SendAsync(httpRequest); + return new ApiResponse { StatusCode = (int)response.StatusCode, Raw = response }; + } + + /// + /// The request object to be sent to the API. + /// + public class ApiRequest + { + public HttpMethod Method; + + public string Path; + + public string? ContentType = null; + + public object? Body { get; init; } = null; + + public Dictionary Query { get; init; } = new(); + + public Dictionary Headers { get; init; } = new(); + + public object RequestOptions { get; init; } + } + + /// + /// The response object returned from the API. + /// + public class ApiResponse + { + public int StatusCode; + + public HttpResponseMessage Raw; + } + + private Dictionary GetHeaders(ApiRequest request) + { + var headers = new Dictionary(); + foreach (var (key, value) in request.Headers) + { + headers.Add(key, value); + } + foreach (var (key, value) in _headers) + { + headers.Add(key, value); + } + return headers; + } + + private string BuildUrl(string path, Dictionary query) + { + var url = $"{_clientOptions.BaseUrl}/{path}"; + if (query.Count > 0) + { + url += "?"; + foreach (var (key, value) in query) + { + url += $"{key}={value}&"; + } + url = url.Substring(0, url.Length - 1); + } + return url; + } +} diff --git a/src/Merge.Client/Crm/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Crm/AccountDetails/AccountDetailsClient.cs index e2d428ab..500c71bc 100644 --- a/src/Merge.Client/Crm/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Crm/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,31 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/account-details" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Crm/AccountToken/AccountTokenClient.cs index 6de4adf2..3ab5cab4 100644 --- a/src/Merge.Client/Crm/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Crm/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Accounts/AccountsClient.cs b/src/Merge.Client/Crm/Accounts/AccountsClient.cs index 69784a05..66299dc4 100644 --- a/src/Merge.Client/Crm/Accounts/AccountsClient.cs +++ b/src/Merge.Client/Crm/Accounts/AccountsClient.cs @@ -1,19 +1,270 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AccountsClient { - public async void List(){ + private RawClient _client; + + public AccountsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Account` objects. + /// + public async Task ListAsync(AccountsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Name != null) + { + _query["name"] = request.Name; + } + if (request.OwnerId != null) + { + _query["owner_id"] = request.OwnerId; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates an `Account` object with the given values. + /// + public async Task CreateAsync(CrmAccountEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Account` object with the given `id`. + /// + public async Task RetrieveAsync(string id, AccountsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/accounts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Updates an `Account` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedCrmAccountEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/accounts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns metadata for `CRMAccount` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/accounts/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `CRMAccount` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/accounts/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + AccountsRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/accounts/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Accounts/requests/AccountsListRequest.cs b/src/Merge.Client/Crm/Accounts/requests/AccountsListRequest.cs new file mode 100644 index 00000000..cf06caa4 --- /dev/null +++ b/src/Merge.Client/Crm/Accounts/requests/AccountsListRequest.cs @@ -0,0 +1,69 @@ +namespace Merge.Client.Crm; + +public class AccountsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return accounts with this name. + /// + public string? Name { get; init; } + + /// + /// If provided, will only return accounts with this owner. + /// + public string? OwnerId { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Accounts/requests/AccountsRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Accounts/requests/AccountsRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..fbfa1dfe --- /dev/null +++ b/src/Merge.Client/Crm/Accounts/requests/AccountsRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class AccountsRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Accounts/requests/AccountsRetrieveRequest.cs b/src/Merge.Client/Crm/Accounts/requests/AccountsRetrieveRequest.cs new file mode 100644 index 00000000..70bf5d67 --- /dev/null +++ b/src/Merge.Client/Crm/Accounts/requests/AccountsRetrieveRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Crm; + +public class AccountsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Accounts/requests/CrmAccountEndpointRequest.cs b/src/Merge.Client/Crm/Accounts/requests/CrmAccountEndpointRequest.cs new file mode 100644 index 00000000..d94a28ed --- /dev/null +++ b/src/Merge.Client/Crm/Accounts/requests/CrmAccountEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CrmAccountEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AccountRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Accounts/requests/PatchedCrmAccountEndpointRequest.cs b/src/Merge.Client/Crm/Accounts/requests/PatchedCrmAccountEndpointRequest.cs new file mode 100644 index 00000000..d700dbcb --- /dev/null +++ b/src/Merge.Client/Crm/Accounts/requests/PatchedCrmAccountEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class PatchedCrmAccountEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedAccountRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/AssociationTypes/AssociationTypesClient.cs b/src/Merge.Client/Crm/AssociationTypes/AssociationTypesClient.cs index 929be37f..a187aa6c 100644 --- a/src/Merge.Client/Crm/AssociationTypes/AssociationTypesClient.cs +++ b/src/Merge.Client/Crm/AssociationTypes/AssociationTypesClient.cs @@ -1,13 +1,171 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AssociationTypesClient { - public async void CustomObjectClassesAssociationTypesList(){ + private RawClient _client; + + public AssociationTypesClient(RawClient client) + { + _client = client; } - public async void CustomObjectClassesAssociationTypesCreate(){ + + /// + /// Returns a list of `AssociationType` objects. + /// + public async Task CustomObjectClassesAssociationTypesListAsync( + string customObjectClassId, + CustomObjectClassesAssociationTypesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/custom-object-classes/{customObjectClassId}/association-types", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CustomObjectClassesAssociationTypesRetrieve(){ + + /// + /// Creates an `AssociationType` object with the given values. + /// + public async Task CustomObjectClassesAssociationTypesCreateAsync( + string customObjectClassId, + CrmAssociationTypeEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/crm/v1/custom-object-classes/{customObjectClassId}/association-types", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CustomObjectClassesAssociationTypesMetaPostRetrieve(){ + + /// + /// Returns an `AssociationType` object with the given `id`. + /// + public async Task CustomObjectClassesAssociationTypesRetrieveAsync( + string customObjectClassId, + string id, + CustomObjectClassesAssociationTypesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = + $"/crm/v1/custom-object-classes/{customObjectClassId}/association-types/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `CRMAssociationType` POSTs. + /// + public async Task CustomObjectClassesAssociationTypesMetaPostRetrieveAsync( + string customObjectClassId + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = + $"/crm/v1/custom-object-classes/{customObjectClassId}/association-types/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/AssociationTypes/requests/CrmAssociationTypeEndpointRequest.cs b/src/Merge.Client/Crm/AssociationTypes/requests/CrmAssociationTypeEndpointRequest.cs new file mode 100644 index 00000000..a3178701 --- /dev/null +++ b/src/Merge.Client/Crm/AssociationTypes/requests/CrmAssociationTypeEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CrmAssociationTypeEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AssociationTypeRequestRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesListRequest.cs b/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesListRequest.cs new file mode 100644 index 00000000..0f2f6391 --- /dev/null +++ b/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesAssociationTypesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesRetrieveRequest.cs b/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesRetrieveRequest.cs new file mode 100644 index 00000000..4880361b --- /dev/null +++ b/src/Merge.Client/Crm/AssociationTypes/requests/CustomObjectClassesAssociationTypesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesAssociationTypesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Crm/Associations/AssociationsClient.cs b/src/Merge.Client/Crm/Associations/AssociationsClient.cs index 9e9af899..fb76e5bc 100644 --- a/src/Merge.Client/Crm/Associations/AssociationsClient.cs +++ b/src/Merge.Client/Crm/Associations/AssociationsClient.cs @@ -1,9 +1,124 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AssociationsClient { - public async void CustomObjectClassesCustomObjectsAssociationsList(){ + private RawClient _client; + + public AssociationsClient(RawClient client) + { + _client = client; } - public async void CustomObjectClassesCustomObjectsAssociationsUpdate(){ + + /// + /// Returns a list of `Association` objects. + /// + public async Task CustomObjectClassesCustomObjectsAssociationsListAsync( + string customObjectClassId, + string objectId, + CustomObjectClassesCustomObjectsAssociationsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.AssociationTypeId != null) + { + _query["association_type_id"] = request.AssociationTypeId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = + $"/crm/v1/custom-object-classes/{customObjectClassId}/custom-objects/{objectId}/associations", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates an Association between `source_object_id` and `target_object_id` of type `association_type_id`. + /// + public async Task CustomObjectClassesCustomObjectsAssociationsUpdateAsync( + string associationTypeId, + string sourceClassId, + string sourceObjectId, + string targetClassId, + string targetObjectId, + CustomObjectClassesCustomObjectsAssociationsUpdateRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = + $"/crm/v1/custom-object-classes/{sourceClassId}/custom-objects/{sourceObjectId}/associations/{targetClassId}/{targetObjectId}/{associationTypeId}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsListRequest.cs b/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsListRequest.cs new file mode 100644 index 00000000..c40ea342 --- /dev/null +++ b/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesCustomObjectsAssociationsListRequest +{ + /// + /// If provided, will only return opportunities with this association_type. + /// + public string? AssociationTypeId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsUpdateRequest.cs b/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsUpdateRequest.cs new file mode 100644 index 00000000..8d647666 --- /dev/null +++ b/src/Merge.Client/Crm/Associations/requests/CustomObjectClassesCustomObjectsAssociationsUpdateRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesCustomObjectsAssociationsUpdateRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } +} diff --git a/src/Merge.Client/Crm/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Crm/AsyncPassthrough/AsyncPassthroughClient.cs index 452e80ba..df543949 100644 --- a/src/Merge.Client/Crm/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Crm/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Crm/AuditTrail/AuditTrailClient.cs index 34ee10d3..5657ef28 100644 --- a/src/Merge.Client/Crm/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Crm/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Crm/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..4e34734d --- /dev/null +++ b/src/Merge.Client/Crm/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Crm; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Crm/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Crm/AvailableActions/AvailableActionsClient.cs index 65f07bda..826b4b8f 100644 --- a/src/Merge.Client/Crm/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Crm/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,31 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/available-actions" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Contacts/ContactsClient.cs b/src/Merge.Client/Crm/Contacts/ContactsClient.cs index 0052d125..c87f7fca 100644 --- a/src/Merge.Client/Crm/Contacts/ContactsClient.cs +++ b/src/Merge.Client/Crm/Contacts/ContactsClient.cs @@ -1,21 +1,289 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class ContactsClient { - public async void List(){ + private RawClient _client; + + public ContactsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Contact` objects. + /// + public async Task ListAsync(ContactsListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountId != null) + { + _query["account_id"] = request.AccountId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmailAddresses != null) + { + _query["email_addresses"] = request.EmailAddresses; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.PhoneNumbers != null) + { + _query["phone_numbers"] = request.PhoneNumbers; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/contacts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `Contact` object with the given values. + /// + public async Task CreateAsync(CrmContactEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/contacts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Returns a `Contact` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ContactsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/contacts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void IgnoreCreate(){ + + /// + /// Updates a `Contact` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedCrmContactEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/contacts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Ignores a specific row based on the `model_id` in the url. These records will have their properties set to null, and will not be updated in future syncs. The "reason" and "message" fields in the request body will be stored for audit purposes. + /// + public async void IgnoreCreateAsync(string modelId, IgnoreCommonModelRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/crm/v1/contacts/ignore/{modelId}", + Body = request + } + ); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `CRMContact` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/contacts/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns metadata for `CRMContact` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/contacts/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + ContactsRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/contacts/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Contacts/requests/ContactsListRequest.cs b/src/Merge.Client/Crm/Contacts/requests/ContactsListRequest.cs new file mode 100644 index 00000000..8e15eb8f --- /dev/null +++ b/src/Merge.Client/Crm/Contacts/requests/ContactsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class ContactsListRequest +{ + /// + /// If provided, will only return contacts with this account. + /// + public string? AccountId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return contacts matching the email addresses; multiple email_addresses can be separated by commas. + /// + public string? EmailAddresses { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ContactsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return contacts matching the phone numbers; multiple phone numbers can be separated by commas. + /// + public string? PhoneNumbers { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Contacts/requests/ContactsRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Contacts/requests/ContactsRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..450e4e18 --- /dev/null +++ b/src/Merge.Client/Crm/Contacts/requests/ContactsRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class ContactsRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Contacts/requests/ContactsRetrieveRequest.cs b/src/Merge.Client/Crm/Contacts/requests/ContactsRetrieveRequest.cs new file mode 100644 index 00000000..5be722ae --- /dev/null +++ b/src/Merge.Client/Crm/Contacts/requests/ContactsRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class ContactsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ContactsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Contacts/requests/CrmContactEndpointRequest.cs b/src/Merge.Client/Crm/Contacts/requests/CrmContactEndpointRequest.cs new file mode 100644 index 00000000..a772c3ba --- /dev/null +++ b/src/Merge.Client/Crm/Contacts/requests/CrmContactEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CrmContactEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public ContactRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Contacts/requests/PatchedCrmContactEndpointRequest.cs b/src/Merge.Client/Crm/Contacts/requests/PatchedCrmContactEndpointRequest.cs new file mode 100644 index 00000000..a0efd93b --- /dev/null +++ b/src/Merge.Client/Crm/Contacts/requests/PatchedCrmContactEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class PatchedCrmContactEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedContactRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/CrmClient.cs b/src/Merge.Client/Crm/CrmClient.cs new file mode 100644 index 00000000..30632645 --- /dev/null +++ b/src/Merge.Client/Crm/CrmClient.cs @@ -0,0 +1,110 @@ +using Merge.Client; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CrmClient +{ + private RawClient _client; + + public CrmClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + Accounts = new AccountsClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + Contacts = new ContactsClient(_client); + CustomObjectClasses = new CustomObjectClassesClient(_client); + AssociationTypes = new AssociationTypesClient(_client); + CustomObjects = new CustomObjectsClient(_client); + Associations = new AssociationsClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + EngagementTypes = new EngagementTypesClient(_client); + Engagements = new EngagementsClient(_client); + FieldMapping = new FieldMappingClient(_client); + GenerateKey = new GenerateKeyClient(_client); + Issues = new IssuesClient(_client); + Leads = new LeadsClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Notes = new NotesClient(_client); + Opportunities = new OpportunitiesClient(_client); + Passthrough = new PassthroughClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + Stages = new StagesClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + Tasks = new TasksClient(_client); + Users = new UsersClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public AccountsClient Accounts { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public ContactsClient Contacts { get; } + + public CustomObjectClassesClient CustomObjectClasses { get; } + + public AssociationTypesClient AssociationTypes { get; } + + public CustomObjectsClient CustomObjects { get; } + + public AssociationsClient Associations { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public EngagementTypesClient EngagementTypes { get; } + + public EngagementsClient Engagements { get; } + + public FieldMappingClient FieldMapping { get; } + + public GenerateKeyClient GenerateKey { get; } + + public IssuesClient Issues { get; } + + public LeadsClient Leads { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public NotesClient Notes { get; } + + public OpportunitiesClient Opportunities { get; } + + public PassthroughClient Passthrough { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public StagesClient Stages { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public TasksClient Tasks { get; } + + public UsersClient Users { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Crm/CustomObjectClasses/CustomObjectClassesClient.cs b/src/Merge.Client/Crm/CustomObjectClasses/CustomObjectClassesClient.cs index 1c63e155..30f81354 100644 --- a/src/Merge.Client/Crm/CustomObjectClasses/CustomObjectClassesClient.cs +++ b/src/Merge.Client/Crm/CustomObjectClasses/CustomObjectClassesClient.cs @@ -1,9 +1,112 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class CustomObjectClassesClient { - public async void List(){ + private RawClient _client; + + public CustomObjectClassesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `CustomObjectClass` objects. + /// + public async Task ListAsync( + CustomObjectClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/custom-object-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `CustomObjectClass` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + CustomObjectClassesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/custom-object-classes/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesListRequest.cs b/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesListRequest.cs new file mode 100644 index 00000000..c1b44523 --- /dev/null +++ b/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesRetrieveRequest.cs b/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesRetrieveRequest.cs new file mode 100644 index 00000000..9e015cac --- /dev/null +++ b/src/Merge.Client/Crm/CustomObjectClasses/requests/CustomObjectClassesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Crm/CustomObjects/CustomObjectsClient.cs b/src/Merge.Client/Crm/CustomObjects/CustomObjectsClient.cs index c7212902..b043f197 100644 --- a/src/Merge.Client/Crm/CustomObjects/CustomObjectsClient.cs +++ b/src/Merge.Client/Crm/CustomObjects/CustomObjectsClient.cs @@ -1,15 +1,170 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class CustomObjectsClient { - public async void CustomObjectClassesCustomObjectsList(){ + private RawClient _client; + + public CustomObjectsClient(RawClient client) + { + _client = client; } - public async void CustomObjectClassesCustomObjectsCreate(){ + + /// + /// Returns a list of `CustomObject` objects. + /// + public async Task CustomObjectClassesCustomObjectsListAsync( + string customObjectClassId, + CustomObjectClassesCustomObjectsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/custom-object-classes/{customObjectClassId}/custom-objects", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CustomObjectClassesCustomObjectsRetrieve(){ + + /// + /// Creates a `CustomObject` object with the given values. + /// + public async Task CustomObjectClassesCustomObjectsCreateAsync( + string customObjectClassId, + CrmCustomObjectEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/crm/v1/custom-object-classes/{customObjectClassId}/custom-objects", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CustomObjectClassesCustomObjectsMetaPatchRetrieve(){ + + /// + /// Returns a `CustomObject` object with the given `id`. + /// + public async Task CustomObjectClassesCustomObjectsRetrieveAsync( + string customObjectClassId, + string id, + CustomObjectClassesCustomObjectsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/custom-object-classes/{customObjectClassId}/custom-objects/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CustomObjectClassesCustomObjectsMetaPostRetrieve(){ + + /// + /// Returns metadata for `CRMCustomObject` POSTs. + /// + public async Task CustomObjectClassesCustomObjectsMetaPostRetrieveAsync( + string customObjectClassId + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = + $"/crm/v1/custom-object-classes/{customObjectClassId}/custom-objects/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/CustomObjects/requests/CrmCustomObjectEndpointRequest.cs b/src/Merge.Client/Crm/CustomObjects/requests/CrmCustomObjectEndpointRequest.cs new file mode 100644 index 00000000..35d3662d --- /dev/null +++ b/src/Merge.Client/Crm/CustomObjects/requests/CrmCustomObjectEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CrmCustomObjectEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public CustomObjectRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsListRequest.cs b/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsListRequest.cs new file mode 100644 index 00000000..bd87985b --- /dev/null +++ b/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesCustomObjectsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsRetrieveRequest.cs b/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsRetrieveRequest.cs new file mode 100644 index 00000000..ef71d8d2 --- /dev/null +++ b/src/Merge.Client/Crm/CustomObjects/requests/CustomObjectClassesCustomObjectsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class CustomObjectClassesCustomObjectsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Crm/DeleteAccount/DeleteAccountClient.cs index 7216d4f5..3a2264a8 100644 --- a/src/Merge.Client/Crm/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Crm/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,23 @@ +using Merge.Client; + namespace Merge.Client.Crm; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Post, Path = "/crm/v1/delete-account" } + ); } } diff --git a/src/Merge.Client/Crm/EngagementTypes/EngagementTypesClient.cs b/src/Merge.Client/Crm/EngagementTypes/EngagementTypesClient.cs index 1ffef95c..132d1e82 100644 --- a/src/Merge.Client/Crm/EngagementTypes/EngagementTypesClient.cs +++ b/src/Merge.Client/Crm/EngagementTypes/EngagementTypesClient.cs @@ -1,11 +1,154 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class EngagementTypesClient { - public async void List(){ + private RawClient _client; + + public EngagementTypesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `EngagementType` objects. + /// + public async Task ListAsync(EngagementTypesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/engagement-types", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `EngagementType` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + EngagementTypesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/engagement-types/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + EngagementTypesRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/engagement-types/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesListRequest.cs b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesListRequest.cs new file mode 100644 index 00000000..0d348864 --- /dev/null +++ b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class EngagementTypesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..0ac977e0 --- /dev/null +++ b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class EngagementTypesRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRetrieveRequest.cs b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRetrieveRequest.cs new file mode 100644 index 00000000..9c2a3e0b --- /dev/null +++ b/src/Merge.Client/Crm/EngagementTypes/requests/EngagementTypesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class EngagementTypesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Engagements/EngagementsClient.cs b/src/Merge.Client/Crm/Engagements/EngagementsClient.cs index 0d30d2af..8d4a1eda 100644 --- a/src/Merge.Client/Crm/Engagements/EngagementsClient.cs +++ b/src/Merge.Client/Crm/Engagements/EngagementsClient.cs @@ -1,19 +1,270 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class EngagementsClient { - public async void List(){ + private RawClient _client; + + public EngagementsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Engagement` objects. + /// + public async Task ListAsync(EngagementsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/engagements", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates an `Engagement` object with the given values. + /// + public async Task CreateAsync(EngagementEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/engagements", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Engagement` object with the given `id`. + /// + public async Task RetrieveAsync(string id, EngagementsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/engagements/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Updates an `Engagement` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedEngagementEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/engagements/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns metadata for `Engagement` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/engagements/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Engagement` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/engagements/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + EngagementsRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/engagements/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Engagements/requests/EngagementEndpointRequest.cs b/src/Merge.Client/Crm/Engagements/requests/EngagementEndpointRequest.cs new file mode 100644 index 00000000..d7700899 --- /dev/null +++ b/src/Merge.Client/Crm/Engagements/requests/EngagementEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class EngagementEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public EngagementRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Engagements/requests/EngagementsListRequest.cs b/src/Merge.Client/Crm/Engagements/requests/EngagementsListRequest.cs new file mode 100644 index 00000000..879925fa --- /dev/null +++ b/src/Merge.Client/Crm/Engagements/requests/EngagementsListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class EngagementsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EngagementsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return engagements started after this datetime. + /// + public DateTime? StartedAfter { get; init; } + + /// + /// If provided, will only return engagements started before this datetime. + /// + public DateTime? StartedBefore { get; init; } +} diff --git a/src/Merge.Client/Crm/Engagements/requests/EngagementsRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Engagements/requests/EngagementsRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..878bd431 --- /dev/null +++ b/src/Merge.Client/Crm/Engagements/requests/EngagementsRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class EngagementsRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Engagements/requests/EngagementsRetrieveRequest.cs b/src/Merge.Client/Crm/Engagements/requests/EngagementsRetrieveRequest.cs new file mode 100644 index 00000000..1df750e7 --- /dev/null +++ b/src/Merge.Client/Crm/Engagements/requests/EngagementsRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class EngagementsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EngagementsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Engagements/requests/PatchedEngagementEndpointRequest.cs b/src/Merge.Client/Crm/Engagements/requests/PatchedEngagementEndpointRequest.cs new file mode 100644 index 00000000..0a26230d --- /dev/null +++ b/src/Merge.Client/Crm/Engagements/requests/PatchedEngagementEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class PatchedEngagementEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedEngagementRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Crm/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..eb89d7d9 --- /dev/null +++ b/src/Merge.Client/Crm/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,146 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/field-mappings" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/crm/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/target-fields" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Crm/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Crm/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..4fea3a21 --- /dev/null +++ b/src/Merge.Client/Crm/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Crm; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Crm/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Crm/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..aed6dc7b --- /dev/null +++ b/src/Merge.Client/Crm/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Crm; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Crm/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Crm/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..12dbacdd --- /dev/null +++ b/src/Merge.Client/Crm/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Crm/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Crm/ForceResync/ForceResyncClient.cs index 9b7098e6..c2d9b032 100644 --- a/src/Merge.Client/Crm/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Crm/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Crm/GenerateKey/GenerateKeyClient.cs index 07a25363..5bc3b49a 100644 --- a/src/Merge.Client/Crm/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Crm/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Crm/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..a312f275 --- /dev/null +++ b/src/Merge.Client/Crm/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Crm; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Crm/Issues/IssuesClient.cs b/src/Merge.Client/Crm/Issues/IssuesClient.cs index 00a3bfbf..39097539 100644 --- a/src/Merge.Client/Crm/Issues/IssuesClient.cs +++ b/src/Merge.Client/Crm/Issues/IssuesClient.cs @@ -1,9 +1,105 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = $"/crm/v1/issues/{id}" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Crm/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..5b4e57f8 --- /dev/null +++ b/src/Merge.Client/Crm/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Crm/Leads/LeadsClient.cs b/src/Merge.Client/Crm/Leads/LeadsClient.cs index 8e3334a7..ef601b26 100644 --- a/src/Merge.Client/Crm/Leads/LeadsClient.cs +++ b/src/Merge.Client/Crm/Leads/LeadsClient.cs @@ -1,15 +1,225 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class LeadsClient { - public async void List(){ + private RawClient _client; + + public LeadsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Lead` objects. + /// + public async Task ListAsync(LeadsListRequest request) + { + var _query = new Dictionary() { }; + if (request.ConvertedAccountId != null) + { + _query["converted_account_id"] = request.ConvertedAccountId; + } + if (request.ConvertedContactId != null) + { + _query["converted_contact_id"] = request.ConvertedContactId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmailAddresses != null) + { + _query["email_addresses"] = request.EmailAddresses; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OwnerId != null) + { + _query["owner_id"] = request.OwnerId; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.PhoneNumbers != null) + { + _query["phone_numbers"] = request.PhoneNumbers; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/leads", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates a `Lead` object with the given values. + /// + public async Task CreateAsync(LeadEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/leads", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Lead` object with the given `id`. + /// + public async Task RetrieveAsync(string id, LeadsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/leads/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Lead` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/leads/meta/post" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + LeadsRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/leads/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Leads/requests/LeadEndpointRequest.cs b/src/Merge.Client/Crm/Leads/requests/LeadEndpointRequest.cs new file mode 100644 index 00000000..1be70175 --- /dev/null +++ b/src/Merge.Client/Crm/Leads/requests/LeadEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LeadEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public LeadRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Leads/requests/LeadsListRequest.cs b/src/Merge.Client/Crm/Leads/requests/LeadsListRequest.cs new file mode 100644 index 00000000..2cf71c0e --- /dev/null +++ b/src/Merge.Client/Crm/Leads/requests/LeadsListRequest.cs @@ -0,0 +1,86 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LeadsListRequest +{ + /// + /// If provided, will only return leads with this account. + /// + public string? ConvertedAccountId { get; init; } + + /// + /// If provided, will only return leads with this contact. + /// + public string? ConvertedContactId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return contacts matching the email addresses; multiple email_addresses can be separated by commas. + /// + public string? EmailAddresses { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public LeadsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return leads with this owner. + /// + public string? OwnerId { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return contacts matching the phone numbers; multiple phone numbers can be separated by commas. + /// + public string? PhoneNumbers { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Leads/requests/LeadsRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Leads/requests/LeadsRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..aa19d6fe --- /dev/null +++ b/src/Merge.Client/Crm/Leads/requests/LeadsRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class LeadsRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Leads/requests/LeadsRetrieveRequest.cs b/src/Merge.Client/Crm/Leads/requests/LeadsRetrieveRequest.cs new file mode 100644 index 00000000..b2a1bbb3 --- /dev/null +++ b/src/Merge.Client/Crm/Leads/requests/LeadsRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LeadsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public LeadsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Crm/LinkToken/LinkTokenClient.cs index d574bf5d..82ea0f94 100644 --- a/src/Merge.Client/Crm/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Crm/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Crm/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..6abca1db --- /dev/null +++ b/src/Merge.Client/Crm/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Crm/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Crm/LinkedAccounts/LinkedAccountsClient.cs index 3f9a779d..1e4c4589 100644 --- a/src/Merge.Client/Crm/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Crm/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Crm/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..2a1198cb --- /dev/null +++ b/src/Merge.Client/Crm/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LinkedAccountsListRequest +{ + /// + /// Options: `accounting`, `ats`, `crm`, `filestorage`, `hris`, `mktg`, `ticketing` + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Crm/Notes/NotesClient.cs b/src/Merge.Client/Crm/Notes/NotesClient.cs index 78dc1ea8..cbf75974 100644 --- a/src/Merge.Client/Crm/Notes/NotesClient.cs +++ b/src/Merge.Client/Crm/Notes/NotesClient.cs @@ -1,15 +1,221 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class NotesClient { - public async void List(){ + private RawClient _client; + + public NotesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Note` objects. + /// + public async Task ListAsync(NotesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountId != null) + { + _query["account_id"] = request.AccountId; + } + if (request.ContactId != null) + { + _query["contact_id"] = request.ContactId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OpportunityId != null) + { + _query["opportunity_id"] = request.OpportunityId; + } + if (request.OwnerId != null) + { + _query["owner_id"] = request.OwnerId; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/notes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates a `Note` object with the given values. + /// + public async Task CreateAsync(NoteEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/notes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Note` object with the given `id`. + /// + public async Task RetrieveAsync(string id, NotesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/notes/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Note` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/notes/meta/post" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + NotesRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/notes/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Notes/requests/NoteEndpointRequest.cs b/src/Merge.Client/Crm/Notes/requests/NoteEndpointRequest.cs new file mode 100644 index 00000000..e5254fbf --- /dev/null +++ b/src/Merge.Client/Crm/Notes/requests/NoteEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class NoteEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public NoteRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Notes/requests/NotesListRequest.cs b/src/Merge.Client/Crm/Notes/requests/NotesListRequest.cs new file mode 100644 index 00000000..9c4627c1 --- /dev/null +++ b/src/Merge.Client/Crm/Notes/requests/NotesListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class NotesListRequest +{ + /// + /// If provided, will only return notes with this account. + /// + public string? AccountId { get; init; } + + /// + /// If provided, will only return notes with this contact. + /// + public string? ContactId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public NotesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return notes with this opportunity. + /// + public string? OpportunityId { get; init; } + + /// + /// If provided, will only return notes with this owner. + /// + public string? OwnerId { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Notes/requests/NotesRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Notes/requests/NotesRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..59289a8f --- /dev/null +++ b/src/Merge.Client/Crm/Notes/requests/NotesRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class NotesRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Notes/requests/NotesRetrieveRequest.cs b/src/Merge.Client/Crm/Notes/requests/NotesRetrieveRequest.cs new file mode 100644 index 00000000..7f876850 --- /dev/null +++ b/src/Merge.Client/Crm/Notes/requests/NotesRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class NotesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public NotesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Opportunities/OpportunitiesClient.cs b/src/Merge.Client/Crm/Opportunities/OpportunitiesClient.cs index 3c325b6f..e7fbc96e 100644 --- a/src/Merge.Client/Crm/Opportunities/OpportunitiesClient.cs +++ b/src/Merge.Client/Crm/Opportunities/OpportunitiesClient.cs @@ -1,19 +1,294 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class OpportunitiesClient { - public async void List(){ + private RawClient _client; + + public OpportunitiesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Opportunity` objects. + /// + public async Task ListAsync(OpportunitiesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountId != null) + { + _query["account_id"] = request.AccountId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OwnerId != null) + { + _query["owner_id"] = request.OwnerId; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.StageId != null) + { + _query["stage_id"] = request.StageId; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/opportunities", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates an `Opportunity` object with the given values. + /// + public async Task CreateAsync(OpportunityEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/opportunities", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Opportunity` object with the given `id`. + /// + public async Task RetrieveAsync(string id, OpportunitiesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/opportunities/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Updates an `Opportunity` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedOpportunityEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/opportunities/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns metadata for `Opportunity` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/opportunities/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Opportunity` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/opportunities/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + OpportunitiesRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/opportunities/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesListRequest.cs b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesListRequest.cs new file mode 100644 index 00000000..d8d8f668 --- /dev/null +++ b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesListRequest.cs @@ -0,0 +1,95 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class OpportunitiesListRequest +{ + /// + /// If provided, will only return opportunities with this account. + /// + public string? AccountId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public OpportunitiesListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return opportunities with this owner. + /// + public string? OwnerId { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return opportunities with this stage. + /// + public string? StageId { get; init; } + + /// + /// If provided, will only return opportunities with this status. Options: ('OPEN', 'WON', 'LOST') + /// + /// - `OPEN` - OPEN + /// - `WON` - WON + /// - `LOST` - LOST + /// + public OpportunitiesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..7a2871b5 --- /dev/null +++ b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class OpportunitiesRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRetrieveRequest.cs b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRetrieveRequest.cs new file mode 100644 index 00000000..47a62a68 --- /dev/null +++ b/src/Merge.Client/Crm/Opportunities/requests/OpportunitiesRetrieveRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class OpportunitiesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public OpportunitiesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Crm/Opportunities/requests/OpportunityEndpointRequest.cs b/src/Merge.Client/Crm/Opportunities/requests/OpportunityEndpointRequest.cs new file mode 100644 index 00000000..2654b0a4 --- /dev/null +++ b/src/Merge.Client/Crm/Opportunities/requests/OpportunityEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class OpportunityEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public OpportunityRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Opportunities/requests/PatchedOpportunityEndpointRequest.cs b/src/Merge.Client/Crm/Opportunities/requests/PatchedOpportunityEndpointRequest.cs new file mode 100644 index 00000000..ab61d72a --- /dev/null +++ b/src/Merge.Client/Crm/Opportunities/requests/PatchedOpportunityEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class PatchedOpportunityEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedOpportunityRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Passthrough/PassthroughClient.cs b/src/Merge.Client/Crm/Passthrough/PassthroughClient.cs index 1cb620cc..bc14fe53 100644 --- a/src/Merge.Client/Crm/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Crm/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Crm/RegenerateKey/RegenerateKeyClient.cs index 21931e6e..2653a32a 100644 --- a/src/Merge.Client/Crm/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Crm/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Crm/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..a879157c --- /dev/null +++ b/src/Merge.Client/Crm/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Crm; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Crm/Scopes/ScopesClient.cs b/src/Merge.Client/Crm/Scopes/ScopesClient.cs new file mode 100644 index 00000000..b0aa30da --- /dev/null +++ b/src/Merge.Client/Crm/Scopes/ScopesClient.cs @@ -0,0 +1,74 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/default-scopes" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Crm/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Crm/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..d2a7828b --- /dev/null +++ b/src/Merge.Client/Crm/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Crm/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Crm/SelectiveSync/SelectiveSyncClient.cs index 2b550ada..47c00584 100644 --- a/src/Merge.Client/Crm/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Crm/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/crm/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Crm/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..6ac56501 --- /dev/null +++ b/src/Merge.Client/Crm/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Crm/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Crm/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..b8e21ddb --- /dev/null +++ b/src/Merge.Client/Crm/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Crm; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Stages/StagesClient.cs b/src/Merge.Client/Crm/Stages/StagesClient.cs index 1d1dd403..8ab09301 100644 --- a/src/Merge.Client/Crm/Stages/StagesClient.cs +++ b/src/Merge.Client/Crm/Stages/StagesClient.cs @@ -1,11 +1,151 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class StagesClient { - public async void List(){ + private RawClient _client; + + public StagesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Stage` objects. + /// + public async Task ListAsync(StagesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/stages", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Stage` object with the given `id`. + /// + public async Task RetrieveAsync(string id, StagesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/stages/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + StagesRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/stages/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Stages/requests/StagesListRequest.cs b/src/Merge.Client/Crm/Stages/requests/StagesListRequest.cs new file mode 100644 index 00000000..0b1bc4bc --- /dev/null +++ b/src/Merge.Client/Crm/Stages/requests/StagesListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class StagesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Stages/requests/StagesRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Stages/requests/StagesRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..41322576 --- /dev/null +++ b/src/Merge.Client/Crm/Stages/requests/StagesRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class StagesRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Stages/requests/StagesRetrieveRequest.cs b/src/Merge.Client/Crm/Stages/requests/StagesRetrieveRequest.cs new file mode 100644 index 00000000..83d94c9a --- /dev/null +++ b/src/Merge.Client/Crm/Stages/requests/StagesRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class StagesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Crm/SyncStatus/SyncStatusClient.cs index 91f54ef0..e5e076e3 100644 --- a/src/Merge.Client/Crm/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Crm/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Crm/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..283ec694 --- /dev/null +++ b/src/Merge.Client/Crm/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Tasks/TasksClient.cs b/src/Merge.Client/Crm/Tasks/TasksClient.cs index cd2fff68..9e63c76a 100644 --- a/src/Merge.Client/Crm/Tasks/TasksClient.cs +++ b/src/Merge.Client/Crm/Tasks/TasksClient.cs @@ -1,19 +1,258 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class TasksClient { - public async void List(){ + private RawClient _client; + + public TasksClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Task` objects. + /// + public async Task ListAsync(TasksListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/tasks", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `Task` object with the given values. + /// + public async Task CreateAsync(TaskEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/tasks", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Task` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TasksRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/tasks/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Updates a `Task` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedTaskEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/crm/v1/tasks/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns metadata for `Task` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/tasks/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Task` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/tasks/meta/post" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + TasksRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/tasks/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Tasks/requests/PatchedTaskEndpointRequest.cs b/src/Merge.Client/Crm/Tasks/requests/PatchedTaskEndpointRequest.cs new file mode 100644 index 00000000..a02c95da --- /dev/null +++ b/src/Merge.Client/Crm/Tasks/requests/PatchedTaskEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class PatchedTaskEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedTaskRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Tasks/requests/TaskEndpointRequest.cs b/src/Merge.Client/Crm/Tasks/requests/TaskEndpointRequest.cs new file mode 100644 index 00000000..99bb5b85 --- /dev/null +++ b/src/Merge.Client/Crm/Tasks/requests/TaskEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class TaskEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public TaskRequest Model { get; init; } +} diff --git a/src/Merge.Client/Crm/Tasks/requests/TasksListRequest.cs b/src/Merge.Client/Crm/Tasks/requests/TasksListRequest.cs new file mode 100644 index 00000000..cae2cd04 --- /dev/null +++ b/src/Merge.Client/Crm/Tasks/requests/TasksListRequest.cs @@ -0,0 +1,61 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class TasksListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TasksListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Tasks/requests/TasksRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Tasks/requests/TasksRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..cb8d93e9 --- /dev/null +++ b/src/Merge.Client/Crm/Tasks/requests/TasksRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class TasksRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Tasks/requests/TasksRetrieveRequest.cs b/src/Merge.Client/Crm/Tasks/requests/TasksRetrieveRequest.cs new file mode 100644 index 00000000..e065fcf4 --- /dev/null +++ b/src/Merge.Client/Crm/Tasks/requests/TasksRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class TasksRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TasksRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/Account.cs b/src/Merge.Client/Crm/Types/Account.cs index e518fb55..38c5376a 100644 --- a/src/Merge.Client/Crm/Types/Account.cs +++ b/src/Merge.Client/Crm/Types/Account.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Account { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The account's owner. /// @@ -69,24 +87,6 @@ public class Account [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Crm/Types/AccountDetailsAndActions.cs index 15c58f27..5a4cf873 100644 --- a/src/Merge.Client/Crm/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Crm/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Crm/Types/AccountIntegration.cs b/src/Merge.Client/Crm/Types/AccountIntegration.cs index b6c140c4..3ceac9c3 100644 --- a/src/Merge.Client/Crm/Types/AccountIntegration.cs +++ b/src/Merge.Client/Crm/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Crm/Types/AccountRequest.cs b/src/Merge.Client/Crm/Types/AccountRequest.cs index 8d0bc327..f2c0c2ac 100644 --- a/src/Merge.Client/Crm/Types/AccountRequest.cs +++ b/src/Merge.Client/Crm/Types/AccountRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/Address.cs b/src/Merge.Client/Crm/Types/Address.cs index ebd35061..33ebd32c 100644 --- a/src/Merge.Client/Crm/Types/Address.cs +++ b/src/Merge.Client/Crm/Types/Address.cs @@ -5,6 +5,15 @@ namespace Merge.Client.Crm; public class Address { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// Line 1 of the address's street. /// @@ -37,7 +46,7 @@ public class Address /// /// The address's country. - /// + /// /// - `AF` - Afghanistan /// - `AX` - Åland Islands /// - `AL` - Albania @@ -293,19 +302,10 @@ public class Address /// /// The address type. - /// + /// /// - `BILLING` - BILLING /// - `SHIPPING` - SHIPPING /// [JsonPropertyName("address_type")] public AddressTypeEnum? AddressType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Crm/Types/AddressRequest.cs b/src/Merge.Client/Crm/Types/AddressRequest.cs index c871d9e3..27b5972a 100644 --- a/src/Merge.Client/Crm/Types/AddressRequest.cs +++ b/src/Merge.Client/Crm/Types/AddressRequest.cs @@ -37,7 +37,7 @@ public class AddressRequest /// /// The address's country. - /// + /// /// - `AF` - Afghanistan /// - `AX` - Åland Islands /// - `AL` - Albania @@ -293,7 +293,7 @@ public class AddressRequest /// /// The address type. - /// + /// /// - `BILLING` - BILLING /// - `SHIPPING` - SHIPPING /// diff --git a/src/Merge.Client/Crm/Types/AdvancedMetadata.cs b/src/Merge.Client/Crm/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..d85404e5 --- /dev/null +++ b/src/Merge.Client/Crm/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/Association.cs b/src/Merge.Client/Crm/Types/Association.cs index 2f97a64c..ae287ac8 100644 --- a/src/Merge.Client/Crm/Types/Association.cs +++ b/src/Merge.Client/Crm/Types/Association.cs @@ -1,20 +1,11 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Association { - [JsonPropertyName("source_object")] - public Dictionary? SourceObject { get; init; } - - [JsonPropertyName("target_object")] - public Dictionary? TargetObject { get; init; } - - [JsonPropertyName("association_type")] - public OneOf? AssociationType { get; init; } - [JsonPropertyName("created_at")] public DateTime? CreatedAt { get; init; } @@ -23,4 +14,13 @@ public class Association /// [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + + [JsonPropertyName("source_object")] + public Dictionary? SourceObject { get; init; } + + [JsonPropertyName("target_object")] + public Dictionary? TargetObject { get; init; } + + [JsonPropertyName("association_type")] + public OneOf? AssociationType { get; init; } } diff --git a/src/Merge.Client/Crm/Types/AssociationSubType.cs b/src/Merge.Client/Crm/Types/AssociationSubType.cs index 7060fc9a..a75a41f7 100644 --- a/src/Merge.Client/Crm/Types/AssociationSubType.cs +++ b/src/Merge.Client/Crm/Types/AssociationSubType.cs @@ -7,9 +7,6 @@ public class AssociationSubType [JsonPropertyName("id")] public string? Id { get; init; } - [JsonPropertyName("origin_type")] - public string? OriginType { get; init; } - [JsonPropertyName("created_at")] public DateTime? CreatedAt { get; init; } @@ -18,4 +15,7 @@ public class AssociationSubType /// [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + + [JsonPropertyName("origin_type")] + public string? OriginType { get; init; } } diff --git a/src/Merge.Client/Crm/Types/AssociationType.cs b/src/Merge.Client/Crm/Types/AssociationType.cs index 0e631fac..0940b2fc 100644 --- a/src/Merge.Client/Crm/Types/AssociationType.cs +++ b/src/Merge.Client/Crm/Types/AssociationType.cs @@ -5,24 +5,6 @@ namespace Merge.Client.Crm; public class AssociationType { - [JsonPropertyName("source_object_class")] - public Dictionary? SourceObjectClass { get; init; } - - [JsonPropertyName("target_object_classes")] - public List? TargetObjectClasses { get; init; } - - [JsonPropertyName("remote_key_name")] - public string? RemoteKeyName { get; init; } - - [JsonPropertyName("display_name")] - public string? DisplayName { get; init; } - - [JsonPropertyName("cardinality")] - public CardinalityEnum? Cardinality { get; init; } - - [JsonPropertyName("is_required")] - public bool? IsRequired { get; init; } - [JsonPropertyName("id")] public string? Id { get; init; } @@ -40,4 +22,22 @@ public class AssociationType /// [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + + [JsonPropertyName("source_object_class")] + public Dictionary? SourceObjectClass { get; init; } + + [JsonPropertyName("target_object_classes")] + public List? TargetObjectClasses { get; init; } + + [JsonPropertyName("remote_key_name")] + public string? RemoteKeyName { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("cardinality")] + public CardinalityEnum? Cardinality { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } } diff --git a/src/Merge.Client/Crm/Types/AuditLogEvent.cs b/src/Merge.Client/Crm/Types/AuditLogEvent.cs index fa6d7a04..b8846eb4 100644 --- a/src/Merge.Client/Crm/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Crm/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Crm/Types/CommonModelScopeApi.cs b/src/Merge.Client/Crm/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..c74b3e07 --- /dev/null +++ b/src/Merge.Client/Crm/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/ConditionSchema.cs b/src/Merge.Client/Crm/Types/ConditionSchema.cs index 70a955c3..2d17957f 100644 --- a/src/Merge.Client/Crm/Types/ConditionSchema.cs +++ b/src/Merge.Client/Crm/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Crm/Types/Contact.cs b/src/Merge.Client/Crm/Types/Contact.cs index a2b8de0f..6c4aed18 100644 --- a/src/Merge.Client/Crm/Types/Contact.cs +++ b/src/Merge.Client/Crm/Types/Contact.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Contact { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The contact's first name. /// @@ -54,24 +72,6 @@ public class Contact [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/ContactRequest.cs b/src/Merge.Client/Crm/Types/ContactRequest.cs index 9d7b567a..23f962c8 100644 --- a/src/Merge.Client/Crm/Types/ContactRequest.cs +++ b/src/Merge.Client/Crm/Types/ContactRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/CustomObject.cs b/src/Merge.Client/Crm/Types/CustomObject.cs index 26cc5aac..52efe83b 100644 --- a/src/Merge.Client/Crm/Types/CustomObject.cs +++ b/src/Merge.Client/Crm/Types/CustomObject.cs @@ -5,11 +5,8 @@ namespace Merge.Client.Crm; public class CustomObject { - [JsonPropertyName("object_class")] - public string? ObjectClass { get; init; } - - [JsonPropertyName("fields")] - public Dictionary? Fields { get; init; } + [JsonPropertyName("id")] + public string? Id { get; init; } /// /// The third-party API ID of the matching object. @@ -17,9 +14,6 @@ public class CustomObject [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - [JsonPropertyName("created_at")] public DateTime? CreatedAt { get; init; } @@ -29,6 +23,12 @@ public class CustomObject [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("object_class")] + public string? ObjectClass { get; init; } + + [JsonPropertyName("fields")] + public Dictionary? Fields { get; init; } + [JsonPropertyName("remote_fields")] public List? RemoteFields { get; init; } } diff --git a/src/Merge.Client/Crm/Types/CustomObjectClass.cs b/src/Merge.Client/Crm/Types/CustomObjectClass.cs index 01d80d60..39c4ed1e 100644 --- a/src/Merge.Client/Crm/Types/CustomObjectClass.cs +++ b/src/Merge.Client/Crm/Types/CustomObjectClass.cs @@ -5,21 +5,6 @@ namespace Merge.Client.Crm; public class CustomObjectClass { - [JsonPropertyName("name")] - public string? Name { get; init; } - - [JsonPropertyName("description")] - public string? Description { get; init; } - - [JsonPropertyName("labels")] - public Dictionary? Labels { get; init; } - - [JsonPropertyName("fields")] - public List? Fields { get; init; } - - [JsonPropertyName("association_types")] - public List>? AssociationTypes { get; init; } - [JsonPropertyName("id")] public string? Id { get; init; } @@ -34,4 +19,19 @@ public class CustomObjectClass [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("labels")] + public Dictionary? Labels { get; init; } + + [JsonPropertyName("fields")] + public List? Fields { get; init; } + + [JsonPropertyName("association_types")] + public List>? AssociationTypes { get; init; } } diff --git a/src/Merge.Client/Crm/Types/DataPassthroughRequest.cs b/src/Merge.Client/Crm/Types/DataPassthroughRequest.cs index fe6002f5..2caa80f9 100644 --- a/src/Merge.Client/Crm/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Crm/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Crm/Types/EmailAddress.cs b/src/Merge.Client/Crm/Types/EmailAddress.cs index 4fa15de1..5d31b083 100644 --- a/src/Merge.Client/Crm/Types/EmailAddress.cs +++ b/src/Merge.Client/Crm/Types/EmailAddress.cs @@ -4,6 +4,15 @@ namespace Merge.Client.Crm; public class EmailAddress { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The email address. /// @@ -15,13 +24,4 @@ public class EmailAddress /// [JsonPropertyName("email_address_type")] public string? EmailAddressType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Crm/Types/Engagement.cs b/src/Merge.Client/Crm/Types/Engagement.cs index 248b56cf..59938338 100644 --- a/src/Merge.Client/Crm/Types/Engagement.cs +++ b/src/Merge.Client/Crm/Types/Engagement.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Engagement { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The engagement's owner. /// @@ -26,7 +44,7 @@ public class Engagement /// /// The engagement's direction. - /// + /// /// - `INBOUND` - INBOUND /// - `OUTBOUND` - OUTBOUND /// @@ -66,24 +84,6 @@ public class Engagement [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/EngagementRequest.cs b/src/Merge.Client/Crm/Types/EngagementRequest.cs index ffc569db..493fa888 100644 --- a/src/Merge.Client/Crm/Types/EngagementRequest.cs +++ b/src/Merge.Client/Crm/Types/EngagementRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; @@ -26,7 +26,7 @@ public class EngagementRequest /// /// The engagement's direction. - /// + /// /// - `INBOUND` - INBOUND /// - `OUTBOUND` - OUTBOUND /// diff --git a/src/Merge.Client/Crm/Types/EngagementType.cs b/src/Merge.Client/Crm/Types/EngagementType.cs index c9279b5f..68b05ce8 100644 --- a/src/Merge.Client/Crm/Types/EngagementType.cs +++ b/src/Merge.Client/Crm/Types/EngagementType.cs @@ -5,22 +5,6 @@ namespace Merge.Client.Crm; public class EngagementType { - /// - /// The engagement type's activity type. - /// - /// - `CALL` - CALL - /// - `MEETING` - MEETING - /// - `EMAIL` - EMAIL - /// - [JsonPropertyName("activity_type")] - public ActivityTypeEnum? ActivityType { get; init; } - - /// - /// The engagement type's name. - /// - [JsonPropertyName("name")] - public string? Name { get; init; } - [JsonPropertyName("id")] public string? Id { get; init; } @@ -39,6 +23,22 @@ public class EngagementType [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + /// + /// The engagement type's activity type. + /// + /// - `CALL` - CALL + /// - `MEETING` - MEETING + /// - `EMAIL` - EMAIL + /// + [JsonPropertyName("activity_type")] + public ActivityTypeEnum? ActivityType { get; init; } + + /// + /// The engagement type's name. + /// + [JsonPropertyName("name")] + public string? Name { get; init; } + [JsonPropertyName("remote_fields")] public List? RemoteFields { get; init; } } diff --git a/src/Merge.Client/Crm/Types/EventTypeEnum.cs b/src/Merge.Client/Crm/Types/EventTypeEnum.cs index e789ab32..2e90505d 100644 --- a/src/Merge.Client/Crm/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Crm/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Crm/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Crm/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..e652ad0a --- /dev/null +++ b/src/Merge.Client/Crm/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Crm/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..ad27507d --- /dev/null +++ b/src/Merge.Client/Crm/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("Lead")] + public List? Lead { get; init; } + + [JsonPropertyName("Note")] + public List? Note { get; init; } + + [JsonPropertyName("Opportunity")] + public List? Opportunity { get; init; } + + [JsonPropertyName("Stage")] + public List? Stage { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Task")] + public List? Task { get; init; } + + [JsonPropertyName("Engagement")] + public List? Engagement { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Crm/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..d121cca4 --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..8f6162c5 --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..030b834c --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..cdcc31da --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("Lead")] + public List? Lead { get; init; } + + [JsonPropertyName("Note")] + public List? Note { get; init; } + + [JsonPropertyName("Opportunity")] + public List? Opportunity { get; init; } + + [JsonPropertyName("Stage")] + public List? Stage { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Task")] + public List? Task { get; init; } + + [JsonPropertyName("Engagement")] + public List? Engagement { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..d2dbb67a --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Crm/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..54b9d572 --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Crm/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..2ef36094 --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Crm/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..dcafb82d --- /dev/null +++ b/src/Merge.Client/Crm/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..19c5ed1f --- /dev/null +++ b/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..661cab6c --- /dev/null +++ b/src/Merge.Client/Crm/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/Issue.cs b/src/Merge.Client/Crm/Types/Issue.cs index d1e1c021..2006e13b 100644 --- a/src/Merge.Client/Crm/Types/Issue.cs +++ b/src/Merge.Client/Crm/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Crm/Types/Lead.cs b/src/Merge.Client/Crm/Types/Lead.cs index 0547e399..9dcd7adc 100644 --- a/src/Merge.Client/Crm/Types/Lead.cs +++ b/src/Merge.Client/Crm/Types/Lead.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Lead { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The lead's owner. /// @@ -84,24 +102,6 @@ public class Lead [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/LeadRequest.cs b/src/Merge.Client/Crm/Types/LeadRequest.cs index e25697ef..58a44bc0 100644 --- a/src/Merge.Client/Crm/Types/LeadRequest.cs +++ b/src/Merge.Client/Crm/Types/LeadRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/LinkedAccountCondition.cs b/src/Merge.Client/Crm/Types/LinkedAccountCondition.cs index 806bf014..d0d195c0 100644 --- a/src/Merge.Client/Crm/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Crm/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Crm/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Crm/Types/LinkedAccountConditionRequest.cs index 8540f908..4c329111 100644 --- a/src/Merge.Client/Crm/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Crm/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Crm; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Crm/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Crm/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..fff413ac --- /dev/null +++ b/src/Merge.Client/Crm/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Crm/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..2454d1d5 --- /dev/null +++ b/src/Merge.Client/Crm/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Crm/Types/MultipartFormFieldRequest.cs index e4aa2bd1..850a88ff 100644 --- a/src/Merge.Client/Crm/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Crm/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Crm/Types/Note.cs b/src/Merge.Client/Crm/Types/Note.cs index 3e97c672..34c6cff3 100644 --- a/src/Merge.Client/Crm/Types/Note.cs +++ b/src/Merge.Client/Crm/Types/Note.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Note { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The note's owner. /// @@ -51,24 +69,6 @@ public class Note [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/NoteRequest.cs b/src/Merge.Client/Crm/Types/NoteRequest.cs index 6998bbf7..db77f896 100644 --- a/src/Merge.Client/Crm/Types/NoteRequest.cs +++ b/src/Merge.Client/Crm/Types/NoteRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/Opportunity.cs b/src/Merge.Client/Crm/Types/Opportunity.cs index 894f67b1..3a7fe182 100644 --- a/src/Merge.Client/Crm/Types/Opportunity.cs +++ b/src/Merge.Client/Crm/Types/Opportunity.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Opportunity { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The opportunity's name. /// @@ -44,7 +62,7 @@ public class Opportunity /// /// The opportunity's status. - /// + /// /// - `OPEN` - OPEN /// - `WON` - WON /// - `LOST` - LOST @@ -73,24 +91,6 @@ public class Opportunity [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/OpportunityRequest.cs b/src/Merge.Client/Crm/Types/OpportunityRequest.cs index 19709684..29210a20 100644 --- a/src/Merge.Client/Crm/Types/OpportunityRequest.cs +++ b/src/Merge.Client/Crm/Types/OpportunityRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; @@ -44,7 +44,7 @@ public class OpportunityRequest /// /// The opportunity's status. - /// + /// /// - `OPEN` - OPEN /// - `WON` - WON /// - `LOST` - LOST diff --git a/src/Merge.Client/Crm/Types/PatchedContactRequest.cs b/src/Merge.Client/Crm/Types/PatchedContactRequest.cs index e71a7311..712f9d3f 100644 --- a/src/Merge.Client/Crm/Types/PatchedContactRequest.cs +++ b/src/Merge.Client/Crm/Types/PatchedContactRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/PatchedEngagementRequest.cs b/src/Merge.Client/Crm/Types/PatchedEngagementRequest.cs index f7bedbb0..97171521 100644 --- a/src/Merge.Client/Crm/Types/PatchedEngagementRequest.cs +++ b/src/Merge.Client/Crm/Types/PatchedEngagementRequest.cs @@ -25,7 +25,7 @@ public class PatchedEngagementRequest /// /// The engagement's direction. - /// + /// /// - `INBOUND` - INBOUND /// - `OUTBOUND` - OUTBOUND /// diff --git a/src/Merge.Client/Crm/Types/PatchedOpportunityRequest.cs b/src/Merge.Client/Crm/Types/PatchedOpportunityRequest.cs index 85ca505f..506d6440 100644 --- a/src/Merge.Client/Crm/Types/PatchedOpportunityRequest.cs +++ b/src/Merge.Client/Crm/Types/PatchedOpportunityRequest.cs @@ -43,7 +43,7 @@ public class PatchedOpportunityRequest /// /// The opportunity's status. - /// + /// /// - `OPEN` - OPEN /// - `WON` - WON /// - `LOST` - LOST diff --git a/src/Merge.Client/Crm/Types/PatchedTaskRequest.cs b/src/Merge.Client/Crm/Types/PatchedTaskRequest.cs index 34768a61..c38d8e61 100644 --- a/src/Merge.Client/Crm/Types/PatchedTaskRequest.cs +++ b/src/Merge.Client/Crm/Types/PatchedTaskRequest.cs @@ -49,7 +49,7 @@ public class PatchedTaskRequest /// /// The task's status. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// diff --git a/src/Merge.Client/Crm/Types/PhoneNumber.cs b/src/Merge.Client/Crm/Types/PhoneNumber.cs index 5f019beb..ed4b3f2f 100644 --- a/src/Merge.Client/Crm/Types/PhoneNumber.cs +++ b/src/Merge.Client/Crm/Types/PhoneNumber.cs @@ -4,6 +4,15 @@ namespace Merge.Client.Crm; public class PhoneNumber { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The phone number. /// @@ -15,13 +24,4 @@ public class PhoneNumber /// [JsonPropertyName("phone_number_type")] public string? PhoneNumberType { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Crm/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Crm/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..f032db1f --- /dev/null +++ b/src/Merge.Client/Crm/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Crm; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/RemoteField.cs b/src/Merge.Client/Crm/Types/RemoteField.cs index 3dc3ee4c..4dbfad53 100644 --- a/src/Merge.Client/Crm/Types/RemoteField.cs +++ b/src/Merge.Client/Crm/Types/RemoteField.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; @@ -10,5 +10,5 @@ public class RemoteField public OneOf RemoteFieldClass { get; init; } [JsonPropertyName("value")] - public object? Value { get; init; } + public Dictionary? Value { get; init; } } diff --git a/src/Merge.Client/Crm/Types/RemoteFieldApi.cs b/src/Merge.Client/Crm/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..046b9949 --- /dev/null +++ b/src/Merge.Client/Crm/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Crm/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..f7e92dae --- /dev/null +++ b/src/Merge.Client/Crm/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; +using Merge.Client.Crm; + +namespace Merge.Client.Crm; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } + + [JsonPropertyName("Lead")] + public List? Lead { get; init; } + + [JsonPropertyName("Note")] + public List? Note { get; init; } + + [JsonPropertyName("Opportunity")] + public List? Opportunity { get; init; } + + [JsonPropertyName("Stage")] + public List? Stage { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Task")] + public List? Task { get; init; } + + [JsonPropertyName("Engagement")] + public List? Engagement { get; init; } +} diff --git a/src/Merge.Client/Crm/Types/RemoteFieldClassForCustomObjectClass.cs b/src/Merge.Client/Crm/Types/RemoteFieldClassForCustomObjectClass.cs index 14d4fbc1..4662ee64 100644 --- a/src/Merge.Client/Crm/Types/RemoteFieldClassForCustomObjectClass.cs +++ b/src/Merge.Client/Crm/Types/RemoteFieldClassForCustomObjectClass.cs @@ -5,6 +5,15 @@ namespace Merge.Client.Crm; public class RemoteFieldClassForCustomObjectClass { + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("display_name")] public string? DisplayName { get; init; } @@ -28,13 +37,4 @@ public class RemoteFieldClassForCustomObjectClass [JsonPropertyName("item_schema")] public RemoteFieldClassForCustomObjectClassItemSchema? ItemSchema { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Crm/Types/RemoteFieldRequest.cs b/src/Merge.Client/Crm/Types/RemoteFieldRequest.cs index e2366082..9ab2b922 100644 --- a/src/Merge.Client/Crm/Types/RemoteFieldRequest.cs +++ b/src/Merge.Client/Crm/Types/RemoteFieldRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; diff --git a/src/Merge.Client/Crm/Types/Stage.cs b/src/Merge.Client/Crm/Types/Stage.cs index 8dd8dfbb..0130aeee 100644 --- a/src/Merge.Client/Crm/Types/Stage.cs +++ b/src/Merge.Client/Crm/Types/Stage.cs @@ -5,18 +5,6 @@ namespace Merge.Client.Crm; public class Stage { - /// - /// The stage's name. - /// - [JsonPropertyName("name")] - public string? Name { get; init; } - - /// - /// Indicates whether or not this object has been deleted in the third party platform. - /// - [JsonPropertyName("remote_was_deleted")] - public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] public string? Id { get; init; } @@ -35,6 +23,18 @@ public class Stage [JsonPropertyName("modified_at")] public DateTime? ModifiedAt { get; init; } + /// + /// The stage's name. + /// + [JsonPropertyName("name")] + public string? Name { get; init; } + + /// + /// Indicates whether or not this object has been deleted in the third party platform. + /// + [JsonPropertyName("remote_was_deleted")] + public bool? RemoteWasDeleted { get; init; } + [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/Task.cs b/src/Merge.Client/Crm/Types/Task.cs index 6b1bc208..1acd16de 100644 --- a/src/Merge.Client/Crm/Types/Task.cs +++ b/src/Merge.Client/Crm/Types/Task.cs @@ -1,11 +1,29 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; public class Task { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The task's subject. /// @@ -50,7 +68,7 @@ public class Task /// /// The task's status. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// @@ -63,24 +81,6 @@ public class Task [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Types/TaskRequest.cs b/src/Merge.Client/Crm/Types/TaskRequest.cs index 823de66e..d6bd3e2c 100644 --- a/src/Merge.Client/Crm/Types/TaskRequest.cs +++ b/src/Merge.Client/Crm/Types/TaskRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Crm; +using OneOf; namespace Merge.Client.Crm; @@ -50,7 +50,7 @@ public class TaskRequest /// /// The task's status. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// diff --git a/src/Merge.Client/Crm/Types/User.cs b/src/Merge.Client/Crm/Types/User.cs index 35602f6b..e0acb848 100644 --- a/src/Merge.Client/Crm/Types/User.cs +++ b/src/Merge.Client/Crm/Types/User.cs @@ -5,6 +5,24 @@ namespace Merge.Client.Crm; public class User { + [JsonPropertyName("id")] + public string? Id { get; init; } + + /// + /// The third-party API ID of the matching object. + /// + [JsonPropertyName("remote_id")] + public string? RemoteId { get; init; } + + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user's name. /// @@ -29,24 +47,6 @@ public class User [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("id")] - public string? Id { get; init; } - - /// - /// The third-party API ID of the matching object. - /// - [JsonPropertyName("remote_id")] - public string? RemoteId { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Crm/Users/UsersClient.cs b/src/Merge.Client/Crm/Users/UsersClient.cs index 247b75e0..303a0763 100644 --- a/src/Merge.Client/Crm/Users/UsersClient.cs +++ b/src/Merge.Client/Crm/Users/UsersClient.cs @@ -1,13 +1,166 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class UsersClient { - public async void List(){ + private RawClient _client; + + public UsersClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task ListAsync(UsersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void IgnoreCreate(){ + + /// + /// Returns a `User` object with the given `id`. + /// + public async Task RetrieveAsync(string id, UsersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/crm/v1/users/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Ignores a specific row based on the `model_id` in the url. These records will have their properties set to null, and will not be updated in future syncs. The "reason" and "message" fields in the request body will be stored for audit purposes. + /// + public async void IgnoreCreateAsync(string modelId, IgnoreCommonModelRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/crm/v1/users/ignore/{modelId}", + Body = request + } + ); + } + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + UsersRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/crm/v1/users/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/Users/requests/UsersListRequest.cs b/src/Merge.Client/Crm/Users/requests/UsersListRequest.cs new file mode 100644 index 00000000..0d4fe345 --- /dev/null +++ b/src/Merge.Client/Crm/Users/requests/UsersListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Crm; + +public class UsersListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Crm/Users/requests/UsersRemoteFieldClassesListRequest.cs b/src/Merge.Client/Crm/Users/requests/UsersRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..a9403026 --- /dev/null +++ b/src/Merge.Client/Crm/Users/requests/UsersRemoteFieldClassesListRequest.cs @@ -0,0 +1,29 @@ +namespace Merge.Client.Crm; + +public class UsersRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Crm/Users/requests/UsersRetrieveRequest.cs b/src/Merge.Client/Crm/Users/requests/UsersRetrieveRequest.cs new file mode 100644 index 00000000..df367740 --- /dev/null +++ b/src/Merge.Client/Crm/Users/requests/UsersRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Crm; + +public class UsersRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } +} diff --git a/src/Merge.Client/Crm/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Crm/WebhookReceivers/WebhookReceiversClient.cs index 0bf29cab..2c586d0a 100644 --- a/src/Merge.Client/Crm/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Crm/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,52 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Crm; + namespace Merge.Client.Crm; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/crm/v1/webhook-receivers" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/crm/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Crm/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Crm/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..ccdb2988 --- /dev/null +++ b/src/Merge.Client/Crm/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Crm; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +} diff --git a/src/Merge.Client/Filestorage/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Filestorage/AccountDetails/AccountDetailsClient.cs index 58f62b68..854b8071 100644 --- a/src/Merge.Client/Filestorage/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Filestorage/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/account-details" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Filestorage/AccountToken/AccountTokenClient.cs index 56002c9d..72c88216 100644 --- a/src/Merge.Client/Filestorage/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Filestorage/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Filestorage/AsyncPassthrough/AsyncPassthroughClient.cs index 671fd665..f613f12b 100644 --- a/src/Merge.Client/Filestorage/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Filestorage/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Filestorage/AuditTrail/AuditTrailClient.cs index 66241fe5..da7a510a 100644 --- a/src/Merge.Client/Filestorage/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Filestorage/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Filestorage/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..99b44b03 --- /dev/null +++ b/src/Merge.Client/Filestorage/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Filestorage; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Filestorage/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Filestorage/AvailableActions/AvailableActionsClient.cs index 53561169..54437061 100644 --- a/src/Merge.Client/Filestorage/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Filestorage/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/available-actions" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Filestorage/DeleteAccount/DeleteAccountClient.cs index dc07d9c3..58c2a9e4 100644 --- a/src/Merge.Client/Filestorage/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Filestorage/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,27 @@ +using Merge.Client; + namespace Merge.Client.Filestorage; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/delete-account" + } + ); } } diff --git a/src/Merge.Client/Filestorage/Drives/DrivesClient.cs b/src/Merge.Client/Filestorage/Drives/DrivesClient.cs index 60092c43..07e1f70a 100644 --- a/src/Merge.Client/Filestorage/Drives/DrivesClient.cs +++ b/src/Merge.Client/Filestorage/Drives/DrivesClient.cs @@ -1,9 +1,103 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class DrivesClient { - public async void List(){ + private RawClient _client; + + public DrivesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Drive` objects. + /// + public async Task ListAsync(DrivesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Name != null) + { + _query["name"] = request.Name; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/drives", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Drive` object with the given `id`. + /// + public async Task RetrieveAsync(string id, DrivesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/drives/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Drives/requests/DrivesListRequest.cs b/src/Merge.Client/Filestorage/Drives/requests/DrivesListRequest.cs new file mode 100644 index 00000000..227ae14d --- /dev/null +++ b/src/Merge.Client/Filestorage/Drives/requests/DrivesListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Filestorage; + +public class DrivesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return drives with this name. This performs an exact match. + /// + public string? Name { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Drives/requests/DrivesRetrieveRequest.cs b/src/Merge.Client/Filestorage/Drives/requests/DrivesRetrieveRequest.cs new file mode 100644 index 00000000..b2d5d28b --- /dev/null +++ b/src/Merge.Client/Filestorage/Drives/requests/DrivesRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class DrivesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Filestorage/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Filestorage/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..6e7daeb1 --- /dev/null +++ b/src/Merge.Client/Filestorage/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,154 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/field-mappings" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/filestorage/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/filestorage/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/target-fields" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Filestorage/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Filestorage/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..f3c4be87 --- /dev/null +++ b/src/Merge.Client/Filestorage/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Filestorage; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Filestorage/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Filestorage/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..044344cd --- /dev/null +++ b/src/Merge.Client/Filestorage/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Filestorage; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Filestorage/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Filestorage/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..fe23658d --- /dev/null +++ b/src/Merge.Client/Filestorage/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Filestorage; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Files/FilesClient.cs b/src/Merge.Client/Filestorage/Files/FilesClient.cs index 05241ebe..7efcdba4 100644 --- a/src/Merge.Client/Filestorage/Files/FilesClient.cs +++ b/src/Merge.Client/Filestorage/Files/FilesClient.cs @@ -1,15 +1,193 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class FilesClient { - public async void List(){ + private RawClient _client; + + public FilesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `File` objects. + /// + public async Task ListAsync(FilesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.DriveId != null) + { + _query["drive_id"] = request.DriveId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.FolderId != null) + { + _query["folder_id"] = request.FolderId; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.MimeType != null) + { + _query["mime_type"] = request.MimeType; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Name != null) + { + _query["name"] = request.Name; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/files", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates a `File` object with the given values. + /// + public async Task CreateAsync(FileStorageFileEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/files", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `File` object with the given `id`. + /// + public async Task RetrieveAsync(string id, FilesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/files/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void DownloadRetrieve(){ + + /// + /// Returns a `File` object with the given `id`. + /// + public async void DownloadRetrieveAsync(string id, FilesDownloadRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.MimeType != null) + { + _query["mime_type"] = request.MimeType; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/files/{id}/download", + Query = _query + } + ); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `FileStorageFile` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/files/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Files/requests/FileStorageFileEndpointRequest.cs b/src/Merge.Client/Filestorage/Files/requests/FileStorageFileEndpointRequest.cs new file mode 100644 index 00000000..ac8e85d8 --- /dev/null +++ b/src/Merge.Client/Filestorage/Files/requests/FileStorageFileEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FileStorageFileEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public FileRequest Model { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Files/requests/FilesDownloadRetrieveRequest.cs b/src/Merge.Client/Filestorage/Files/requests/FilesDownloadRetrieveRequest.cs new file mode 100644 index 00000000..9871f6d3 --- /dev/null +++ b/src/Merge.Client/Filestorage/Files/requests/FilesDownloadRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class FilesDownloadRetrieveRequest +{ + /// + /// If provided, specifies the export format of the file to be downloaded. For information on supported export formats, please refer to our export format help center article. + /// + public string? MimeType { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Files/requests/FilesListRequest.cs b/src/Merge.Client/Filestorage/Files/requests/FilesListRequest.cs new file mode 100644 index 00000000..05235791 --- /dev/null +++ b/src/Merge.Client/Filestorage/Files/requests/FilesListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FilesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Specifying a drive id returns only the files in that drive. Specifying null returns only the files outside the top-level drive. + /// + public string? DriveId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public FilesListRequestExpand? Expand { get; init; } + + /// + /// Specifying a folder id returns only the files in that folder. Specifying null returns only the files in root directory. + /// + public string? FolderId { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return files with these mime_types. Multiple values can be separated by commas. + /// + public string? MimeType { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return files with this name. This performs an exact match. + /// + public string? Name { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Files/requests/FilesRetrieveRequest.cs b/src/Merge.Client/Filestorage/Files/requests/FilesRetrieveRequest.cs new file mode 100644 index 00000000..d4c55d74 --- /dev/null +++ b/src/Merge.Client/Filestorage/Files/requests/FilesRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FilesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public FilesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Filestorage/FilestorageClient.cs b/src/Merge.Client/Filestorage/FilestorageClient.cs new file mode 100644 index 00000000..ebc325aa --- /dev/null +++ b/src/Merge.Client/Filestorage/FilestorageClient.cs @@ -0,0 +1,83 @@ +using Merge.Client; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FilestorageClient +{ + private RawClient _client; + + public FilestorageClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + Drives = new DrivesClient(_client); + FieldMapping = new FieldMappingClient(_client); + Files = new FilesClient(_client); + Folders = new FoldersClient(_client); + GenerateKey = new GenerateKeyClient(_client); + Groups = new GroupsClient(_client); + Issues = new IssuesClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Passthrough = new PassthroughClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + Users = new UsersClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public DrivesClient Drives { get; } + + public FieldMappingClient FieldMapping { get; } + + public FilesClient Files { get; } + + public FoldersClient Folders { get; } + + public GenerateKeyClient GenerateKey { get; } + + public GroupsClient Groups { get; } + + public IssuesClient Issues { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public PassthroughClient Passthrough { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public UsersClient Users { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Filestorage/Folders/FoldersClient.cs b/src/Merge.Client/Filestorage/Folders/FoldersClient.cs index 9fb2b232..cf590584 100644 --- a/src/Merge.Client/Filestorage/Folders/FoldersClient.cs +++ b/src/Merge.Client/Filestorage/Folders/FoldersClient.cs @@ -1,13 +1,171 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class FoldersClient { - public async void List(){ + private RawClient _client; + + public FoldersClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Folder` objects. + /// + public async Task ListAsync(FoldersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.DriveId != null) + { + _query["drive_id"] = request.DriveId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Name != null) + { + _query["name"] = request.Name; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.ParentFolderId != null) + { + _query["parent_folder_id"] = request.ParentFolderId; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/folders", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `Folder` object with the given values. + /// + public async Task CreateAsync( + FileStorageFolderEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/folders", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `Folder` object with the given `id`. + /// + public async Task RetrieveAsync(string id, FoldersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/folders/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `FileStorageFolder` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/folders/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Folders/requests/FileStorageFolderEndpointRequest.cs b/src/Merge.Client/Filestorage/Folders/requests/FileStorageFolderEndpointRequest.cs new file mode 100644 index 00000000..5acec252 --- /dev/null +++ b/src/Merge.Client/Filestorage/Folders/requests/FileStorageFolderEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FileStorageFolderEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public FolderRequest Model { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Folders/requests/FoldersListRequest.cs b/src/Merge.Client/Filestorage/Folders/requests/FoldersListRequest.cs new file mode 100644 index 00000000..73aa63fa --- /dev/null +++ b/src/Merge.Client/Filestorage/Folders/requests/FoldersListRequest.cs @@ -0,0 +1,71 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FoldersListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return folders in this drive. + /// + public string? DriveId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public FoldersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return folders with this name. This performs an exact match. + /// + public string? Name { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return folders in this parent folder. If null, will return folders in root directory. + /// + public string? ParentFolderId { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Folders/requests/FoldersRetrieveRequest.cs b/src/Merge.Client/Filestorage/Folders/requests/FoldersRetrieveRequest.cs new file mode 100644 index 00000000..63c155a0 --- /dev/null +++ b/src/Merge.Client/Filestorage/Folders/requests/FoldersRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FoldersRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public FoldersRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Filestorage/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Filestorage/ForceResync/ForceResyncClient.cs index d2dfd47d..3f057700 100644 --- a/src/Merge.Client/Filestorage/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Filestorage/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Filestorage/GenerateKey/GenerateKeyClient.cs index 59c0d31d..1f1c0ff7 100644 --- a/src/Merge.Client/Filestorage/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Filestorage/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Filestorage/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..e41b5b42 --- /dev/null +++ b/src/Merge.Client/Filestorage/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Groups/GroupsClient.cs b/src/Merge.Client/Filestorage/Groups/GroupsClient.cs index feb8e4b2..4d33dfb1 100644 --- a/src/Merge.Client/Filestorage/Groups/GroupsClient.cs +++ b/src/Merge.Client/Filestorage/Groups/GroupsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class GroupsClient { - public async void List(){ + private RawClient _client; + + public GroupsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Group` objects. + /// + public async Task ListAsync(GroupsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/groups", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Group` object with the given `id`. + /// + public async Task RetrieveAsync(string id, GroupsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/groups/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Groups/requests/GroupsListRequest.cs b/src/Merge.Client/Filestorage/Groups/requests/GroupsListRequest.cs new file mode 100644 index 00000000..f6032bf4 --- /dev/null +++ b/src/Merge.Client/Filestorage/Groups/requests/GroupsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Filestorage; + +public class GroupsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Groups/requests/GroupsRetrieveRequest.cs b/src/Merge.Client/Filestorage/Groups/requests/GroupsRetrieveRequest.cs new file mode 100644 index 00000000..f77f0bc5 --- /dev/null +++ b/src/Merge.Client/Filestorage/Groups/requests/GroupsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class GroupsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Issues/IssuesClient.cs b/src/Merge.Client/Filestorage/Issues/IssuesClient.cs index fd479c8c..9a53ca0c 100644 --- a/src/Merge.Client/Filestorage/Issues/IssuesClient.cs +++ b/src/Merge.Client/Filestorage/Issues/IssuesClient.cs @@ -1,9 +1,109 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/issues/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Filestorage/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..79cc0485 --- /dev/null +++ b/src/Merge.Client/Filestorage/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Filestorage/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Filestorage/LinkToken/LinkTokenClient.cs index a938d713..0e1d3a30 100644 --- a/src/Merge.Client/Filestorage/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Filestorage/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Filestorage/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..c354b837 --- /dev/null +++ b/src/Merge.Client/Filestorage/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Filestorage/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Filestorage/LinkedAccounts/LinkedAccountsClient.cs index cd75a376..7f4433d3 100644 --- a/src/Merge.Client/Filestorage/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Filestorage/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Filestorage/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..ed99adaf --- /dev/null +++ b/src/Merge.Client/Filestorage/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class LinkedAccountsListRequest +{ + /// + /// Options: ('hris', 'ats', 'accounting', 'ticketing', 'crm', 'mktg', 'filestorage') + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Passthrough/PassthroughClient.cs b/src/Merge.Client/Filestorage/Passthrough/PassthroughClient.cs index 08d6d52c..1758d5a6 100644 --- a/src/Merge.Client/Filestorage/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Filestorage/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Filestorage/RegenerateKey/RegenerateKeyClient.cs index 9c133c68..6cef5d8a 100644 --- a/src/Merge.Client/Filestorage/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Filestorage/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Filestorage/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..09902faa --- /dev/null +++ b/src/Merge.Client/Filestorage/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Scopes/ScopesClient.cs b/src/Merge.Client/Filestorage/Scopes/ScopesClient.cs new file mode 100644 index 00000000..c6a30496 --- /dev/null +++ b/src/Merge.Client/Filestorage/Scopes/ScopesClient.cs @@ -0,0 +1,78 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/default-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Filestorage/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Filestorage/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..abe48e04 --- /dev/null +++ b/src/Merge.Client/Filestorage/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Filestorage/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Filestorage/SelectiveSync/SelectiveSyncClient.cs index 894e2555..d158db07 100644 --- a/src/Merge.Client/Filestorage/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Filestorage/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/filestorage/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Filestorage/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..68fd416f --- /dev/null +++ b/src/Merge.Client/Filestorage/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Filestorage/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Filestorage/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..a40771cb --- /dev/null +++ b/src/Merge.Client/Filestorage/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Filestorage; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Filestorage/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Filestorage/SyncStatus/SyncStatusClient.cs index df580605..46a6f781 100644 --- a/src/Merge.Client/Filestorage/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Filestorage/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Filestorage/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..6732f6a8 --- /dev/null +++ b/src/Merge.Client/Filestorage/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Filestorage; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Filestorage/Types/AccountDetailsAndActions.cs index 47c65ebf..934fadf8 100644 --- a/src/Merge.Client/Filestorage/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Filestorage/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/AccountIntegration.cs b/src/Merge.Client/Filestorage/Types/AccountIntegration.cs index 8d96ae41..f8e01d93 100644 --- a/src/Merge.Client/Filestorage/Types/AccountIntegration.cs +++ b/src/Merge.Client/Filestorage/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Filestorage/Types/AdvancedMetadata.cs b/src/Merge.Client/Filestorage/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..d509511f --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/AuditLogEvent.cs b/src/Merge.Client/Filestorage/Types/AuditLogEvent.cs index 341f4666..af62ad92 100644 --- a/src/Merge.Client/Filestorage/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Filestorage/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/CommonModelScopeApi.cs b/src/Merge.Client/Filestorage/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..07603b8c --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/ConditionSchema.cs b/src/Merge.Client/Filestorage/Types/ConditionSchema.cs index 366d420e..816ffae4 100644 --- a/src/Merge.Client/Filestorage/Types/ConditionSchema.cs +++ b/src/Merge.Client/Filestorage/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Filestorage/Types/DataPassthroughRequest.cs b/src/Merge.Client/Filestorage/Types/DataPassthroughRequest.cs index 723f1247..6b41de58 100644 --- a/src/Merge.Client/Filestorage/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Filestorage/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/Drive.cs b/src/Merge.Client/Filestorage/Types/Drive.cs index a8fdd308..2d479df9 100644 --- a/src/Merge.Client/Filestorage/Types/Drive.cs +++ b/src/Merge.Client/Filestorage/Types/Drive.cs @@ -13,6 +13,15 @@ public class Drive [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The drive's name. /// @@ -37,15 +46,6 @@ public class Drive [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/EventTypeEnum.cs b/src/Merge.Client/Filestorage/Types/EventTypeEnum.cs index f7dc89ae..4eb48f24 100644 --- a/src/Merge.Client/Filestorage/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Filestorage/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..055a4191 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..785ff47b --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("File")] + public List? File { get; init; } + + [JsonPropertyName("Folder")] + public List? Folder { get; init; } + + [JsonPropertyName("Drive")] + public List? Drive { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..2f2b13db --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..8cd386ca --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..2b2d2a04 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..5a55535d --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("File")] + public List? File { get; init; } + + [JsonPropertyName("Folder")] + public List? Folder { get; init; } + + [JsonPropertyName("Drive")] + public List? Drive { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..f1af1105 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Filestorage/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..62a23414 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..e3d0de2b --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..420f8bb6 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/File.cs b/src/Merge.Client/Filestorage/Types/File.cs index f1c56286..5b8922ac 100644 --- a/src/Merge.Client/Filestorage/Types/File.cs +++ b/src/Merge.Client/Filestorage/Types/File.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -15,6 +15,15 @@ public class File [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The file's name. /// @@ -61,7 +70,11 @@ public class File /// The Permission object is used to represent a user's or group's access to a File or Folder. Permissions are unexpanded by default. Use the query param `expand=permissions` to see more details under `GET /files`. /// [JsonPropertyName("permissions")] - public OneOf>>? Permissions { get; init; } + public OneOf< + string, + PermissionRequest, + List> + >? Permissions { get; init; } /// /// The drive that the file belongs to. @@ -87,15 +100,6 @@ public class File [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/FileRequest.cs b/src/Merge.Client/Filestorage/Types/FileRequest.cs index ad56e313..750d69de 100644 --- a/src/Merge.Client/Filestorage/Types/FileRequest.cs +++ b/src/Merge.Client/Filestorage/Types/FileRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -52,7 +52,11 @@ public class FileRequest /// The Permission object is used to represent a user's or group's access to a File or Folder. Permissions are unexpanded by default. Use the query param `expand=permissions` to see more details under `GET /files`. /// [JsonPropertyName("permissions")] - public OneOf>>? Permissions { get; init; } + public OneOf< + string, + PermissionRequest, + List> + >? Permissions { get; init; } /// /// The drive that the file belongs to. diff --git a/src/Merge.Client/Filestorage/Types/Folder.cs b/src/Merge.Client/Filestorage/Types/Folder.cs index 8d706916..a1f8d7a1 100644 --- a/src/Merge.Client/Filestorage/Types/Folder.cs +++ b/src/Merge.Client/Filestorage/Types/Folder.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -15,6 +15,15 @@ public class Folder [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The folder's name. /// @@ -55,7 +64,11 @@ public class Folder /// The Permission object is used to represent a user's or group's access to a File or Folder. Permissions are unexpanded by default. Use the query param `expand=permissions` to see more details under `GET /folders`. /// [JsonPropertyName("permissions")] - public OneOf>>? Permissions { get; init; } + public OneOf< + string, + PermissionRequest, + List> + >? Permissions { get; init; } /// /// When the third party's folder was created. @@ -75,15 +88,6 @@ public class Folder [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/FolderRequest.cs b/src/Merge.Client/Filestorage/Types/FolderRequest.cs index 5a59ab38..c6872515 100644 --- a/src/Merge.Client/Filestorage/Types/FolderRequest.cs +++ b/src/Merge.Client/Filestorage/Types/FolderRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -46,7 +46,11 @@ public class FolderRequest /// The Permission object is used to represent a user's or group's access to a File or Folder. Permissions are unexpanded by default. Use the query param `expand=permissions` to see more details under `GET /folders`. /// [JsonPropertyName("permissions")] - public OneOf>>? Permissions { get; init; } + public OneOf< + string, + PermissionRequest, + List> + >? Permissions { get; init; } [JsonPropertyName("integration_params")] public Dictionary? IntegrationParams { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/Group.cs b/src/Merge.Client/Filestorage/Types/Group.cs index 647b1055..fab321f8 100644 --- a/src/Merge.Client/Filestorage/Types/Group.cs +++ b/src/Merge.Client/Filestorage/Types/Group.cs @@ -13,6 +13,15 @@ public class Group [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The group's name. /// @@ -31,15 +40,6 @@ public class Group [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..d692ea4e --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..e30761c6 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/Issue.cs b/src/Merge.Client/Filestorage/Types/Issue.cs index 6bf5ea8c..058e83c1 100644 --- a/src/Merge.Client/Filestorage/Types/Issue.cs +++ b/src/Merge.Client/Filestorage/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Filestorage/Types/LinkedAccountCondition.cs b/src/Merge.Client/Filestorage/Types/LinkedAccountCondition.cs index 79b71f88..290dfafa 100644 --- a/src/Merge.Client/Filestorage/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Filestorage/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Filestorage/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Filestorage/Types/LinkedAccountConditionRequest.cs index eb14d714..06360833 100644 --- a/src/Merge.Client/Filestorage/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Filestorage/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Filestorage; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..bc5bf5fe --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..cdc88f0b --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Filestorage/Types/MultipartFormFieldRequest.cs index c5be1943..5bb20788 100644 --- a/src/Merge.Client/Filestorage/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Filestorage/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Filestorage/Types/Permission.cs b/src/Merge.Client/Filestorage/Types/Permission.cs index 83384e4c..852daa32 100644 --- a/src/Merge.Client/Filestorage/Types/Permission.cs +++ b/src/Merge.Client/Filestorage/Types/Permission.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -15,6 +15,15 @@ public class Permission [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user that is granted this permission. /// @@ -29,7 +38,7 @@ public class Permission /// /// Denotes what type of people have access to the file. - /// + /// /// - `USER` - USER /// - `GROUP` - GROUP /// - `COMPANY` - COMPANY @@ -43,13 +52,4 @@ public class Permission /// [JsonPropertyName("roles")] public List? Roles { get; init; } - - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } } diff --git a/src/Merge.Client/Filestorage/Types/PermissionRequest.cs b/src/Merge.Client/Filestorage/Types/PermissionRequest.cs index aa86d4d7..aa982365 100644 --- a/src/Merge.Client/Filestorage/Types/PermissionRequest.cs +++ b/src/Merge.Client/Filestorage/Types/PermissionRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Filestorage; +using OneOf; namespace Merge.Client.Filestorage; @@ -26,7 +26,7 @@ public class PermissionRequest /// /// Denotes what type of people have access to the file. - /// + /// /// - `USER` - USER /// - `GROUP` - GROUP /// - `COMPANY` - COMPANY diff --git a/src/Merge.Client/Filestorage/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Filestorage/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..e4a85e4c --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Filestorage; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/RemoteFieldApi.cs b/src/Merge.Client/Filestorage/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..c88513cf --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Filestorage/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..4043a8a4 --- /dev/null +++ b/src/Merge.Client/Filestorage/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Filestorage; + +namespace Merge.Client.Filestorage; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("File")] + public List? File { get; init; } + + [JsonPropertyName("Folder")] + public List? Folder { get; init; } + + [JsonPropertyName("Drive")] + public List? Drive { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Types/User.cs b/src/Merge.Client/Filestorage/Types/User.cs index 2aa7c991..be60b5c4 100644 --- a/src/Merge.Client/Filestorage/Types/User.cs +++ b/src/Merge.Client/Filestorage/Types/User.cs @@ -13,6 +13,15 @@ public class User [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user's name. /// @@ -37,15 +46,6 @@ public class User [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Filestorage/Users/UsersClient.cs b/src/Merge.Client/Filestorage/Users/UsersClient.cs index 79b8dff6..30643881 100644 --- a/src/Merge.Client/Filestorage/Users/UsersClient.cs +++ b/src/Merge.Client/Filestorage/Users/UsersClient.cs @@ -1,9 +1,103 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class UsersClient { - public async void List(){ + private RawClient _client; + + public UsersClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task ListAsync(UsersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IsMe != null) + { + _query["is_me"] = request.IsMe; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `User` object with the given `id`. + /// + public async Task RetrieveAsync(string id, UsersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/filestorage/v1/users/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/Users/requests/UsersListRequest.cs b/src/Merge.Client/Filestorage/Users/requests/UsersListRequest.cs new file mode 100644 index 00000000..2d524277 --- /dev/null +++ b/src/Merge.Client/Filestorage/Users/requests/UsersListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Filestorage; + +public class UsersListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return the user object for requestor. + /// + public string? IsMe { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Filestorage/Users/requests/UsersRetrieveRequest.cs b/src/Merge.Client/Filestorage/Users/requests/UsersRetrieveRequest.cs new file mode 100644 index 00000000..ffb4a463 --- /dev/null +++ b/src/Merge.Client/Filestorage/Users/requests/UsersRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Filestorage; + +public class UsersRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Filestorage/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Filestorage/WebhookReceivers/WebhookReceiversClient.cs index 87b21da6..7f920214 100644 --- a/src/Merge.Client/Filestorage/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Filestorage/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Filestorage; + namespace Merge.Client.Filestorage; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/filestorage/v1/webhook-receivers" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/filestorage/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Filestorage/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Filestorage/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..93e5dcbf --- /dev/null +++ b/src/Merge.Client/Filestorage/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Filestorage; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +} diff --git a/src/Merge.Client/Hris/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Hris/AccountDetails/AccountDetailsClient.cs index d4b60175..2f03ebb1 100644 --- a/src/Merge.Client/Hris/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Hris/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,31 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/hris/v1/account-details" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Hris/AccountToken/AccountTokenClient.cs index 73342b9c..5d979c21 100644 --- a/src/Merge.Client/Hris/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Hris/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Hris/AsyncPassthrough/AsyncPassthroughClient.cs index 6e6c1108..c2baae1d 100644 --- a/src/Merge.Client/Hris/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Hris/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Hris/AuditTrail/AuditTrailClient.cs index b3b9b19b..e6cdd333 100644 --- a/src/Merge.Client/Hris/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Hris/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Hris/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..30c4b84d --- /dev/null +++ b/src/Merge.Client/Hris/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Hris; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Hris/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Hris/AvailableActions/AvailableActionsClient.cs index 9ea6c383..e877c4d0 100644 --- a/src/Merge.Client/Hris/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Hris/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/available-actions" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/BankInfo/BankInfoClient.cs b/src/Merge.Client/Hris/BankInfo/BankInfoClient.cs index d7483621..919f6609 100644 --- a/src/Merge.Client/Hris/BankInfo/BankInfoClient.cs +++ b/src/Merge.Client/Hris/BankInfo/BankInfoClient.cs @@ -1,9 +1,139 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class BankInfoClient { - public async void List(){ + private RawClient _client; + + public BankInfoClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `BankInfo` objects. + /// + public async Task ListAsync(BankInfoListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountType != null) + { + _query["account_type"] = request.AccountType; + } + if (request.BankName != null) + { + _query["bank_name"] = request.BankName; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OrderBy != null) + { + _query["order_by"] = request.OrderBy; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/bank-info", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `BankInfo` object with the given `id`. + /// + public async Task RetrieveAsync(string id, BankInfoRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/bank-info/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/BankInfo/requests/BankInfoListRequest.cs b/src/Merge.Client/Hris/BankInfo/requests/BankInfoListRequest.cs new file mode 100644 index 00000000..3b682868 --- /dev/null +++ b/src/Merge.Client/Hris/BankInfo/requests/BankInfoListRequest.cs @@ -0,0 +1,89 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class BankInfoListRequest +{ + /// + /// If provided, will only return BankInfo's with this account type. Options: ('SAVINGS', 'CHECKING') + /// + /// - `SAVINGS` - SAVINGS + /// - `CHECKING` - CHECKING + /// + public BankInfoListRequestAccountType? AccountType { get; init; } + + /// + /// If provided, will only return BankInfo's with this bank name. + /// + public string? BankName { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return bank accounts for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Overrides the default ordering for this endpoint. + /// + public BankInfoListRequestOrderBy? OrderBy { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/BankInfo/requests/BankInfoRetrieveRequest.cs b/src/Merge.Client/Hris/BankInfo/requests/BankInfoRetrieveRequest.cs new file mode 100644 index 00000000..43878276 --- /dev/null +++ b/src/Merge.Client/Hris/BankInfo/requests/BankInfoRetrieveRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Hris; + +public class BankInfoRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/Benefits/BenefitsClient.cs b/src/Merge.Client/Hris/Benefits/BenefitsClient.cs index 0ace313e..3aa1fc5b 100644 --- a/src/Merge.Client/Hris/Benefits/BenefitsClient.cs +++ b/src/Merge.Client/Hris/Benefits/BenefitsClient.cs @@ -1,9 +1,111 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class BenefitsClient { - public async void List(){ + private RawClient _client; + + public BenefitsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Benefit` objects. + /// + public async Task ListAsync(BenefitsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/benefits", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Benefit` object with the given `id`. + /// + public async Task RetrieveAsync(string id, BenefitsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/benefits/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Benefits/requests/BenefitsListRequest.cs b/src/Merge.Client/Hris/Benefits/requests/BenefitsListRequest.cs new file mode 100644 index 00000000..cba30ecf --- /dev/null +++ b/src/Merge.Client/Hris/Benefits/requests/BenefitsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Hris; + +public class BenefitsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will return the benefits associated with the employee. + /// + public string? EmployeeId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/Benefits/requests/BenefitsRetrieveRequest.cs b/src/Merge.Client/Hris/Benefits/requests/BenefitsRetrieveRequest.cs new file mode 100644 index 00000000..256982e1 --- /dev/null +++ b/src/Merge.Client/Hris/Benefits/requests/BenefitsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Hris; + +public class BenefitsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/Companies/CompaniesClient.cs b/src/Merge.Client/Hris/Companies/CompaniesClient.cs index 5fb4cd76..b2637c51 100644 --- a/src/Merge.Client/Hris/Companies/CompaniesClient.cs +++ b/src/Merge.Client/Hris/Companies/CompaniesClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class CompaniesClient { - public async void List(){ + private RawClient _client; + + public CompaniesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Company` objects. + /// + public async Task ListAsync(CompaniesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/companies", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Company` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CompaniesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/companies/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Companies/requests/CompaniesListRequest.cs b/src/Merge.Client/Hris/Companies/requests/CompaniesListRequest.cs new file mode 100644 index 00000000..bd8776eb --- /dev/null +++ b/src/Merge.Client/Hris/Companies/requests/CompaniesListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Hris; + +public class CompaniesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/Companies/requests/CompaniesRetrieveRequest.cs b/src/Merge.Client/Hris/Companies/requests/CompaniesRetrieveRequest.cs new file mode 100644 index 00000000..252fefa8 --- /dev/null +++ b/src/Merge.Client/Hris/Companies/requests/CompaniesRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class CompaniesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Hris/DeleteAccount/DeleteAccountClient.cs index 4cc79d19..70db7239 100644 --- a/src/Merge.Client/Hris/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Hris/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,23 @@ +using Merge.Client; + namespace Merge.Client.Hris; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Post, Path = "/hris/v1/delete-account" } + ); } } diff --git a/src/Merge.Client/Hris/Dependents/DependentsClient.cs b/src/Merge.Client/Hris/Dependents/DependentsClient.cs index f954df7f..03637ad7 100644 --- a/src/Merge.Client/Hris/Dependents/DependentsClient.cs +++ b/src/Merge.Client/Hris/Dependents/DependentsClient.cs @@ -1,9 +1,107 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class DependentsClient { - public async void List(){ + private RawClient _client; + + public DependentsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Dependent` objects. + /// + public async Task ListAsync(DependentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeSensitiveFields != null) + { + _query["include_sensitive_fields"] = request.IncludeSensitiveFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/dependents", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Dependent` object with the given `id`. + /// + public async Task RetrieveAsync(string id, DependentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeSensitiveFields != null) + { + _query["include_sensitive_fields"] = request.IncludeSensitiveFields; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/dependents/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Dependents/requests/DependentsListRequest.cs b/src/Merge.Client/Hris/Dependents/requests/DependentsListRequest.cs new file mode 100644 index 00000000..52e10e6d --- /dev/null +++ b/src/Merge.Client/Hris/Dependents/requests/DependentsListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Hris; + +public class DependentsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include sensitive fields (such as social security numbers) in the response. + /// + public bool? IncludeSensitiveFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/Dependents/requests/DependentsRetrieveRequest.cs b/src/Merge.Client/Hris/Dependents/requests/DependentsRetrieveRequest.cs new file mode 100644 index 00000000..2e4938e8 --- /dev/null +++ b/src/Merge.Client/Hris/Dependents/requests/DependentsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Hris; + +public class DependentsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include sensitive fields (such as social security numbers) in the response. + /// + public bool? IncludeSensitiveFields { get; init; } +} diff --git a/src/Merge.Client/Hris/EmployeePayrollRuns/EmployeePayrollRunsClient.cs b/src/Merge.Client/Hris/EmployeePayrollRuns/EmployeePayrollRunsClient.cs index 74788513..c9003186 100644 --- a/src/Merge.Client/Hris/EmployeePayrollRuns/EmployeePayrollRunsClient.cs +++ b/src/Merge.Client/Hris/EmployeePayrollRuns/EmployeePayrollRunsClient.cs @@ -1,9 +1,136 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class EmployeePayrollRunsClient { - public async void List(){ + private RawClient _client; + + public EmployeePayrollRunsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `EmployeePayrollRun` objects. + /// + public async Task ListAsync( + EmployeePayrollRunsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.EndedAfter != null) + { + _query["ended_after"] = request.EndedAfter; + } + if (request.EndedBefore != null) + { + _query["ended_before"] = request.EndedBefore; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.PayrollRunId != null) + { + _query["payroll_run_id"] = request.PayrollRunId; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/employee-payroll-runs", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `EmployeePayrollRun` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + EmployeePayrollRunsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/employee-payroll-runs/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsListRequest.cs b/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsListRequest.cs new file mode 100644 index 00000000..57039aa4 --- /dev/null +++ b/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsListRequest.cs @@ -0,0 +1,86 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmployeePayrollRunsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return employee payroll runs for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// If provided, will only return employee payroll runs ended after this datetime. + /// + public DateTime? EndedAfter { get; init; } + + /// + /// If provided, will only return employee payroll runs ended before this datetime. + /// + public DateTime? EndedBefore { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmployeePayrollRunsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return employee payroll runs for this employee. + /// + public string? PayrollRunId { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return employee payroll runs started after this datetime. + /// + public DateTime? StartedAfter { get; init; } + + /// + /// If provided, will only return employee payroll runs started before this datetime. + /// + public DateTime? StartedBefore { get; init; } +} diff --git a/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsRetrieveRequest.cs b/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsRetrieveRequest.cs new file mode 100644 index 00000000..aa55c56e --- /dev/null +++ b/src/Merge.Client/Hris/EmployeePayrollRuns/requests/EmployeePayrollRunsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmployeePayrollRunsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmployeePayrollRunsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/Employees/EmployeesClient.cs b/src/Merge.Client/Hris/Employees/EmployeesClient.cs index 506e9dab..83023ffa 100644 --- a/src/Merge.Client/Hris/Employees/EmployeesClient.cs +++ b/src/Merge.Client/Hris/Employees/EmployeesClient.cs @@ -1,15 +1,272 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class EmployeesClient { - public async void List(){ + private RawClient _client; + + public EmployeesClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Employee` objects. + /// + public async Task ListAsync(EmployeesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CompanyId != null) + { + _query["company_id"] = request.CompanyId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.DisplayFullName != null) + { + _query["display_full_name"] = request.DisplayFullName; + } + if (request.EmploymentStatus != null) + { + _query["employment_status"] = request.EmploymentStatus; + } + if (request.EmploymentType != null) + { + _query["employment_type"] = request.EmploymentType; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.FirstName != null) + { + _query["first_name"] = request.FirstName; + } + if (request.Groups != null) + { + _query["groups"] = request.Groups; + } + if (request.HomeLocationId != null) + { + _query["home_location_id"] = request.HomeLocationId; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeSensitiveFields != null) + { + _query["include_sensitive_fields"] = request.IncludeSensitiveFields; + } + if (request.JobTitle != null) + { + _query["job_title"] = request.JobTitle; + } + if (request.LastName != null) + { + _query["last_name"] = request.LastName; + } + if (request.ManagerId != null) + { + _query["manager_id"] = request.ManagerId; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.PayGroupId != null) + { + _query["pay_group_id"] = request.PayGroupId; + } + if (request.PersonalEmail != null) + { + _query["personal_email"] = request.PersonalEmail; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + if (request.TeamId != null) + { + _query["team_id"] = request.TeamId; + } + if (request.TerminatedAfter != null) + { + _query["terminated_after"] = request.TerminatedAfter; + } + if (request.TerminatedBefore != null) + { + _query["terminated_before"] = request.TerminatedBefore; + } + if (request.WorkEmail != null) + { + _query["work_email"] = request.WorkEmail; + } + if (request.WorkLocationId != null) + { + _query["work_location_id"] = request.WorkLocationId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/employees", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates an `Employee` object with the given values. + /// + public async Task CreateAsync(EmployeeEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/employees", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Employee` object with the given `id`. + /// + public async Task RetrieveAsync(string id, EmployeesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeSensitiveFields != null) + { + _query["include_sensitive_fields"] = request.IncludeSensitiveFields; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/employees/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void IgnoreCreate(){ + + /// + /// Ignores a specific row based on the `model_id` in the url. These records will have their properties set to null, and will not be updated in future syncs. The "reason" and "message" fields in the request body will be stored for audit purposes. + /// + public async void IgnoreCreateAsync(string modelId, IgnoreCommonModelRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = $"/hris/v1/employees/ignore/{modelId}", + Body = request + } + ); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Employee` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/employees/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Employees/Types/EmployeesListRequestExpand.cs b/src/Merge.Client/Hris/Employees/Types/EmployeesListRequestExpand.cs index 37b55409..094cda7c 100644 --- a/src/Merge.Client/Hris/Employees/Types/EmployeesListRequestExpand.cs +++ b/src/Merge.Client/Hris/Employees/Types/EmployeesListRequestExpand.cs @@ -103,7 +103,9 @@ public enum EmployeesListRequestExpand [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,company")] EmploymentsGroupsHomeLocationWorkLocationManagerTeamCompany, - [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,company,pay_group")] + [EnumMember( + Value = "employments,groups,home_location,work_location,manager,team,company,pay_group" + )] EmploymentsGroupsHomeLocationWorkLocationManagerTeamCompanyPayGroup, [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,pay_group")] diff --git a/src/Merge.Client/Hris/Employees/Types/EmployeesRetrieveRequestExpand.cs b/src/Merge.Client/Hris/Employees/Types/EmployeesRetrieveRequestExpand.cs index 51429564..1e2e327a 100644 --- a/src/Merge.Client/Hris/Employees/Types/EmployeesRetrieveRequestExpand.cs +++ b/src/Merge.Client/Hris/Employees/Types/EmployeesRetrieveRequestExpand.cs @@ -103,7 +103,9 @@ public enum EmployeesRetrieveRequestExpand [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,company")] EmploymentsGroupsHomeLocationWorkLocationManagerTeamCompany, - [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,company,pay_group")] + [EnumMember( + Value = "employments,groups,home_location,work_location,manager,team,company,pay_group" + )] EmploymentsGroupsHomeLocationWorkLocationManagerTeamCompanyPayGroup, [EnumMember(Value = "employments,groups,home_location,work_location,manager,team,pay_group")] diff --git a/src/Merge.Client/Hris/Employees/requests/EmployeeEndpointRequest.cs b/src/Merge.Client/Hris/Employees/requests/EmployeeEndpointRequest.cs new file mode 100644 index 00000000..4d8aa8c9 --- /dev/null +++ b/src/Merge.Client/Hris/Employees/requests/EmployeeEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmployeeEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public EmployeeRequest Model { get; init; } +} diff --git a/src/Merge.Client/Hris/Employees/requests/EmployeesListRequest.cs b/src/Merge.Client/Hris/Employees/requests/EmployeesListRequest.cs new file mode 100644 index 00000000..c294dd8f --- /dev/null +++ b/src/Merge.Client/Hris/Employees/requests/EmployeesListRequest.cs @@ -0,0 +1,170 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmployeesListRequest +{ + /// + /// If provided, will only return employees for this company. + /// + public string? CompanyId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return employees with this display name. + /// + public string? DisplayFullName { get; init; } + + /// + /// If provided, will only return employees with this employment status. + /// + /// - `ACTIVE` - ACTIVE + /// - `PENDING` - PENDING + /// - `INACTIVE` - INACTIVE + /// + public EmployeesListRequestEmploymentStatus? EmploymentStatus { get; init; } + + /// + /// If provided, will only return employees that have an employment of the specified employment_type. + /// + public string? EmploymentType { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmployeesListRequestExpand? Expand { get; init; } + + /// + /// If provided, will only return employees with this first name. + /// + public string? FirstName { get; init; } + + /// + /// If provided, will only return employees matching the group ids; multiple groups can be separated by commas. + /// + public string? Groups { get; init; } + + /// + /// If provided, will only return employees for this home location. + /// + public string? HomeLocationId { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include sensitive fields (such as social security numbers) in the response. + /// + public bool? IncludeSensitiveFields { get; init; } + + /// + /// If provided, will only return employees that have an employment of the specified job_title. + /// + public string? JobTitle { get; init; } + + /// + /// If provided, will only return employees with this last name. + /// + public string? LastName { get; init; } + + /// + /// If provided, will only return employees for this manager. + /// + public string? ManagerId { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return employees for this pay group + /// + public string? PayGroupId { get; init; } + + /// + /// If provided, will only return Employees with this personal email + /// + public string? PersonalEmail { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EmployeesListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EmployeesListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return employees that started after this datetime. + /// + public DateTime? StartedAfter { get; init; } + + /// + /// If provided, will only return employees that started before this datetime. + /// + public DateTime? StartedBefore { get; init; } + + /// + /// If provided, will only return employees for this team. + /// + public string? TeamId { get; init; } + + /// + /// If provided, will only return employees that were terminated after this datetime. + /// + public DateTime? TerminatedAfter { get; init; } + + /// + /// If provided, will only return employees that were terminated before this datetime. + /// + public DateTime? TerminatedBefore { get; init; } + + /// + /// If provided, will only return Employees with this work email + /// + public string? WorkEmail { get; init; } + + /// + /// If provided, will only return employees for this location. + /// + public string? WorkLocationId { get; init; } +} diff --git a/src/Merge.Client/Hris/Employees/requests/EmployeesRetrieveRequest.cs b/src/Merge.Client/Hris/Employees/requests/EmployeesRetrieveRequest.cs new file mode 100644 index 00000000..779ab068 --- /dev/null +++ b/src/Merge.Client/Hris/Employees/requests/EmployeesRetrieveRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmployeesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmployeesRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include sensitive fields (such as social security numbers) in the response. + /// + public bool? IncludeSensitiveFields { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EmployeesRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EmployeesRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/Employees/requests/IgnoreCommonModelRequest.cs b/src/Merge.Client/Hris/Employees/requests/IgnoreCommonModelRequest.cs new file mode 100644 index 00000000..5a2619fc --- /dev/null +++ b/src/Merge.Client/Hris/Employees/requests/IgnoreCommonModelRequest.cs @@ -0,0 +1,10 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class IgnoreCommonModelRequest +{ + public ReasonEnum Reason { get; init; } + + public string? Message { get; init; } +} diff --git a/src/Merge.Client/Hris/EmployerBenefits/EmployerBenefitsClient.cs b/src/Merge.Client/Hris/EmployerBenefits/EmployerBenefitsClient.cs index a4278f7e..ea7626f8 100644 --- a/src/Merge.Client/Hris/EmployerBenefits/EmployerBenefitsClient.cs +++ b/src/Merge.Client/Hris/EmployerBenefits/EmployerBenefitsClient.cs @@ -1,9 +1,102 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class EmployerBenefitsClient { - public async void List(){ + private RawClient _client; + + public EmployerBenefitsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `EmployerBenefit` objects. + /// + public async Task ListAsync(EmployerBenefitsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/employer-benefits", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `EmployerBenefit` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + EmployerBenefitsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/employer-benefits/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsListRequest.cs b/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsListRequest.cs new file mode 100644 index 00000000..145175a2 --- /dev/null +++ b/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Hris; + +public class EmployerBenefitsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsRetrieveRequest.cs b/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsRetrieveRequest.cs new file mode 100644 index 00000000..c2a72493 --- /dev/null +++ b/src/Merge.Client/Hris/EmployerBenefits/requests/EmployerBenefitsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class EmployerBenefitsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/Employments/EmploymentsClient.cs b/src/Merge.Client/Hris/Employments/EmploymentsClient.cs index 0c9e4210..e271e1a1 100644 --- a/src/Merge.Client/Hris/Employments/EmploymentsClient.cs +++ b/src/Merge.Client/Hris/Employments/EmploymentsClient.cs @@ -1,9 +1,131 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class EmploymentsClient { - public async void List(){ + private RawClient _client; + + public EmploymentsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Employment` objects. + /// + public async Task ListAsync(EmploymentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OrderBy != null) + { + _query["order_by"] = request.OrderBy; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/employments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `Employment` object with the given `id`. + /// + public async Task RetrieveAsync(string id, EmploymentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/employments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Employments/requests/EmploymentsListRequest.cs b/src/Merge.Client/Hris/Employments/requests/EmploymentsListRequest.cs new file mode 100644 index 00000000..6f6287c1 --- /dev/null +++ b/src/Merge.Client/Hris/Employments/requests/EmploymentsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmploymentsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return employments for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmploymentsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Overrides the default ordering for this endpoint. + /// + public EmploymentsListRequestOrderBy? OrderBy { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EmploymentsListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EmploymentsListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/Employments/requests/EmploymentsRetrieveRequest.cs b/src/Merge.Client/Hris/Employments/requests/EmploymentsRetrieveRequest.cs new file mode 100644 index 00000000..15a4915b --- /dev/null +++ b/src/Merge.Client/Hris/Employments/requests/EmploymentsRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EmploymentsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public EmploymentsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public EmploymentsRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public EmploymentsRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Hris/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..50913d4e --- /dev/null +++ b/src/Merge.Client/Hris/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,146 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/hris/v1/field-mappings" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/hris/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/hris/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/hris/v1/target-fields" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Hris/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Hris/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..c3d45af1 --- /dev/null +++ b/src/Merge.Client/Hris/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Hris; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Hris/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Hris/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..4ea1aad9 --- /dev/null +++ b/src/Merge.Client/Hris/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Hris; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Hris/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Hris/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..10bd6cc8 --- /dev/null +++ b/src/Merge.Client/Hris/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Hris; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Hris/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Hris/ForceResync/ForceResyncClient.cs index 1be47bb1..9b960b4f 100644 --- a/src/Merge.Client/Hris/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Hris/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Hris/GenerateKey/GenerateKeyClient.cs index 99cc2372..93bfee78 100644 --- a/src/Merge.Client/Hris/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Hris/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Hris/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..cfc9f947 --- /dev/null +++ b/src/Merge.Client/Hris/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Hris/Groups/GroupsClient.cs b/src/Merge.Client/Hris/Groups/GroupsClient.cs index 154cd72c..d8377d4e 100644 --- a/src/Merge.Client/Hris/Groups/GroupsClient.cs +++ b/src/Merge.Client/Hris/Groups/GroupsClient.cs @@ -1,9 +1,123 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class GroupsClient { - public async void List(){ + private RawClient _client; + + public GroupsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Group` objects. + /// + public async Task ListAsync(GroupsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.Names != null) + { + _query["names"] = request.Names; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.Types != null) + { + _query["types"] = request.Types; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/groups", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Group` object with the given `id`. + /// + public async Task RetrieveAsync(string id, GroupsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/groups/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Groups/requests/GroupsListRequest.cs b/src/Merge.Client/Hris/Groups/requests/GroupsListRequest.cs new file mode 100644 index 00000000..fcb81239 --- /dev/null +++ b/src/Merge.Client/Hris/Groups/requests/GroupsListRequest.cs @@ -0,0 +1,69 @@ +namespace Merge.Client.Hris; + +public class GroupsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// If provided, will only return groups with these names. Multiple values can be separated by commas. + /// + public string? Names { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return groups of these types. Multiple values can be separated by commas. + /// + public string? Types { get; init; } +} diff --git a/src/Merge.Client/Hris/Groups/requests/GroupsRetrieveRequest.cs b/src/Merge.Client/Hris/Groups/requests/GroupsRetrieveRequest.cs new file mode 100644 index 00000000..ca9fc360 --- /dev/null +++ b/src/Merge.Client/Hris/Groups/requests/GroupsRetrieveRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Hris; + +public class GroupsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/HrisClient.cs b/src/Merge.Client/Hris/HrisClient.cs new file mode 100644 index 00000000..2dea45e0 --- /dev/null +++ b/src/Merge.Client/Hris/HrisClient.cs @@ -0,0 +1,116 @@ +using Merge.Client; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class HrisClient +{ + private RawClient _client; + + public HrisClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + BankInfo = new BankInfoClient(_client); + Benefits = new BenefitsClient(_client); + Companies = new CompaniesClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + Dependents = new DependentsClient(_client); + EmployeePayrollRuns = new EmployeePayrollRunsClient(_client); + Employees = new EmployeesClient(_client); + EmployerBenefits = new EmployerBenefitsClient(_client); + Employments = new EmploymentsClient(_client); + FieldMapping = new FieldMappingClient(_client); + GenerateKey = new GenerateKeyClient(_client); + Groups = new GroupsClient(_client); + Issues = new IssuesClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Locations = new LocationsClient(_client); + Passthrough = new PassthroughClient(_client); + PayGroups = new PayGroupsClient(_client); + PayrollRuns = new PayrollRunsClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + Teams = new TeamsClient(_client); + TimeOff = new TimeOffClient(_client); + TimeOffBalances = new TimeOffBalancesClient(_client); + TimesheetEntries = new TimesheetEntriesClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public BankInfoClient BankInfo { get; } + + public BenefitsClient Benefits { get; } + + public CompaniesClient Companies { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public DependentsClient Dependents { get; } + + public EmployeePayrollRunsClient EmployeePayrollRuns { get; } + + public EmployeesClient Employees { get; } + + public EmployerBenefitsClient EmployerBenefits { get; } + + public EmploymentsClient Employments { get; } + + public FieldMappingClient FieldMapping { get; } + + public GenerateKeyClient GenerateKey { get; } + + public GroupsClient Groups { get; } + + public IssuesClient Issues { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public LocationsClient Locations { get; } + + public PassthroughClient Passthrough { get; } + + public PayGroupsClient PayGroups { get; } + + public PayrollRunsClient PayrollRuns { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public TeamsClient Teams { get; } + + public TimeOffClient TimeOff { get; } + + public TimeOffBalancesClient TimeOffBalances { get; } + + public TimesheetEntriesClient TimesheetEntries { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Hris/Issues/IssuesClient.cs b/src/Merge.Client/Hris/Issues/IssuesClient.cs index c877a5f0..4e7ed501 100644 --- a/src/Merge.Client/Hris/Issues/IssuesClient.cs +++ b/src/Merge.Client/Hris/Issues/IssuesClient.cs @@ -1,9 +1,105 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = $"/hris/v1/issues/{id}" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Hris/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..55df0479 --- /dev/null +++ b/src/Merge.Client/Hris/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Hris/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Hris/LinkToken/LinkTokenClient.cs index b37a768b..2b2f9543 100644 --- a/src/Merge.Client/Hris/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Hris/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Hris/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..03616614 --- /dev/null +++ b/src/Merge.Client/Hris/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Hris/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Hris/LinkedAccounts/LinkedAccountsClient.cs index 1ffdcb19..0735c043 100644 --- a/src/Merge.Client/Hris/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Hris/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Hris/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..234af1bb --- /dev/null +++ b/src/Merge.Client/Hris/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class LinkedAccountsListRequest +{ + /// + /// Options: ('hris', 'ats', 'accounting', 'ticketing', 'crm', 'mktg', 'filestorage') + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Hris/Locations/LocationsClient.cs b/src/Merge.Client/Hris/Locations/LocationsClient.cs index 8e2d6009..8ba1e32f 100644 --- a/src/Merge.Client/Hris/Locations/LocationsClient.cs +++ b/src/Merge.Client/Hris/Locations/LocationsClient.cs @@ -1,9 +1,119 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class LocationsClient { - public async void List(){ + private RawClient _client; + + public LocationsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Location` objects. + /// + public async Task ListAsync(LocationsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.LocationType != null) + { + _query["location_type"] = request.LocationType; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/locations", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Location` object with the given `id`. + /// + public async Task RetrieveAsync(string id, LocationsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/locations/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Locations/requests/LocationsListRequest.cs b/src/Merge.Client/Hris/Locations/requests/LocationsListRequest.cs new file mode 100644 index 00000000..5b7a4425 --- /dev/null +++ b/src/Merge.Client/Hris/Locations/requests/LocationsListRequest.cs @@ -0,0 +1,69 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class LocationsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, will only return locations with this location_type + /// + /// - `HOME` - HOME + /// - `WORK` - WORK + /// + public LocationsListRequestLocationType? LocationType { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/Locations/requests/LocationsRetrieveRequest.cs b/src/Merge.Client/Hris/Locations/requests/LocationsRetrieveRequest.cs new file mode 100644 index 00000000..acde5e21 --- /dev/null +++ b/src/Merge.Client/Hris/Locations/requests/LocationsRetrieveRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Hris; + +public class LocationsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/Passthrough/PassthroughClient.cs b/src/Merge.Client/Hris/Passthrough/PassthroughClient.cs index 9aa68dc8..3c857dfa 100644 --- a/src/Merge.Client/Hris/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Hris/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/PayGroups/PayGroupsClient.cs b/src/Merge.Client/Hris/PayGroups/PayGroupsClient.cs index ffbd8d22..729597b6 100644 --- a/src/Merge.Client/Hris/PayGroups/PayGroupsClient.cs +++ b/src/Merge.Client/Hris/PayGroups/PayGroupsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class PayGroupsClient { - public async void List(){ + private RawClient _client; + + public PayGroupsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `PayGroup` objects. + /// + public async Task ListAsync(PayGroupsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/pay-groups", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `PayGroup` object with the given `id`. + /// + public async Task RetrieveAsync(string id, PayGroupsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/pay-groups/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/PayGroups/requests/PayGroupsListRequest.cs b/src/Merge.Client/Hris/PayGroups/requests/PayGroupsListRequest.cs new file mode 100644 index 00000000..00582f4d --- /dev/null +++ b/src/Merge.Client/Hris/PayGroups/requests/PayGroupsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Hris; + +public class PayGroupsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/PayGroups/requests/PayGroupsRetrieveRequest.cs b/src/Merge.Client/Hris/PayGroups/requests/PayGroupsRetrieveRequest.cs new file mode 100644 index 00000000..2563e9ac --- /dev/null +++ b/src/Merge.Client/Hris/PayGroups/requests/PayGroupsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class PayGroupsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/PayrollRuns/PayrollRunsClient.cs b/src/Merge.Client/Hris/PayrollRuns/PayrollRunsClient.cs index cfbf1843..57cf8cb7 100644 --- a/src/Merge.Client/Hris/PayrollRuns/PayrollRunsClient.cs +++ b/src/Merge.Client/Hris/PayrollRuns/PayrollRunsClient.cs @@ -1,9 +1,135 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class PayrollRunsClient { - public async void List(){ + private RawClient _client; + + public PayrollRunsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `PayrollRun` objects. + /// + public async Task ListAsync(PayrollRunsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndedAfter != null) + { + _query["ended_after"] = request.EndedAfter; + } + if (request.EndedBefore != null) + { + _query["ended_before"] = request.EndedBefore; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.RunType != null) + { + _query["run_type"] = request.RunType; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/payroll-runs", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `PayrollRun` object with the given `id`. + /// + public async Task RetrieveAsync(string id, PayrollRunsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/payroll-runs/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsListRequest.cs b/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsListRequest.cs new file mode 100644 index 00000000..c317928f --- /dev/null +++ b/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsListRequest.cs @@ -0,0 +1,92 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class PayrollRunsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return payroll runs ended after this datetime. + /// + public DateTime? EndedAfter { get; init; } + + /// + /// If provided, will only return payroll runs ended before this datetime. + /// + public DateTime? EndedBefore { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public PayrollRunsListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return PayrollRun's with this status. Options: ('REGULAR', 'OFF_CYCLE', 'CORRECTION', 'TERMINATION', 'SIGN_ON_BONUS') + /// + /// - `REGULAR` - REGULAR + /// - `OFF_CYCLE` - OFF_CYCLE + /// - `CORRECTION` - CORRECTION + /// - `TERMINATION` - TERMINATION + /// - `SIGN_ON_BONUS` - SIGN_ON_BONUS + /// + public PayrollRunsListRequestRunType? RunType { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public PayrollRunsListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return payroll runs started after this datetime. + /// + public DateTime? StartedAfter { get; init; } + + /// + /// If provided, will only return payroll runs started before this datetime. + /// + public DateTime? StartedBefore { get; init; } +} diff --git a/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsRetrieveRequest.cs b/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsRetrieveRequest.cs new file mode 100644 index 00000000..b14228b4 --- /dev/null +++ b/src/Merge.Client/Hris/PayrollRuns/requests/PayrollRunsRetrieveRequest.cs @@ -0,0 +1,21 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class PayrollRunsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public PayrollRunsRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public PayrollRunsRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Hris/RegenerateKey/RegenerateKeyClient.cs index dde98e8c..c9da87f1 100644 --- a/src/Merge.Client/Hris/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Hris/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Hris/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..eb20087e --- /dev/null +++ b/src/Merge.Client/Hris/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Hris/Scopes/ScopesClient.cs b/src/Merge.Client/Hris/Scopes/ScopesClient.cs new file mode 100644 index 00000000..56b70d13 --- /dev/null +++ b/src/Merge.Client/Hris/Scopes/ScopesClient.cs @@ -0,0 +1,74 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest { Method = HttpMethod.Get, Path = "/hris/v1/default-scopes" } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Hris/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Hris/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..59f583ad --- /dev/null +++ b/src/Merge.Client/Hris/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Hris/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Hris/SelectiveSync/SelectiveSyncClient.cs index cb558335..a902a9e7 100644 --- a/src/Merge.Client/Hris/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Hris/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/hris/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Hris/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..4456999b --- /dev/null +++ b/src/Merge.Client/Hris/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Hris/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Hris/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..42280860 --- /dev/null +++ b/src/Merge.Client/Hris/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Hris; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Hris/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Hris/SyncStatus/SyncStatusClient.cs index 5c149df5..f2541657 100644 --- a/src/Merge.Client/Hris/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Hris/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Hris/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..b3f49c5c --- /dev/null +++ b/src/Merge.Client/Hris/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Hris; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Hris/Teams/TeamsClient.cs b/src/Merge.Client/Hris/Teams/TeamsClient.cs index d2b0bcf0..2aceda98 100644 --- a/src/Merge.Client/Hris/Teams/TeamsClient.cs +++ b/src/Merge.Client/Hris/Teams/TeamsClient.cs @@ -1,9 +1,111 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class TeamsClient { - public async void List(){ + private RawClient _client; + + public TeamsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Team` objects. + /// + public async Task ListAsync(TeamsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.ParentTeamId != null) + { + _query["parent_team_id"] = request.ParentTeamId; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/teams", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Team` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TeamsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/teams/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/Teams/requests/TeamsListRequest.cs b/src/Merge.Client/Hris/Teams/requests/TeamsListRequest.cs new file mode 100644 index 00000000..c26b6a4e --- /dev/null +++ b/src/Merge.Client/Hris/Teams/requests/TeamsListRequest.cs @@ -0,0 +1,59 @@ +namespace Merge.Client.Hris; + +public class TeamsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return teams with this parent team. + /// + public string? ParentTeamId { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Hris/Teams/requests/TeamsRetrieveRequest.cs b/src/Merge.Client/Hris/Teams/requests/TeamsRetrieveRequest.cs new file mode 100644 index 00000000..aa6ada45 --- /dev/null +++ b/src/Merge.Client/Hris/Teams/requests/TeamsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Hris; + +public class TeamsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/TimeOff/TimeOffClient.cs b/src/Merge.Client/Hris/TimeOff/TimeOffClient.cs index 30c412c4..f4a7fc75 100644 --- a/src/Merge.Client/Hris/TimeOff/TimeOffClient.cs +++ b/src/Merge.Client/Hris/TimeOff/TimeOffClient.cs @@ -1,13 +1,205 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class TimeOffClient { - public async void List(){ + private RawClient _client; + + public TimeOffClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `TimeOff` objects. + /// + public async Task ListAsync(TimeOffListRequest request) + { + var _query = new Dictionary() { }; + if (request.ApproverId != null) + { + _query["approver_id"] = request.ApproverId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.EndedAfter != null) + { + _query["ended_after"] = request.EndedAfter; + } + if (request.EndedBefore != null) + { + _query["ended_before"] = request.EndedBefore; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.RequestType != null) + { + _query["request_type"] = request.RequestType; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/time-off", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `TimeOff` object with the given values. + /// + public async Task CreateAsync(TimeOffEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/time-off", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `TimeOff` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TimeOffRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/time-off/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `TimeOff` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/time-off/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/TimeOff/requests/TimeOffEndpointRequest.cs b/src/Merge.Client/Hris/TimeOff/requests/TimeOffEndpointRequest.cs new file mode 100644 index 00000000..47046758 --- /dev/null +++ b/src/Merge.Client/Hris/TimeOff/requests/TimeOffEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimeOffEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public TimeOffRequest Model { get; init; } +} diff --git a/src/Merge.Client/Hris/TimeOff/requests/TimeOffListRequest.cs b/src/Merge.Client/Hris/TimeOff/requests/TimeOffListRequest.cs new file mode 100644 index 00000000..ca11e49e --- /dev/null +++ b/src/Merge.Client/Hris/TimeOff/requests/TimeOffListRequest.cs @@ -0,0 +1,119 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimeOffListRequest +{ + /// + /// If provided, will only return time off for this approver. + /// + public string? ApproverId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return time off for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// If provided, will only return employees that ended after this datetime. + /// + public DateTime? EndedAfter { get; init; } + + /// + /// If provided, will only return time-offs that ended before this datetime. + /// + public DateTime? EndedBefore { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TimeOffListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public TimeOffListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return TimeOff with this request type. Options: ('VACATION', 'SICK', 'PERSONAL', 'JURY_DUTY', 'VOLUNTEER', 'BEREAVEMENT') + /// + /// - `VACATION` - VACATION + /// - `SICK` - SICK + /// - `PERSONAL` - PERSONAL + /// - `JURY_DUTY` - JURY_DUTY + /// - `VOLUNTEER` - VOLUNTEER + /// - `BEREAVEMENT` - BEREAVEMENT + /// + public TimeOffListRequestRequestType? RequestType { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public TimeOffListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return time-offs that started after this datetime. + /// + public DateTime? StartedAfter { get; init; } + + /// + /// If provided, will only return time-offs that started before this datetime. + /// + public DateTime? StartedBefore { get; init; } + + /// + /// If provided, will only return TimeOff with this status. Options: ('REQUESTED', 'APPROVED', 'DECLINED', 'CANCELLED', 'DELETED') + /// + /// - `REQUESTED` - REQUESTED + /// - `APPROVED` - APPROVED + /// - `DECLINED` - DECLINED + /// - `CANCELLED` - CANCELLED + /// - `DELETED` - DELETED + /// + public TimeOffListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Hris/TimeOff/requests/TimeOffRetrieveRequest.cs b/src/Merge.Client/Hris/TimeOff/requests/TimeOffRetrieveRequest.cs new file mode 100644 index 00000000..6ea94e49 --- /dev/null +++ b/src/Merge.Client/Hris/TimeOff/requests/TimeOffRetrieveRequest.cs @@ -0,0 +1,26 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimeOffRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TimeOffRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public TimeOffRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public TimeOffRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/TimeOffBalances/TimeOffBalancesClient.cs b/src/Merge.Client/Hris/TimeOffBalances/TimeOffBalancesClient.cs index 8d3591a1..9e1fb872 100644 --- a/src/Merge.Client/Hris/TimeOffBalances/TimeOffBalancesClient.cs +++ b/src/Merge.Client/Hris/TimeOffBalances/TimeOffBalancesClient.cs @@ -1,9 +1,134 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class TimeOffBalancesClient { - public async void List(){ + private RawClient _client; + + public TimeOffBalancesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `TimeOffBalance` objects. + /// + public async Task ListAsync(TimeOffBalancesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.PolicyType != null) + { + _query["policy_type"] = request.PolicyType; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/time-off-balances", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `TimeOffBalance` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + TimeOffBalancesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/time-off-balances/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesListRequest.cs b/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesListRequest.cs new file mode 100644 index 00000000..1477e297 --- /dev/null +++ b/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesListRequest.cs @@ -0,0 +1,83 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimeOffBalancesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return time off balances for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return TimeOffBalance with this policy type. Options: ('VACATION', 'SICK', 'PERSONAL', 'JURY_DUTY', 'VOLUNTEER', 'BEREAVEMENT') + /// + /// - `VACATION` - VACATION + /// - `SICK` - SICK + /// - `PERSONAL` - PERSONAL + /// - `JURY_DUTY` - JURY_DUTY + /// - `VOLUNTEER` - VOLUNTEER + /// - `BEREAVEMENT` - BEREAVEMENT + /// + public TimeOffBalancesListRequestPolicyType? PolicyType { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesRetrieveRequest.cs b/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesRetrieveRequest.cs new file mode 100644 index 00000000..2f67f4bf --- /dev/null +++ b/src/Merge.Client/Hris/TimeOffBalances/requests/TimeOffBalancesRetrieveRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Hris; + +public class TimeOffBalancesRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Hris/TimesheetEntries/TimesheetEntriesClient.cs b/src/Merge.Client/Hris/TimesheetEntries/TimesheetEntriesClient.cs index b3d65929..e4ed9594 100644 --- a/src/Merge.Client/Hris/TimesheetEntries/TimesheetEntriesClient.cs +++ b/src/Merge.Client/Hris/TimesheetEntries/TimesheetEntriesClient.cs @@ -1,13 +1,176 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class TimesheetEntriesClient { - public async void List(){ + private RawClient _client; + + public TimesheetEntriesClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `TimesheetEntry` objects. + /// + public async Task ListAsync(TimesheetEntriesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmployeeId != null) + { + _query["employee_id"] = request.EmployeeId; + } + if (request.EndedAfter != null) + { + _query["ended_after"] = request.EndedAfter; + } + if (request.EndedBefore != null) + { + _query["ended_before"] = request.EndedBefore; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.OrderBy != null) + { + _query["order_by"] = request.OrderBy; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.StartedAfter != null) + { + _query["started_after"] = request.StartedAfter; + } + if (request.StartedBefore != null) + { + _query["started_before"] = request.StartedBefore; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/timesheet-entries", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `TimesheetEntry` object with the given values. + /// + public async Task CreateAsync(TimesheetEntryEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/timesheet-entries", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `TimesheetEntry` object with the given `id`. + /// + public async Task RetrieveAsync( + string id, + TimesheetEntriesRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/hris/v1/timesheet-entries/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `TimesheetEntry` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/timesheet-entries/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesListRequest.cs b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesListRequest.cs new file mode 100644 index 00000000..5094eb73 --- /dev/null +++ b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesListRequest.cs @@ -0,0 +1,81 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimesheetEntriesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return employee payroll runs for this employee. + /// + public string? EmployeeId { get; init; } + + /// + /// If provided, will only return employee payroll runs ended after this datetime. + /// + public string? EndedAfter { get; init; } + + /// + /// If provided, will only return employee payroll runs ended before this datetime. + /// + public string? EndedBefore { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Overrides the default ordering for this endpoint. Possible values include: start_time, -start_time. + /// + public TimesheetEntriesListRequestOrderBy? OrderBy { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return employee payroll runs started after this datetime. + /// + public string? StartedAfter { get; init; } + + /// + /// If provided, will only return employee payroll runs started before this datetime. + /// + public string? StartedBefore { get; init; } +} diff --git a/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesRetrieveRequest.cs b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesRetrieveRequest.cs new file mode 100644 index 00000000..9031bdec --- /dev/null +++ b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntriesRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Hris; + +public class TimesheetEntriesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntryEndpointRequest.cs b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntryEndpointRequest.cs new file mode 100644 index 00000000..1f47ca5d --- /dev/null +++ b/src/Merge.Client/Hris/TimesheetEntries/requests/TimesheetEntryEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class TimesheetEntryEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public TimesheetEntryRequest Model { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Hris/Types/AccountDetailsAndActions.cs index 4a6b5a6f..5e30ed17 100644 --- a/src/Merge.Client/Hris/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Hris/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Hris/Types/AccountIntegration.cs b/src/Merge.Client/Hris/Types/AccountIntegration.cs index 9d691c82..1da6b287 100644 --- a/src/Merge.Client/Hris/Types/AccountIntegration.cs +++ b/src/Merge.Client/Hris/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Hris/Types/AdvancedMetadata.cs b/src/Merge.Client/Hris/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..af48a5bd --- /dev/null +++ b/src/Merge.Client/Hris/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/AuditLogEvent.cs b/src/Merge.Client/Hris/Types/AuditLogEvent.cs index f7abe098..56a17166 100644 --- a/src/Merge.Client/Hris/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Hris/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Hris/Types/BankInfo.cs b/src/Merge.Client/Hris/Types/BankInfo.cs index b4401ef0..f699f88f 100644 --- a/src/Merge.Client/Hris/Types/BankInfo.cs +++ b/src/Merge.Client/Hris/Types/BankInfo.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class BankInfo [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee with this bank account. /// @@ -41,7 +50,7 @@ public class BankInfo /// /// The bank account type - /// + /// /// - `SAVINGS` - SAVINGS /// - `CHECKING` - CHECKING /// @@ -60,15 +69,6 @@ public class BankInfo [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Benefit.cs b/src/Merge.Client/Hris/Types/Benefit.cs index 3a204826..5a748f38 100644 --- a/src/Merge.Client/Hris/Types/Benefit.cs +++ b/src/Merge.Client/Hris/Types/Benefit.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class Benefit [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee on the plan. /// @@ -69,15 +78,6 @@ public class Benefit [JsonPropertyName("employer_benefit")] public string? EmployerBenefit { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/CommonModelScopeApi.cs b/src/Merge.Client/Hris/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..19c84b75 --- /dev/null +++ b/src/Merge.Client/Hris/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/Company.cs b/src/Merge.Client/Hris/Types/Company.cs index 2b430d17..fe290f67 100644 --- a/src/Merge.Client/Hris/Types/Company.cs +++ b/src/Merge.Client/Hris/Types/Company.cs @@ -14,6 +14,15 @@ public class Company [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The company's legal name. /// @@ -38,15 +47,6 @@ public class Company [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/ConditionSchema.cs b/src/Merge.Client/Hris/Types/ConditionSchema.cs index 7276b18b..b7616164 100644 --- a/src/Merge.Client/Hris/Types/ConditionSchema.cs +++ b/src/Merge.Client/Hris/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Hris/Types/DataPassthroughRequest.cs b/src/Merge.Client/Hris/Types/DataPassthroughRequest.cs index df0204d1..adb99a6e 100644 --- a/src/Merge.Client/Hris/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Hris/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Hris/Types/Deduction.cs b/src/Merge.Client/Hris/Types/Deduction.cs index e1d908cd..5789c558 100644 --- a/src/Merge.Client/Hris/Types/Deduction.cs +++ b/src/Merge.Client/Hris/Types/Deduction.cs @@ -14,6 +14,15 @@ public class Deduction [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("employee_payroll_run")] public string? EmployeePayrollRun { get; init; } @@ -41,15 +50,6 @@ public class Deduction [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Dependent.cs b/src/Merge.Client/Hris/Types/Dependent.cs index eb3d7416..6c9cc8af 100644 --- a/src/Merge.Client/Hris/Types/Dependent.cs +++ b/src/Merge.Client/Hris/Types/Dependent.cs @@ -14,6 +14,15 @@ public class Dependent [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The dependents's first name. /// @@ -34,7 +43,7 @@ public class Dependent /// /// The dependent's relationship to the employee. - /// + /// /// - `CHILD` - CHILD /// - `SPOUSE` - SPOUSE /// - `DOMESTIC_PARTNER` - DOMESTIC_PARTNER @@ -56,7 +65,7 @@ public class Dependent /// /// The dependent's gender. - /// + /// /// - `MALE` - MALE /// - `FEMALE` - FEMALE /// - `NON-BINARY` - NON-BINARY @@ -96,15 +105,6 @@ public class Dependent [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Earning.cs b/src/Merge.Client/Hris/Types/Earning.cs index 49283037..f303d3c3 100644 --- a/src/Merge.Client/Hris/Types/Earning.cs +++ b/src/Merge.Client/Hris/Types/Earning.cs @@ -14,6 +14,15 @@ public class Earning [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("employee_payroll_run")] public string? EmployeePayrollRun { get; init; } @@ -25,7 +34,7 @@ public class Earning /// /// The type of earning. - /// + /// /// - `SALARY` - SALARY /// - `REIMBURSEMENT` - REIMBURSEMENT /// - `OVERTIME` - OVERTIME @@ -40,15 +49,6 @@ public class Earning [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Employee.cs b/src/Merge.Client/Hris/Types/Employee.cs index e4882f0c..6ae6330d 100644 --- a/src/Merge.Client/Hris/Types/Employee.cs +++ b/src/Merge.Client/Hris/Types/Employee.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class Employee [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee's number that appears in the third-party integration's UI. /// @@ -122,7 +131,7 @@ public class Employee /// /// The employee's gender. - /// + /// /// - `MALE` - MALE /// - `FEMALE` - FEMALE /// - `NON-BINARY` - NON-BINARY @@ -134,7 +143,7 @@ public class Employee /// /// The employee's ethnicity. - /// + /// /// - `AMERICAN_INDIAN_OR_ALASKA_NATIVE` - AMERICAN_INDIAN_OR_ALASKA_NATIVE /// - `ASIAN_OR_INDIAN_SUBCONTINENT` - ASIAN_OR_INDIAN_SUBCONTINENT /// - `BLACK_OR_AFRICAN_AMERICAN` - BLACK_OR_AFRICAN_AMERICAN @@ -149,7 +158,7 @@ public class Employee /// /// The employee's filing status as related to marital status. - /// + /// /// - `SINGLE` - SINGLE /// - `MARRIED_FILING_JOINTLY` - MARRIED_FILING_JOINTLY /// - `MARRIED_FILING_SEPARATELY` - MARRIED_FILING_SEPARATELY @@ -185,7 +194,7 @@ public class Employee /// /// The employment status of the employee. - /// + /// /// - `ACTIVE` - ACTIVE /// - `PENDING` - PENDING /// - `INACTIVE` - INACTIVE @@ -214,15 +223,6 @@ public class Employee [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/EmployeePayrollRun.cs b/src/Merge.Client/Hris/Types/EmployeePayrollRun.cs index 67a38297..d2f53fe4 100644 --- a/src/Merge.Client/Hris/Types/EmployeePayrollRun.cs +++ b/src/Merge.Client/Hris/Types/EmployeePayrollRun.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class EmployeePayrollRun [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee whose payroll is being run. /// @@ -72,15 +81,6 @@ public class EmployeePayrollRun [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/EmployeeRequest.cs b/src/Merge.Client/Hris/Types/EmployeeRequest.cs index d1d628ec..ec5d66f0 100644 --- a/src/Merge.Client/Hris/Types/EmployeeRequest.cs +++ b/src/Merge.Client/Hris/Types/EmployeeRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -113,7 +113,7 @@ public class EmployeeRequest /// /// The employee's gender. - /// + /// /// - `MALE` - MALE /// - `FEMALE` - FEMALE /// - `NON-BINARY` - NON-BINARY @@ -125,7 +125,7 @@ public class EmployeeRequest /// /// The employee's ethnicity. - /// + /// /// - `AMERICAN_INDIAN_OR_ALASKA_NATIVE` - AMERICAN_INDIAN_OR_ALASKA_NATIVE /// - `ASIAN_OR_INDIAN_SUBCONTINENT` - ASIAN_OR_INDIAN_SUBCONTINENT /// - `BLACK_OR_AFRICAN_AMERICAN` - BLACK_OR_AFRICAN_AMERICAN @@ -140,7 +140,7 @@ public class EmployeeRequest /// /// The employee's filing status as related to marital status. - /// + /// /// - `SINGLE` - SINGLE /// - `MARRIED_FILING_JOINTLY` - MARRIED_FILING_JOINTLY /// - `MARRIED_FILING_SEPARATELY` - MARRIED_FILING_SEPARATELY @@ -170,7 +170,7 @@ public class EmployeeRequest /// /// The employment status of the employee. - /// + /// /// - `ACTIVE` - ACTIVE /// - `PENDING` - PENDING /// - `INACTIVE` - INACTIVE diff --git a/src/Merge.Client/Hris/Types/EmployerBenefit.cs b/src/Merge.Client/Hris/Types/EmployerBenefit.cs index c6dc0837..b454274e 100644 --- a/src/Merge.Client/Hris/Types/EmployerBenefit.cs +++ b/src/Merge.Client/Hris/Types/EmployerBenefit.cs @@ -14,9 +14,18 @@ public class EmployerBenefit [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The type of benefit plan. - /// + /// /// - `MEDICAL` - MEDICAL /// - `HEALTH_SAVINGS` - HEALTH_SAVINGS /// - `INSURANCE` - INSURANCE @@ -50,15 +59,6 @@ public class EmployerBenefit [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Employment.cs b/src/Merge.Client/Hris/Types/Employment.cs index fd516a9d..ca4fef13 100644 --- a/src/Merge.Client/Hris/Types/Employment.cs +++ b/src/Merge.Client/Hris/Types/Employment.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class Employment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee holding this position. /// @@ -35,7 +44,7 @@ public class Employment /// /// The time period this pay rate encompasses. - /// + /// /// - `HOUR` - HOUR /// - `DAY` - DAY /// - `WEEK` - WEEK @@ -51,7 +60,7 @@ public class Employment /// /// The position's pay frequency. - /// + /// /// - `WEEKLY` - WEEKLY /// - `BIWEEKLY` - BIWEEKLY /// - `MONTHLY` - MONTHLY @@ -67,7 +76,7 @@ public class Employment /// /// The position's currency code. - /// + /// /// - `XUA` - ADB Unit of Account /// - `AFN` - Afghan Afghani /// - `AFA` - Afghan Afghani (1927–2002) @@ -386,7 +395,7 @@ public class Employment /// /// The position's FLSA status. - /// + /// /// - `EXEMPT` - EXEMPT /// - `SALARIED_NONEXEMPT` - SALARIED_NONEXEMPT /// - `NONEXEMPT` - NONEXEMPT @@ -403,7 +412,7 @@ public class Employment /// /// The position's type of employment. - /// + /// /// - `FULL_TIME` - FULL_TIME /// - `PART_TIME` - PART_TIME /// - `INTERN` - INTERN @@ -419,15 +428,6 @@ public class Employment [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/EventTypeEnum.cs b/src/Merge.Client/Hris/Types/EventTypeEnum.cs index 73ed061e..595f7802 100644 --- a/src/Merge.Client/Hris/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Hris/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Hris/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Hris/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..d3da1d3f --- /dev/null +++ b/src/Merge.Client/Hris/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Hris/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..56edaf08 --- /dev/null +++ b/src/Merge.Client/Hris/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("Benefit")] + public List? Benefit { get; init; } + + [JsonPropertyName("EmployerBenefit")] + public List? EmployerBenefit { get; init; } + + [JsonPropertyName("Company")] + public List? Company { get; init; } + + [JsonPropertyName("EmployeePayrollRun")] + public List? EmployeePayrollRun { get; init; } + + [JsonPropertyName("Employee")] + public List? Employee { get; init; } + + [JsonPropertyName("Employment")] + public List? Employment { get; init; } + + [JsonPropertyName("Location")] + public List? Location { get; init; } + + [JsonPropertyName("PayrollRun")] + public List? PayrollRun { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("TimeOff")] + public List? TimeOff { get; init; } + + [JsonPropertyName("TimeOffBalance")] + public List? TimeOffBalance { get; init; } + + [JsonPropertyName("BankInfo")] + public List? BankInfo { get; init; } + + [JsonPropertyName("PayGroup")] + public List? PayGroup { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("Dependent")] + public List? Dependent { get; init; } + + [JsonPropertyName("TimesheetEntry")] + public List? TimesheetEntry { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Hris/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..995c4122 --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..654ff55d --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..61e5839e --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..0aa4b920 --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("Benefit")] + public List? Benefit { get; init; } + + [JsonPropertyName("EmployerBenefit")] + public List? EmployerBenefit { get; init; } + + [JsonPropertyName("Company")] + public List? Company { get; init; } + + [JsonPropertyName("EmployeePayrollRun")] + public List? EmployeePayrollRun { get; init; } + + [JsonPropertyName("Employee")] + public List? Employee { get; init; } + + [JsonPropertyName("Employment")] + public List? Employment { get; init; } + + [JsonPropertyName("Location")] + public List? Location { get; init; } + + [JsonPropertyName("PayrollRun")] + public List? PayrollRun { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("TimeOff")] + public List? TimeOff { get; init; } + + [JsonPropertyName("TimeOffBalance")] + public List? TimeOffBalance { get; init; } + + [JsonPropertyName("BankInfo")] + public List? BankInfo { get; init; } + + [JsonPropertyName("PayGroup")] + public List? PayGroup { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("Dependent")] + public List? Dependent { get; init; } + + [JsonPropertyName("TimesheetEntry")] + public List? TimesheetEntry { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..e9dd2ccb --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Hris/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..7aba111c --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Hris/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..bb075435 --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Hris/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..4b052144 --- /dev/null +++ b/src/Merge.Client/Hris/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/Group.cs b/src/Merge.Client/Hris/Types/Group.cs index 47cf847c..09f517b9 100644 --- a/src/Merge.Client/Hris/Types/Group.cs +++ b/src/Merge.Client/Hris/Types/Group.cs @@ -14,6 +14,15 @@ public class Group [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The parent group for this group. /// @@ -27,8 +36,8 @@ public class Group public string? Name { get; init; } /// - /// The group type - /// + /// The Group type returned directly from the third-party. + /// /// - `TEAM` - TEAM /// - `DEPARTMENT` - DEPARTMENT /// - `COST_CENTER` - COST_CENTER @@ -44,15 +53,6 @@ public class Group [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..707486b6 --- /dev/null +++ b/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..a18ef956 --- /dev/null +++ b/src/Merge.Client/Hris/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/Issue.cs b/src/Merge.Client/Hris/Types/Issue.cs index f95b0041..ca4e95f4 100644 --- a/src/Merge.Client/Hris/Types/Issue.cs +++ b/src/Merge.Client/Hris/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Hris/Types/LinkedAccountCondition.cs b/src/Merge.Client/Hris/Types/LinkedAccountCondition.cs index 6227264e..ce71e256 100644 --- a/src/Merge.Client/Hris/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Hris/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Hris/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Hris/Types/LinkedAccountConditionRequest.cs index 8c054d5d..be3cb684 100644 --- a/src/Merge.Client/Hris/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Hris/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Hris; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Hris/Types/Location.cs b/src/Merge.Client/Hris/Types/Location.cs index 7f0bcf5c..a31a2dd5 100644 --- a/src/Merge.Client/Hris/Types/Location.cs +++ b/src/Merge.Client/Hris/Types/Location.cs @@ -14,6 +14,15 @@ public class Location [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The location's name. /// @@ -58,7 +67,7 @@ public class Location /// /// The location's country. - /// + /// /// - `AF` - Afghanistan /// - `AX` - Åland Islands /// - `AL` - Albania @@ -314,7 +323,7 @@ public class Location /// /// The location's type. Can be either WORK or HOME - /// + /// /// - `HOME` - HOME /// - `WORK` - WORK /// @@ -327,15 +336,6 @@ public class Location [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Hris/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..9fbe9871 --- /dev/null +++ b/src/Merge.Client/Hris/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Hris/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..fdd2efa9 --- /dev/null +++ b/src/Merge.Client/Hris/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Hris/Types/MultipartFormFieldRequest.cs index 2a03996e..753545ab 100644 --- a/src/Merge.Client/Hris/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Hris/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Hris/Types/PayGroup.cs b/src/Merge.Client/Hris/Types/PayGroup.cs index ba012b73..2bbeb854 100644 --- a/src/Merge.Client/Hris/Types/PayGroup.cs +++ b/src/Merge.Client/Hris/Types/PayGroup.cs @@ -14,6 +14,15 @@ public class PayGroup [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The pay group name. /// @@ -26,15 +35,6 @@ public class PayGroup [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/PayrollRun.cs b/src/Merge.Client/Hris/Types/PayrollRun.cs index 8110518e..4363745f 100644 --- a/src/Merge.Client/Hris/Types/PayrollRun.cs +++ b/src/Merge.Client/Hris/Types/PayrollRun.cs @@ -14,9 +14,18 @@ public class PayrollRun [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The state of the payroll run - /// + /// /// - `PAID` - PAID /// - `DRAFT` - DRAFT /// - `APPROVED` - APPROVED @@ -28,7 +37,7 @@ public class PayrollRun /// /// The type of the payroll run - /// + /// /// - `REGULAR` - REGULAR /// - `OFF_CYCLE` - OFF_CYCLE /// - `CORRECTION` - CORRECTION @@ -62,15 +71,6 @@ public class PayrollRun [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Hris/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..ac9d1452 --- /dev/null +++ b/src/Merge.Client/Hris/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Hris; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/RemoteFieldApi.cs b/src/Merge.Client/Hris/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..261ed25a --- /dev/null +++ b/src/Merge.Client/Hris/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Hris/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..3b6160a3 --- /dev/null +++ b/src/Merge.Client/Hris/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Merge.Client.Hris; + +namespace Merge.Client.Hris; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("Benefit")] + public List? Benefit { get; init; } + + [JsonPropertyName("EmployerBenefit")] + public List? EmployerBenefit { get; init; } + + [JsonPropertyName("Company")] + public List? Company { get; init; } + + [JsonPropertyName("EmployeePayrollRun")] + public List? EmployeePayrollRun { get; init; } + + [JsonPropertyName("Employee")] + public List? Employee { get; init; } + + [JsonPropertyName("Employment")] + public List? Employment { get; init; } + + [JsonPropertyName("Location")] + public List? Location { get; init; } + + [JsonPropertyName("PayrollRun")] + public List? PayrollRun { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("TimeOff")] + public List? TimeOff { get; init; } + + [JsonPropertyName("TimeOffBalance")] + public List? TimeOffBalance { get; init; } + + [JsonPropertyName("BankInfo")] + public List? BankInfo { get; init; } + + [JsonPropertyName("PayGroup")] + public List? PayGroup { get; init; } + + [JsonPropertyName("Group")] + public List? Group { get; init; } + + [JsonPropertyName("Dependent")] + public List? Dependent { get; init; } + + [JsonPropertyName("TimesheetEntry")] + public List? TimesheetEntry { get; init; } +} diff --git a/src/Merge.Client/Hris/Types/Tax.cs b/src/Merge.Client/Hris/Types/Tax.cs index 053e58a5..764e82e9 100644 --- a/src/Merge.Client/Hris/Types/Tax.cs +++ b/src/Merge.Client/Hris/Types/Tax.cs @@ -14,6 +14,15 @@ public class Tax [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("employee_payroll_run")] public string? EmployeePayrollRun { get; init; } @@ -41,15 +50,6 @@ public class Tax [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/Team.cs b/src/Merge.Client/Hris/Types/Team.cs index 580a4c5c..06f0befc 100644 --- a/src/Merge.Client/Hris/Types/Team.cs +++ b/src/Merge.Client/Hris/Types/Team.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class Team [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The team's name. /// @@ -33,15 +42,6 @@ public class Team [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/TimeOff.cs b/src/Merge.Client/Hris/Types/TimeOff.cs index 5c4852f3..eebecd18 100644 --- a/src/Merge.Client/Hris/Types/TimeOff.cs +++ b/src/Merge.Client/Hris/Types/TimeOff.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class TimeOff [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee requesting time off. /// @@ -29,7 +38,7 @@ public class TimeOff /// /// The status of this time off request. - /// + /// /// - `REQUESTED` - REQUESTED /// - `APPROVED` - APPROVED /// - `DECLINED` - DECLINED @@ -47,7 +56,7 @@ public class TimeOff /// /// The measurement that the third-party integration uses to count time requested. - /// + /// /// - `HOURS` - HOURS /// - `DAYS` - DAYS /// @@ -62,7 +71,7 @@ public class TimeOff /// /// The type of time off request. - /// + /// /// - `VACATION` - VACATION /// - `SICK` - SICK /// - `PERSONAL` - PERSONAL @@ -88,15 +97,6 @@ public class TimeOff [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/TimeOffBalance.cs b/src/Merge.Client/Hris/Types/TimeOffBalance.cs index 975b8134..276c9c1b 100644 --- a/src/Merge.Client/Hris/Types/TimeOffBalance.cs +++ b/src/Merge.Client/Hris/Types/TimeOffBalance.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -15,6 +15,15 @@ public class TimeOffBalance [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee the balance belongs to. /// @@ -35,7 +44,7 @@ public class TimeOffBalance /// /// The policy type of this time off balance. - /// + /// /// - `VACATION` - VACATION /// - `SICK` - SICK /// - `PERSONAL` - PERSONAL @@ -52,15 +61,6 @@ public class TimeOffBalance [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Hris/Types/TimeOffRequest.cs b/src/Merge.Client/Hris/Types/TimeOffRequest.cs index fa6c48f3..d9651fa7 100644 --- a/src/Merge.Client/Hris/Types/TimeOffRequest.cs +++ b/src/Merge.Client/Hris/Types/TimeOffRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Hris; +using OneOf; namespace Merge.Client.Hris; @@ -20,7 +20,7 @@ public class TimeOffRequest /// /// The status of this time off request. - /// + /// /// - `REQUESTED` - REQUESTED /// - `APPROVED` - APPROVED /// - `DECLINED` - DECLINED @@ -38,7 +38,7 @@ public class TimeOffRequest /// /// The measurement that the third-party integration uses to count time requested. - /// + /// /// - `HOURS` - HOURS /// - `DAYS` - DAYS /// @@ -53,7 +53,7 @@ public class TimeOffRequest /// /// The type of time off request. - /// + /// /// - `VACATION` - VACATION /// - `SICK` - SICK /// - `PERSONAL` - PERSONAL diff --git a/src/Merge.Client/Hris/Types/TimesheetEntry.cs b/src/Merge.Client/Hris/Types/TimesheetEntry.cs index 70f36ebb..616ad014 100644 --- a/src/Merge.Client/Hris/Types/TimesheetEntry.cs +++ b/src/Merge.Client/Hris/Types/TimesheetEntry.cs @@ -13,6 +13,15 @@ public class TimesheetEntry [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The employee the timesheet entry is for. /// @@ -37,12 +46,15 @@ public class TimesheetEntry [JsonPropertyName("end_time")] public DateTime? EndTime { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - /// - /// This is the datetime that this object was last updated by Merge + /// Indicates whether or not this object has been deleted in the third party platform. /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } + [JsonPropertyName("remote_was_deleted")] + public bool? RemoteWasDeleted { get; init; } + + [JsonPropertyName("field_mappings")] + public Dictionary? FieldMappings { get; init; } + + [JsonPropertyName("remote_data")] + public List?>? RemoteData { get; init; } } diff --git a/src/Merge.Client/Hris/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Hris/WebhookReceivers/WebhookReceiversClient.cs index 2b996f8c..0da43e52 100644 --- a/src/Merge.Client/Hris/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Hris/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Hris; + namespace Merge.Client.Hris; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/hris/v1/webhook-receivers" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/hris/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Hris/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Hris/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..710d9dfa --- /dev/null +++ b/src/Merge.Client/Hris/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Hris; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +} diff --git a/src/Merge.Client/Merge.Client.csproj b/src/Merge.Client/Merge.Client.csproj index 5a57834e..4e30294b 100644 --- a/src/Merge.Client/Merge.Client.csproj +++ b/src/Merge.Client/Merge.Client.csproj @@ -4,7 +4,7 @@ net7.0 enable false - 0.0.1 + 0.0.3 README.md LICENSE https://github.com/merge/merge-csharp-client @@ -12,6 +12,7 @@ + \ No newline at end of file diff --git a/src/Merge.Client/Merge.cs b/src/Merge.Client/Merge.cs new file mode 100644 index 00000000..c6f8d851 --- /dev/null +++ b/src/Merge.Client/Merge.cs @@ -0,0 +1,61 @@ +using Merge.Client; +using Merge.Client.Accounting; +using Merge.Client.Ats; +using Merge.Client.Crm; +using Merge.Client.Filestorage; +using Merge.Client.Hris; +using Merge.Client.Ticketing; + +namespace Merge.Client; + +public partial class Merge +{ + private RawClient _client; + + public Merge( + string apiKey = null, + string? accountToken = null, + ClientOptions clientOptions = null + ) + { + _client = new RawClient( + new Dictionary() + { + { "Authorization", $"Bearer {apiKey}" }, + { "X-Account-Token", accountToken }, + { "X-Fern-Language", "C#" }, + { "X-Fern-SDK-Name", "Merge.Client" }, + { "X-Fern-SDK-Version", "0.0.3" }, + }, + clientOptions ?? new ClientOptions() + ); + Ats = new AtsClient(_client); + Filestorage = new FilestorageClient(_client); + Crm = new CrmClient(_client); + Ticketing = new TicketingClient(_client); + Hris = new HrisClient(_client); + Accounting = new AccountingClient(_client); + } + + public AtsClient Ats { get; } + + public FilestorageClient Filestorage { get; } + + public CrmClient Crm { get; } + + public TicketingClient Ticketing { get; } + + public HrisClient Hris { get; } + + public AccountingClient Accounting { get; } + + private string GetFromEnvironmentOrThrow(string env, string message) + { + var value = Environment.GetEnvironmentVariable(env); + if (value == null) + { + throw new Exception(message); + } + return value; + } +} diff --git a/src/Merge.Client/Ticketing/AccountDetails/AccountDetailsClient.cs b/src/Merge.Client/Ticketing/AccountDetails/AccountDetailsClient.cs index dfbbb84d..f75a7f57 100644 --- a/src/Merge.Client/Ticketing/AccountDetails/AccountDetailsClient.cs +++ b/src/Merge.Client/Ticketing/AccountDetails/AccountDetailsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AccountDetailsClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountDetailsClient(RawClient client) + { + _client = client; + } + + /// + /// Get details for a linked account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/account-details" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/AccountToken/AccountTokenClient.cs b/src/Merge.Client/Ticketing/AccountToken/AccountTokenClient.cs index 5825f871..8af02abc 100644 --- a/src/Merge.Client/Ticketing/AccountToken/AccountTokenClient.cs +++ b/src/Merge.Client/Ticketing/AccountToken/AccountTokenClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AccountTokenClient { - public async void Retrieve(){ + private RawClient _client; + + public AccountTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Returns the account token for the end user with the provided public token. + /// + public async Task RetrieveAsync(string publicToken) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/account-token/{publicToken}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Accounts/AccountsClient.cs b/src/Merge.Client/Ticketing/Accounts/AccountsClient.cs index 8b0addde..75a5f9fd 100644 --- a/src/Merge.Client/Ticketing/Accounts/AccountsClient.cs +++ b/src/Merge.Client/Ticketing/Accounts/AccountsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AccountsClient { - public async void List(){ + private RawClient _client; + + public AccountsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Account` objects. + /// + public async Task ListAsync(AccountsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns an `Account` object with the given `id`. + /// + public async Task RetrieveAsync(string id, AccountsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/accounts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Accounts/requests/AccountsListRequest.cs b/src/Merge.Client/Ticketing/Accounts/requests/AccountsListRequest.cs new file mode 100644 index 00000000..2b4ff22f --- /dev/null +++ b/src/Merge.Client/Ticketing/Accounts/requests/AccountsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ticketing; + +public class AccountsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Accounts/requests/AccountsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Accounts/requests/AccountsRetrieveRequest.cs new file mode 100644 index 00000000..4a7a239d --- /dev/null +++ b/src/Merge.Client/Ticketing/Accounts/requests/AccountsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class AccountsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/AsyncPassthrough/AsyncPassthroughClient.cs b/src/Merge.Client/Ticketing/AsyncPassthrough/AsyncPassthroughClient.cs index 6b49ff7a..5b14206f 100644 --- a/src/Merge.Client/Ticketing/AsyncPassthrough/AsyncPassthroughClient.cs +++ b/src/Merge.Client/Ticketing/AsyncPassthrough/AsyncPassthroughClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AsyncPassthroughClient { - public async void Create(){ + private RawClient _client; + + public AsyncPassthroughClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Asynchronously pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/async-passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Retrieves data from earlier async-passthrough POST request + /// + public async Task RetrieveAsync(string asyncPassthroughReceiptId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/async-passthrough/{asyncPassthroughReceiptId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Attachments/AttachmentsClient.cs b/src/Merge.Client/Ticketing/Attachments/AttachmentsClient.cs index ef8383a5..2bf41499 100644 --- a/src/Merge.Client/Ticketing/Attachments/AttachmentsClient.cs +++ b/src/Merge.Client/Ticketing/Attachments/AttachmentsClient.cs @@ -1,15 +1,187 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AttachmentsClient { - public async void List(){ + private RawClient _client; + + public AttachmentsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Attachment` objects. + /// + public async Task ListAsync(AttachmentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteCreatedAfter != null) + { + _query["remote_created_after"] = request.RemoteCreatedAfter; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TicketId != null) + { + _query["ticket_id"] = request.TicketId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Create(){ + + /// + /// Creates an `Attachment` object with the given values. + /// + public async Task CreateAsync( + TicketingAttachmentEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/attachments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns an `Attachment` object with the given `id`. + /// + public async Task RetrieveAsync(string id, AttachmentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/attachments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void DownloadRetrieve(){ + + /// + /// Returns an `Attachment` object with the given `id`. + /// + public async void DownloadRetrieveAsync(string id, AttachmentsDownloadRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.MimeType != null) + { + _query["mime_type"] = request.MimeType; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/attachments/{id}/download", + Query = _query + } + ); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `TicketingAttachment` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/attachments/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsDownloadRetrieveRequest.cs b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsDownloadRetrieveRequest.cs new file mode 100644 index 00000000..aae8df8e --- /dev/null +++ b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsDownloadRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class AttachmentsDownloadRetrieveRequest +{ + /// + /// If provided, specifies the export format of the file to be downloaded. For information on supported export formats, please refer to our export format help center article. + /// + public string? MimeType { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsListRequest.cs b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsListRequest.cs new file mode 100644 index 00000000..1f596019 --- /dev/null +++ b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsListRequest.cs @@ -0,0 +1,64 @@ +namespace Merge.Client.Ticketing; + +public class AttachmentsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return attachments created in the third party platform after this datetime. + /// + public DateTime? RemoteCreatedAfter { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return comments for this ticket. + /// + public string? TicketId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsRetrieveRequest.cs new file mode 100644 index 00000000..ba666767 --- /dev/null +++ b/src/Merge.Client/Ticketing/Attachments/requests/AttachmentsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ticketing; + +public class AttachmentsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Attachments/requests/TicketingAttachmentEndpointRequest.cs b/src/Merge.Client/Ticketing/Attachments/requests/TicketingAttachmentEndpointRequest.cs new file mode 100644 index 00000000..6c3f1420 --- /dev/null +++ b/src/Merge.Client/Ticketing/Attachments/requests/TicketingAttachmentEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketingAttachmentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public AttachmentRequest Model { get; init; } +} diff --git a/src/Merge.Client/Ticketing/AuditTrail/AuditTrailClient.cs b/src/Merge.Client/Ticketing/AuditTrail/AuditTrailClient.cs index c0ef96a5..51577cac 100644 --- a/src/Merge.Client/Ticketing/AuditTrail/AuditTrailClient.cs +++ b/src/Merge.Client/Ticketing/AuditTrail/AuditTrailClient.cs @@ -1,7 +1,61 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AuditTrailClient { - public async void List(){ + private RawClient _client; + + public AuditTrailClient(RawClient client) + { + _client = client; + } + + /// + /// Gets a list of audit trail events. + /// + public async Task ListAsync(AuditTrailListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EventType != null) + { + _query["event_type"] = request.EventType; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.UserEmail != null) + { + _query["user_email"] = request.UserEmail; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/audit-trail", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/AuditTrail/requests/AuditTrailListRequest.cs b/src/Merge.Client/Ticketing/AuditTrail/requests/AuditTrailListRequest.cs new file mode 100644 index 00000000..e65ed142 --- /dev/null +++ b/src/Merge.Client/Ticketing/AuditTrail/requests/AuditTrailListRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Ticketing; + +public class AuditTrailListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include audit trail events that occurred before this time + /// + public string? EndDate { get; init; } + + /// + /// If included, will only include events with the given event type. Possible values include: `CREATED_REMOTE_PRODUCTION_API_KEY`, `DELETED_REMOTE_PRODUCTION_API_KEY`, `CREATED_TEST_API_KEY`, `DELETED_TEST_API_KEY`, `REGENERATED_PRODUCTION_API_KEY`, `INVITED_USER`, `TWO_FACTOR_AUTH_ENABLED`, `TWO_FACTOR_AUTH_DISABLED`, `DELETED_LINKED_ACCOUNT`, `CREATED_DESTINATION`, `DELETED_DESTINATION`, `CHANGED_DESTINATION`, `CHANGED_SCOPES`, `CHANGED_PERSONAL_INFORMATION`, `CHANGED_ORGANIZATION_SETTINGS`, `ENABLED_INTEGRATION`, `DISABLED_INTEGRATION`, `ENABLED_CATEGORY`, `DISABLED_CATEGORY`, `CHANGED_PASSWORD`, `RESET_PASSWORD`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `ENABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_ORGANIZATION`, `DISABLED_REDACT_UNMAPPED_DATA_FOR_LINKED_ACCOUNT`, `CREATED_INTEGRATION_WIDE_FIELD_MAPPING`, `CREATED_LINKED_ACCOUNT_FIELD_MAPPING`, `CHANGED_INTEGRATION_WIDE_FIELD_MAPPING`, `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING`, `DELETED_INTEGRATION_WIDE_FIELD_MAPPING`, `DELETED_LINKED_ACCOUNT_FIELD_MAPPING`, `FORCED_LINKED_ACCOUNT_RESYNC`, `MUTED_ISSUE`, `GENERATED_MAGIC_LINK` + /// + public string? EventType { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include audit trail events that occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// If provided, this will return events associated with the specified user email. Please note that the email address reflects the user's email at the time of the event, and may not be their current email. + /// + public string? UserEmail { get; init; } +} diff --git a/src/Merge.Client/Ticketing/AvailableActions/AvailableActionsClient.cs b/src/Merge.Client/Ticketing/AvailableActions/AvailableActionsClient.cs index 38acf952..37e46d5c 100644 --- a/src/Merge.Client/Ticketing/AvailableActions/AvailableActionsClient.cs +++ b/src/Merge.Client/Ticketing/AvailableActions/AvailableActionsClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class AvailableActionsClient { - public async void Retrieve(){ + private RawClient _client; + + public AvailableActionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of models and actions available for an account. + /// + public async Task RetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/available-actions" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Collections/CollectionsClient.cs b/src/Merge.Client/Ticketing/Collections/CollectionsClient.cs index 302a5051..a5f782d1 100644 --- a/src/Merge.Client/Ticketing/Collections/CollectionsClient.cs +++ b/src/Merge.Client/Ticketing/Collections/CollectionsClient.cs @@ -1,11 +1,176 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class CollectionsClient { - public async void List(){ + private RawClient _client; + + public CollectionsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Collection` objects. + /// + public async Task ListAsync(CollectionsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CollectionType != null) + { + _query["collection_type"] = request.CollectionType; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.ParentCollectionId != null) + { + _query["parent_collection_id"] = request.ParentCollectionId; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/collections", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Collection` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CollectionsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/collections/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void UsersList(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task UsersListAsync( + string parentId, + CollectionsUsersListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/collections/{parentId}/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Collections/Types/CollectionsListRequestCollectionType.cs b/src/Merge.Client/Ticketing/Collections/Types/CollectionsListRequestCollectionType.cs deleted file mode 100644 index 089e4c22..00000000 --- a/src/Merge.Client/Ticketing/Collections/Types/CollectionsListRequestCollectionType.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Runtime.Serialization; - -namespace Merge.Client.Ticketing; - -public enum CollectionsListRequestCollectionType -{ - [EnumMember(Value = "LIST")] - List, - - [EnumMember(Value = "PROJECT")] - Project -} diff --git a/src/Merge.Client/Ticketing/Collections/requests/CollectionsListRequest.cs b/src/Merge.Client/Ticketing/Collections/requests/CollectionsListRequest.cs new file mode 100644 index 00000000..42e46e1b --- /dev/null +++ b/src/Merge.Client/Ticketing/Collections/requests/CollectionsListRequest.cs @@ -0,0 +1,74 @@ +namespace Merge.Client.Ticketing; + +public class CollectionsListRequest +{ + /// + /// If provided, will only return collections of the given type. + /// + public string? CollectionType { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return collections whose parent collection matches the given id. + /// + public string? ParentCollectionId { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Collections/requests/CollectionsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Collections/requests/CollectionsRetrieveRequest.cs new file mode 100644 index 00000000..e706c385 --- /dev/null +++ b/src/Merge.Client/Ticketing/Collections/requests/CollectionsRetrieveRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Ticketing; + +public class CollectionsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public string? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public string? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Collections/requests/CollectionsUsersListRequest.cs b/src/Merge.Client/Ticketing/Collections/requests/CollectionsUsersListRequest.cs new file mode 100644 index 00000000..247955c3 --- /dev/null +++ b/src/Merge.Client/Ticketing/Collections/requests/CollectionsUsersListRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class CollectionsUsersListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CollectionsUsersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Comments/CommentsClient.cs b/src/Merge.Client/Ticketing/Comments/CommentsClient.cs index 934f731e..fc5c70bc 100644 --- a/src/Merge.Client/Ticketing/Comments/CommentsClient.cs +++ b/src/Merge.Client/Ticketing/Comments/CommentsClient.cs @@ -1,13 +1,165 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class CommentsClient { - public async void List(){ + private RawClient _client; + + public CommentsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Comment` objects. + /// + public async Task ListAsync(CommentsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteCreatedAfter != null) + { + _query["remote_created_after"] = request.RemoteCreatedAfter; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.TicketId != null) + { + _query["ticket_id"] = request.TicketId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/comments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `Comment` object with the given values. + /// + public async Task CreateAsync(CommentEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/comments", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns a `Comment` object with the given `id`. + /// + public async Task RetrieveAsync(string id, CommentsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/comments/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns metadata for `Comment` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/comments/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Comments/requests/CommentEndpointRequest.cs b/src/Merge.Client/Ticketing/Comments/requests/CommentEndpointRequest.cs new file mode 100644 index 00000000..8197bc8c --- /dev/null +++ b/src/Merge.Client/Ticketing/Comments/requests/CommentEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class CommentEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public CommentRequest Model { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Comments/requests/CommentsListRequest.cs b/src/Merge.Client/Ticketing/Comments/requests/CommentsListRequest.cs new file mode 100644 index 00000000..ffd7ebc1 --- /dev/null +++ b/src/Merge.Client/Ticketing/Comments/requests/CommentsListRequest.cs @@ -0,0 +1,66 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class CommentsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CommentsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return Comments created in the third party platform after this datetime. + /// + public DateTime? RemoteCreatedAfter { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return comments for this ticket. + /// + public string? TicketId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Comments/requests/CommentsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Comments/requests/CommentsRetrieveRequest.cs new file mode 100644 index 00000000..181d7979 --- /dev/null +++ b/src/Merge.Client/Ticketing/Comments/requests/CommentsRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class CommentsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public CommentsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Contacts/ContactsClient.cs b/src/Merge.Client/Ticketing/Contacts/ContactsClient.cs index a7e44bfd..1466a17c 100644 --- a/src/Merge.Client/Ticketing/Contacts/ContactsClient.cs +++ b/src/Merge.Client/Ticketing/Contacts/ContactsClient.cs @@ -1,9 +1,107 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class ContactsClient { - public async void List(){ + private RawClient _client; + + public ContactsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Contact` objects. + /// + public async Task ListAsync(ContactsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/contacts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Contact` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ContactsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/contacts/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Contacts/requests/ContactsListRequest.cs b/src/Merge.Client/Ticketing/Contacts/requests/ContactsListRequest.cs new file mode 100644 index 00000000..3cc2dadc --- /dev/null +++ b/src/Merge.Client/Ticketing/Contacts/requests/ContactsListRequest.cs @@ -0,0 +1,54 @@ +namespace Merge.Client.Ticketing; + +public class ContactsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Contacts/requests/ContactsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Contacts/requests/ContactsRetrieveRequest.cs new file mode 100644 index 00000000..c7990768 --- /dev/null +++ b/src/Merge.Client/Ticketing/Contacts/requests/ContactsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ticketing; + +public class ContactsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public string? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/DeleteAccount/DeleteAccountClient.cs b/src/Merge.Client/Ticketing/DeleteAccount/DeleteAccountClient.cs index cf2629c7..e0eac6a8 100644 --- a/src/Merge.Client/Ticketing/DeleteAccount/DeleteAccountClient.cs +++ b/src/Merge.Client/Ticketing/DeleteAccount/DeleteAccountClient.cs @@ -1,7 +1,27 @@ +using Merge.Client; + namespace Merge.Client.Ticketing; public class DeleteAccountClient { - public async void Delete(){ + private RawClient _client; + + public DeleteAccountClient(RawClient client) + { + _client = client; + } + + /// + /// Delete a linked account. + /// + public async void DeleteAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/delete-account" + } + ); } } diff --git a/src/Merge.Client/Ticketing/FieldMapping/FieldMappingClient.cs b/src/Merge.Client/Ticketing/FieldMapping/FieldMappingClient.cs new file mode 100644 index 00000000..2f8999b8 --- /dev/null +++ b/src/Merge.Client/Ticketing/FieldMapping/FieldMappingClient.cs @@ -0,0 +1,154 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class FieldMappingClient +{ + private RawClient _client; + + public FieldMappingClient(RawClient client) + { + _client = client; + } + + /// + /// Get all Field Mappings for this Linked Account. Field Mappings are mappings between third-party Remote Fields and user defined Merge fields. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task FieldMappingsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/field-mappings" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create new Field Mappings that will be available after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsCreateAsync( + CreateFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/field-mappings", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Deletes Field Mappings for a Linked Account. All data related to this Field Mapping will be deleted and these changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsDestroyAsync(string fieldMappingId) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Delete, + Path = $"/ticketing/v1/field-mappings/{fieldMappingId}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Create or update existing Field Mappings for a Linked Account. Changes will be reflected after the next scheduled sync. This will cause the next sync for this Linked Account to sync **ALL** data from start. + /// + public async Task FieldMappingsPartialUpdateAsync( + string fieldMappingId, + PatchedEditFieldMappingRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/ticketing/v1/field-mappings/{fieldMappingId}", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all remote fields for a Linked Account. Remote fields are third-party fields that are accessible after initial sync if remote_data is enabled. You can use remote fields to override existing Merge fields or map a new Merge field. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/overview/). + /// + public async Task RemoteFieldsRetrieveAsync( + RemoteFieldsRetrieveRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModels != null) + { + _query["common_models"] = request.CommonModels; + } + if (request.IncludeExampleValues != null) + { + _query["include_example_values"] = request.IncludeExampleValues; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/remote-fields", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all organization-wide Target Fields, this will not include any Linked Account specific Target Fields. Organization-wide Target Fields are additional fields appended to the Merge Common Model for all Linked Accounts in a category. [Learn more](https://docs.merge.dev/supplemental-data/field-mappings/target-fields/). + /// + public async Task TargetFieldsRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/target-fields" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Ticketing/FieldMapping/requests/CreateFieldMappingRequest.cs b/src/Merge.Client/Ticketing/FieldMapping/requests/CreateFieldMappingRequest.cs new file mode 100644 index 00000000..a5b02057 --- /dev/null +++ b/src/Merge.Client/Ticketing/FieldMapping/requests/CreateFieldMappingRequest.cs @@ -0,0 +1,34 @@ +namespace Merge.Client.Ticketing; + +public class CreateFieldMappingRequest +{ + /// + /// The name of the target field you want this remote field to map to. + /// + public string TargetFieldName { get; init; } + + /// + /// The description of the target field you want this remote field to map to. + /// + public string TargetFieldDescription { get; init; } + + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string RemoteUrlPath { get; init; } + + /// + /// The name of the Common Model that the remote field corresponds to in a given category. + /// + public string CommonModelName { get; init; } +} diff --git a/src/Merge.Client/Ticketing/FieldMapping/requests/PatchedEditFieldMappingRequest.cs b/src/Merge.Client/Ticketing/FieldMapping/requests/PatchedEditFieldMappingRequest.cs new file mode 100644 index 00000000..9d2522b8 --- /dev/null +++ b/src/Merge.Client/Ticketing/FieldMapping/requests/PatchedEditFieldMappingRequest.cs @@ -0,0 +1,19 @@ +namespace Merge.Client.Ticketing; + +public class PatchedEditFieldMappingRequest +{ + /// + /// The field traversal path of the remote field listed when you hit the GET /remote-fields endpoint. + /// + public List? RemoteFieldTraversalPath { get; init; } + + /// + /// The method of the remote endpoint where the remote field is coming from. + /// + public string? RemoteMethod { get; init; } + + /// + /// The path of the remote endpoint where the remote field is coming from. + /// + public string? RemoteUrlPath { get; init; } +} diff --git a/src/Merge.Client/Ticketing/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs b/src/Merge.Client/Ticketing/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs new file mode 100644 index 00000000..6904b27a --- /dev/null +++ b/src/Merge.Client/Ticketing/FieldMapping/requests/RemoteFieldsRetrieveRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ticketing; + +public class RemoteFieldsRetrieveRequest +{ + /// + /// A comma seperated list of Common Model names. If included, will only return Remote Fields for those Common Models. + /// + public string? CommonModels { get; init; } + + /// + /// If true, will include example values, where available, for remote fields in the 3rd party platform. These examples come from active data from your customers. + /// + public string? IncludeExampleValues { get; init; } +} diff --git a/src/Merge.Client/Ticketing/ForceResync/ForceResyncClient.cs b/src/Merge.Client/Ticketing/ForceResync/ForceResyncClient.cs index eb157593..9b957af1 100644 --- a/src/Merge.Client/Ticketing/ForceResync/ForceResyncClient.cs +++ b/src/Merge.Client/Ticketing/ForceResync/ForceResyncClient.cs @@ -1,7 +1,35 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class ForceResyncClient { - public async void SyncStatusResyncCreate(){ + private RawClient _client; + + public ForceResyncClient(RawClient client) + { + _client = client; + } + + /// + /// Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available programmatically via API for monthly, quarterly, and highest sync frequency customers on the Launch, Professional, or Enterprise plans. Doing so will consume a sync credit for the relevant linked account. + /// + public async Task> SyncStatusResyncCreateAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/sync-status/resync" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/GenerateKey/GenerateKeyClient.cs b/src/Merge.Client/Ticketing/GenerateKey/GenerateKeyClient.cs index 4b442be4..647a6cca 100644 --- a/src/Merge.Client/Ticketing/GenerateKey/GenerateKeyClient.cs +++ b/src/Merge.Client/Ticketing/GenerateKey/GenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class GenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public GenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Create a remote key. + /// + public async Task CreateAsync(GenerateRemoteKeyRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/generate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/GenerateKey/requests/GenerateRemoteKeyRequest.cs b/src/Merge.Client/Ticketing/GenerateKey/requests/GenerateRemoteKeyRequest.cs new file mode 100644 index 00000000..7ca2303c --- /dev/null +++ b/src/Merge.Client/Ticketing/GenerateKey/requests/GenerateRemoteKeyRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class GenerateRemoteKeyRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Issues/IssuesClient.cs b/src/Merge.Client/Ticketing/Issues/IssuesClient.cs index 9fe72bd7..8b044a1e 100644 --- a/src/Merge.Client/Ticketing/Issues/IssuesClient.cs +++ b/src/Merge.Client/Ticketing/Issues/IssuesClient.cs @@ -1,9 +1,109 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class IssuesClient { - public async void List(){ + private RawClient _client; + + public IssuesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Gets issues. + /// + public async Task ListAsync(IssuesListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountToken != null) + { + _query["account_token"] = request.AccountToken; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndDate != null) + { + _query["end_date"] = request.EndDate; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.FirstIncidentTimeAfter != null) + { + _query["first_incident_time_after"] = request.FirstIncidentTimeAfter; + } + if (request.FirstIncidentTimeBefore != null) + { + _query["first_incident_time_before"] = request.FirstIncidentTimeBefore; + } + if (request.IncludeMuted != null) + { + _query["include_muted"] = request.IncludeMuted; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.LastIncidentTimeAfter != null) + { + _query["last_incident_time_after"] = request.LastIncidentTimeAfter; + } + if (request.LastIncidentTimeBefore != null) + { + _query["last_incident_time_before"] = request.LastIncidentTimeBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.StartDate != null) + { + _query["start_date"] = request.StartDate; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/issues", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get a specific issue. + /// + public async Task RetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/issues/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Issues/requests/IssuesListRequest.cs b/src/Merge.Client/Ticketing/Issues/requests/IssuesListRequest.cs new file mode 100644 index 00000000..2235cc36 --- /dev/null +++ b/src/Merge.Client/Ticketing/Issues/requests/IssuesListRequest.cs @@ -0,0 +1,65 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class IssuesListRequest +{ + public string? AccountToken { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred before this time + /// + public string? EndDate { get; init; } + + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return issues whose first incident time was after this datetime. + /// + public DateTime? FirstIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose first incident time was before this datetime. + /// + public DateTime? FirstIncidentTimeBefore { get; init; } + + /// + /// If true, will include muted issues + /// + public string? IncludeMuted { get; init; } + + public string? IntegrationName { get; init; } + + /// + /// If provided, will only return issues whose last incident time was after this datetime. + /// + public DateTime? LastIncidentTimeAfter { get; init; } + + /// + /// If provided, will only return issues whose last incident time was before this datetime. + /// + public DateTime? LastIncidentTimeBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If included, will only include issues whose most recent action occurred after this time + /// + public string? StartDate { get; init; } + + /// + /// Status of the issue. Options: ('ONGOING', 'RESOLVED') + /// + /// - `ONGOING` - ONGOING + /// - `RESOLVED` - RESOLVED + /// + public IssuesListRequestStatus? Status { get; init; } +} diff --git a/src/Merge.Client/Ticketing/LinkToken/LinkTokenClient.cs b/src/Merge.Client/Ticketing/LinkToken/LinkTokenClient.cs index 9ff33195..f699370c 100644 --- a/src/Merge.Client/Ticketing/LinkToken/LinkTokenClient.cs +++ b/src/Merge.Client/Ticketing/LinkToken/LinkTokenClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class LinkTokenClient { - public async void Create(){ + private RawClient _client; + + public LinkTokenClient(RawClient client) + { + _client = client; + } + + /// + /// Creates a link token to be used when linking a new end user. + /// + public async Task CreateAsync(EndUserDetailsRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/link-token", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/LinkToken/requests/EndUserDetailsRequest.cs b/src/Merge.Client/Ticketing/LinkToken/requests/EndUserDetailsRequest.cs new file mode 100644 index 00000000..50d8b49a --- /dev/null +++ b/src/Merge.Client/Ticketing/LinkToken/requests/EndUserDetailsRequest.cs @@ -0,0 +1,59 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class EndUserDetailsRequest +{ + /// + /// Your end user's email address. This is purely for identification purposes - setting this value will not cause any emails to be sent. + /// + public string EndUserEmailAddress { get; init; } + + /// + /// Your end user's organization. + /// + public string EndUserOrganizationName { get; init; } + + /// + /// This unique identifier typically represents the ID for your end user in your product's database. This value must be distinct from other Linked Accounts' unique identifiers. + /// + public string EndUserOriginId { get; init; } + + /// + /// The integration categories to show in Merge Link. + /// + public List Categories { get; init; } + + /// + /// The slug of a specific pre-selected integration for this linking flow token. For examples of slugs, see https://docs.merge.dev/guides/merge-link/single-integration/. + /// + public string? Integration { get; init; } + + /// + /// An integer number of minutes between [30, 720 or 10080 if for a Magic Link URL] for how long this token is valid. Defaults to 30. + /// + public int? LinkExpiryMins { get; init; } + + /// + /// Whether to generate a Magic Link URL. Defaults to false. For more information on Magic Link, see https://merge.dev/blog/integrations-fast-say-hello-to-magic-link. + /// + public bool? ShouldCreateMagicLinkUrl { get; init; } + + /// + /// An array of objects to specify the models and fields that will be disabled for a given Linked Account. Each object uses model_id, enabled_actions, and disabled_fields to specify the model, method, and fields that are scoped for a given Linked Account. + /// + public List? CommonModels { get; init; } + + /// + /// When creating a Link Token, you can set permissions for Common Models that will apply to the account that is going to be linked. Any model or field not specified in link token payload will default to existing settings. + /// + public Dictionary< + string, + List? + >? CategoryCommonModelScopes { get; init; } + + /// + /// The language code for the language to localize Merge Link to. + /// + public string? Language { get; init; } +} diff --git a/src/Merge.Client/Ticketing/LinkedAccounts/LinkedAccountsClient.cs b/src/Merge.Client/Ticketing/LinkedAccounts/LinkedAccountsClient.cs index e9006ba1..b058fbd5 100644 --- a/src/Merge.Client/Ticketing/LinkedAccounts/LinkedAccountsClient.cs +++ b/src/Merge.Client/Ticketing/LinkedAccounts/LinkedAccountsClient.cs @@ -1,7 +1,91 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class LinkedAccountsClient { - public async void List(){ + private RawClient _client; + + public LinkedAccountsClient(RawClient client) + { + _client = client; + } + + /// + /// List linked accounts for your organization. + /// + public async Task ListAsync( + LinkedAccountsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Category != null) + { + _query["category"] = request.Category; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EndUserEmailAddress != null) + { + _query["end_user_email_address"] = request.EndUserEmailAddress; + } + if (request.EndUserOrganizationName != null) + { + _query["end_user_organization_name"] = request.EndUserOrganizationName; + } + if (request.EndUserOriginId != null) + { + _query["end_user_origin_id"] = request.EndUserOriginId; + } + if (request.EndUserOriginIds != null) + { + _query["end_user_origin_ids"] = request.EndUserOriginIds; + } + if (request.Id != null) + { + _query["id"] = request.Id; + } + if (request.Ids != null) + { + _query["ids"] = request.Ids; + } + if (request.IncludeDuplicates != null) + { + _query["include_duplicates"] = request.IncludeDuplicates; + } + if (request.IntegrationName != null) + { + _query["integration_name"] = request.IntegrationName; + } + if (request.IsTestAccount != null) + { + _query["is_test_account"] = request.IsTestAccount; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/linked-accounts", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/LinkedAccounts/requests/LinkedAccountsListRequest.cs b/src/Merge.Client/Ticketing/LinkedAccounts/requests/LinkedAccountsListRequest.cs new file mode 100644 index 00000000..a23f1aa3 --- /dev/null +++ b/src/Merge.Client/Ticketing/LinkedAccounts/requests/LinkedAccountsListRequest.cs @@ -0,0 +1,76 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class LinkedAccountsListRequest +{ + /// + /// Options: ('hris', 'ats', 'accounting', 'ticketing', 'crm', 'mktg', 'filestorage') + /// + /// - `hris` - hris + /// - `ats` - ats + /// - `accounting` - accounting + /// - `ticketing` - ticketing + /// - `crm` - crm + /// - `mktg` - mktg + /// - `filestorage` - filestorage + /// + public LinkedAccountsListRequestCategory? Category { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given email address. + /// + public string? EndUserEmailAddress { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given organization name. + /// + public string? EndUserOrganizationName { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given origin ID. + /// + public string? EndUserOriginId { get; init; } + + /// + /// Comma-separated list of EndUser origin IDs, making it possible to specify multiple EndUsers at once. + /// + public string? EndUserOriginIds { get; init; } + + public string? Id { get; init; } + + /// + /// Comma-separated list of LinkedAccount IDs, making it possible to specify multiple LinkedAccounts at once. + /// + public string? Ids { get; init; } + + /// + /// If `true`, will include complete production duplicates of the account specified by the `id` query parameter in the response. `id` must be for a complete production linked account. + /// + public bool? IncludeDuplicates { get; init; } + + /// + /// If provided, will only return linked accounts associated with the given integration name. + /// + public string? IntegrationName { get; init; } + + /// + /// If included, will only include test linked accounts. If not included, will only include non-test linked accounts. + /// + public string? IsTestAccount { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// Filter by status. Options: `COMPLETE`, `INCOMPLETE`, `RELINK_NEEDED` + /// + public string? Status { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Passthrough/PassthroughClient.cs b/src/Merge.Client/Ticketing/Passthrough/PassthroughClient.cs index cc9b5f91..95f3e1dc 100644 --- a/src/Merge.Client/Ticketing/Passthrough/PassthroughClient.cs +++ b/src/Merge.Client/Ticketing/Passthrough/PassthroughClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class PassthroughClient { - public async void Create(){ + private RawClient _client; + + public PassthroughClient(RawClient client) + { + _client = client; + } + + /// + /// Pull data from an endpoint not currently supported by Merge. + /// + public async Task CreateAsync(DataPassthroughRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/passthrough", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Projects/ProjectsClient.cs b/src/Merge.Client/Ticketing/Projects/ProjectsClient.cs index db5fd5fd..b8da5c14 100644 --- a/src/Merge.Client/Ticketing/Projects/ProjectsClient.cs +++ b/src/Merge.Client/Ticketing/Projects/ProjectsClient.cs @@ -1,11 +1,144 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class ProjectsClient { - public async void List(){ + private RawClient _client; + + public ProjectsClient(RawClient client) + { + _client = client; + } + + /// + /// Returns a list of `Project` objects. + /// + public async Task ListAsync(ProjectsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/projects", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Returns a `Project` object with the given `id`. + /// + public async Task RetrieveAsync(string id, ProjectsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/projects/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void UsersList(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task UsersListAsync( + string parentId, + ProjectsUsersListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/projects/{parentId}/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Projects/requests/ProjectsListRequest.cs b/src/Merge.Client/Ticketing/Projects/requests/ProjectsListRequest.cs new file mode 100644 index 00000000..99605745 --- /dev/null +++ b/src/Merge.Client/Ticketing/Projects/requests/ProjectsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ticketing; + +public class ProjectsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Projects/requests/ProjectsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Projects/requests/ProjectsRetrieveRequest.cs new file mode 100644 index 00000000..63e6871b --- /dev/null +++ b/src/Merge.Client/Ticketing/Projects/requests/ProjectsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class ProjectsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Projects/requests/ProjectsUsersListRequest.cs b/src/Merge.Client/Ticketing/Projects/requests/ProjectsUsersListRequest.cs new file mode 100644 index 00000000..1c85eff5 --- /dev/null +++ b/src/Merge.Client/Ticketing/Projects/requests/ProjectsUsersListRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class ProjectsUsersListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public ProjectsUsersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/RegenerateKey/RegenerateKeyClient.cs b/src/Merge.Client/Ticketing/RegenerateKey/RegenerateKeyClient.cs index 3ee787b9..2d5231e4 100644 --- a/src/Merge.Client/Ticketing/RegenerateKey/RegenerateKeyClient.cs +++ b/src/Merge.Client/Ticketing/RegenerateKey/RegenerateKeyClient.cs @@ -1,7 +1,36 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class RegenerateKeyClient { - public async void Create(){ + private RawClient _client; + + public RegenerateKeyClient(RawClient client) + { + _client = client; + } + + /// + /// Exchange remote keys. + /// + public async Task CreateAsync(RemoteKeyForRegenerationRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/regenerate-key", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs b/src/Merge.Client/Ticketing/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs new file mode 100644 index 00000000..800e067b --- /dev/null +++ b/src/Merge.Client/Ticketing/RegenerateKey/requests/RemoteKeyForRegenerationRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class RemoteKeyForRegenerationRequest +{ + /// + /// The name of the remote key + /// + public string Name { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Roles/RolesClient.cs b/src/Merge.Client/Ticketing/Roles/RolesClient.cs index 246e14d8..0b5cbaca 100644 --- a/src/Merge.Client/Ticketing/Roles/RolesClient.cs +++ b/src/Merge.Client/Ticketing/Roles/RolesClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class RolesClient { - public async void List(){ + private RawClient _client; + + public RolesClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Role` objects. + /// + public async Task ListAsync(RolesListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/roles", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Role` object with the given `id`. + /// + public async Task RetrieveAsync(string id, RolesRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/roles/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Roles/requests/RolesListRequest.cs b/src/Merge.Client/Ticketing/Roles/requests/RolesListRequest.cs new file mode 100644 index 00000000..26ad60a2 --- /dev/null +++ b/src/Merge.Client/Ticketing/Roles/requests/RolesListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ticketing; + +public class RolesListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Roles/requests/RolesRetrieveRequest.cs b/src/Merge.Client/Ticketing/Roles/requests/RolesRetrieveRequest.cs new file mode 100644 index 00000000..a2f146b1 --- /dev/null +++ b/src/Merge.Client/Ticketing/Roles/requests/RolesRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class RolesRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Scopes/ScopesClient.cs b/src/Merge.Client/Ticketing/Scopes/ScopesClient.cs new file mode 100644 index 00000000..8cfcb2fe --- /dev/null +++ b/src/Merge.Client/Ticketing/Scopes/ScopesClient.cs @@ -0,0 +1,78 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class ScopesClient +{ + private RawClient _client; + + public ScopesClient(RawClient client) + { + _client = client; + } + + /// + /// Get the default permissions for Merge Common Models and fields across all Linked Accounts of a given category. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task DefaultScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/default-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Get all available permissions for Merge Common Models and fields for a single Linked Account. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes). + /// + public async Task LinkedAccountScopesRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/linked-account-scopes" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Update permissions for any Common Model or field for a single Linked Account. Any Scopes not set in this POST request will inherit the default Scopes. [Learn more](https://help.merge.dev/en/articles/8828211-common-model-and-field-scopes) + /// + public async Task LinkedAccountScopesCreateAsync( + LinkedAccountCommonModelScopeDeserializerRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/linked-account-scopes", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } +} diff --git a/src/Merge.Client/Ticketing/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Ticketing/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..90814691 --- /dev/null +++ b/src/Merge.Client/Ticketing/Scopes/requests/LinkedAccountCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class LinkedAccountCommonModelScopeDeserializerRequest +{ + /// + /// The common models you want to update the scopes for + /// + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Ticketing/SelectiveSync/SelectiveSyncClient.cs b/src/Merge.Client/Ticketing/SelectiveSync/SelectiveSyncClient.cs index d1484b8b..b092d342 100644 --- a/src/Merge.Client/Ticketing/SelectiveSync/SelectiveSyncClient.cs +++ b/src/Merge.Client/Ticketing/SelectiveSync/SelectiveSyncClient.cs @@ -1,11 +1,98 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class SelectiveSyncClient { - public async void ConfigurationsList(){ + private RawClient _client; + + public SelectiveSyncClient(RawClient client) + { + _client = client; + } + + /// + /// Get a linked account's selective syncs. + /// + public async Task> ConfigurationsListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/selective-sync/configurations" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void ConfigurationsUpdate(){ + + /// + /// Replace a linked account's selective syncs. + /// + public async Task> ConfigurationsUpdateAsync( + LinkedAccountSelectiveSyncConfigurationListRequest request + ) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Put, + Path = "/ticketing/v1/selective-sync/configurations", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>( + responseBody + ); + } + throw new Exception(); } - public async void MetaList(){ + + /// + /// Get metadata for the conditions available to a linked account. + /// + public async Task MetaListAsync( + SelectiveSyncMetaListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.CommonModel != null) + { + _query["common_model"] = request.CommonModel; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/selective-sync/meta", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs b/src/Merge.Client/Ticketing/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs new file mode 100644 index 00000000..cd2e2979 --- /dev/null +++ b/src/Merge.Client/Ticketing/SelectiveSync/requests/LinkedAccountSelectiveSyncConfigurationListRequest.cs @@ -0,0 +1,11 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class LinkedAccountSelectiveSyncConfigurationListRequest +{ + /// + /// The selective syncs associated with a linked account. + /// + public List SyncConfigurations { get; init; } +} diff --git a/src/Merge.Client/Ticketing/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs b/src/Merge.Client/Ticketing/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs new file mode 100644 index 00000000..a567d8c2 --- /dev/null +++ b/src/Merge.Client/Ticketing/SelectiveSync/requests/SelectiveSyncMetaListRequest.cs @@ -0,0 +1,16 @@ +namespace Merge.Client.Ticketing; + +public class SelectiveSyncMetaListRequest +{ + public string? CommonModel { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/SyncStatus/SyncStatusClient.cs b/src/Merge.Client/Ticketing/SyncStatus/SyncStatusClient.cs index e886dc8d..14b71bc8 100644 --- a/src/Merge.Client/Ticketing/SyncStatus/SyncStatusClient.cs +++ b/src/Merge.Client/Ticketing/SyncStatus/SyncStatusClient.cs @@ -1,7 +1,45 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class SyncStatusClient { - public async void List(){ + private RawClient _client; + + public SyncStatusClient(RawClient client) + { + _client = client; + } + + /// + /// Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PARTIALLY_SYNCED`, `PAUSED`, `SYNCING`. Learn more about sync status in our [Help Center](https://help.merge.dev/en/articles/8184193-merge-sync-statuses). + /// + public async Task ListAsync(SyncStatusListRequest request) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/sync-status", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/SyncStatus/requests/SyncStatusListRequest.cs b/src/Merge.Client/Ticketing/SyncStatus/requests/SyncStatusListRequest.cs new file mode 100644 index 00000000..67d6381b --- /dev/null +++ b/src/Merge.Client/Ticketing/SyncStatus/requests/SyncStatusListRequest.cs @@ -0,0 +1,14 @@ +namespace Merge.Client.Ticketing; + +public class SyncStatusListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tags/TagsClient.cs b/src/Merge.Client/Ticketing/Tags/TagsClient.cs index 3d91f890..37d3de84 100644 --- a/src/Merge.Client/Ticketing/Tags/TagsClient.cs +++ b/src/Merge.Client/Ticketing/Tags/TagsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class TagsClient { - public async void List(){ + private RawClient _client; + + public TagsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Tag` objects. + /// + public async Task ListAsync(TagsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/tags", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Tag` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TagsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/tags/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Tags/requests/TagsListRequest.cs b/src/Merge.Client/Ticketing/Tags/requests/TagsListRequest.cs new file mode 100644 index 00000000..2a12f0e5 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tags/requests/TagsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ticketing; + +public class TagsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tags/requests/TagsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Tags/requests/TagsRetrieveRequest.cs new file mode 100644 index 00000000..14651aa9 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tags/requests/TagsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class TagsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Teams/TeamsClient.cs b/src/Merge.Client/Ticketing/Teams/TeamsClient.cs index 3b78cca4..7d9bc252 100644 --- a/src/Merge.Client/Ticketing/Teams/TeamsClient.cs +++ b/src/Merge.Client/Ticketing/Teams/TeamsClient.cs @@ -1,9 +1,99 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class TeamsClient { - public async void List(){ + private RawClient _client; + + public TeamsClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `Team` objects. + /// + public async Task ListAsync(TeamsListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/teams", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `Team` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TeamsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/teams/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Teams/requests/TeamsListRequest.cs b/src/Merge.Client/Ticketing/Teams/requests/TeamsListRequest.cs new file mode 100644 index 00000000..1dd16e0c --- /dev/null +++ b/src/Merge.Client/Ticketing/Teams/requests/TeamsListRequest.cs @@ -0,0 +1,49 @@ +namespace Merge.Client.Ticketing; + +public class TeamsListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Teams/requests/TeamsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Teams/requests/TeamsRetrieveRequest.cs new file mode 100644 index 00000000..c4491c1f --- /dev/null +++ b/src/Merge.Client/Ticketing/Teams/requests/TeamsRetrieveRequest.cs @@ -0,0 +1,9 @@ +namespace Merge.Client.Ticketing; + +public class TeamsRetrieveRequest +{ + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/TicketingClient.cs b/src/Merge.Client/Ticketing/TicketingClient.cs new file mode 100644 index 00000000..a05f49a6 --- /dev/null +++ b/src/Merge.Client/Ticketing/TicketingClient.cs @@ -0,0 +1,101 @@ +using Merge.Client; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketingClient +{ + private RawClient _client; + + public TicketingClient(RawClient client) + { + _client = client; + AccountDetails = new AccountDetailsClient(_client); + AccountToken = new AccountTokenClient(_client); + Accounts = new AccountsClient(_client); + AsyncPassthrough = new AsyncPassthroughClient(_client); + Attachments = new AttachmentsClient(_client); + AuditTrail = new AuditTrailClient(_client); + AvailableActions = new AvailableActionsClient(_client); + Collections = new CollectionsClient(_client); + Comments = new CommentsClient(_client); + Contacts = new ContactsClient(_client); + Scopes = new ScopesClient(_client); + DeleteAccount = new DeleteAccountClient(_client); + FieldMapping = new FieldMappingClient(_client); + GenerateKey = new GenerateKeyClient(_client); + Issues = new IssuesClient(_client); + LinkToken = new LinkTokenClient(_client); + LinkedAccounts = new LinkedAccountsClient(_client); + Passthrough = new PassthroughClient(_client); + Projects = new ProjectsClient(_client); + RegenerateKey = new RegenerateKeyClient(_client); + Roles = new RolesClient(_client); + SelectiveSync = new SelectiveSyncClient(_client); + SyncStatus = new SyncStatusClient(_client); + ForceResync = new ForceResyncClient(_client); + Tags = new TagsClient(_client); + Teams = new TeamsClient(_client); + Tickets = new TicketsClient(_client); + Users = new UsersClient(_client); + WebhookReceivers = new WebhookReceiversClient(_client); + } + + public AccountDetailsClient AccountDetails { get; } + + public AccountTokenClient AccountToken { get; } + + public AccountsClient Accounts { get; } + + public AsyncPassthroughClient AsyncPassthrough { get; } + + public AttachmentsClient Attachments { get; } + + public AuditTrailClient AuditTrail { get; } + + public AvailableActionsClient AvailableActions { get; } + + public CollectionsClient Collections { get; } + + public CommentsClient Comments { get; } + + public ContactsClient Contacts { get; } + + public ScopesClient Scopes { get; } + + public DeleteAccountClient DeleteAccount { get; } + + public FieldMappingClient FieldMapping { get; } + + public GenerateKeyClient GenerateKey { get; } + + public IssuesClient Issues { get; } + + public LinkTokenClient LinkToken { get; } + + public LinkedAccountsClient LinkedAccounts { get; } + + public PassthroughClient Passthrough { get; } + + public ProjectsClient Projects { get; } + + public RegenerateKeyClient RegenerateKey { get; } + + public RolesClient Roles { get; } + + public SelectiveSyncClient SelectiveSync { get; } + + public SyncStatusClient SyncStatus { get; } + + public ForceResyncClient ForceResync { get; } + + public TagsClient Tags { get; } + + public TeamsClient Teams { get; } + + public TicketsClient Tickets { get; } + + public UsersClient Users { get; } + + public WebhookReceiversClient WebhookReceivers { get; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/TicketsClient.cs b/src/Merge.Client/Ticketing/Tickets/TicketsClient.cs index 393b022a..df652eed 100644 --- a/src/Merge.Client/Ticketing/Tickets/TicketsClient.cs +++ b/src/Merge.Client/Ticketing/Tickets/TicketsClient.cs @@ -1,21 +1,387 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class TicketsClient { - public async void List(){ + private RawClient _client; + + public TicketsClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `Ticket` objects. + /// + public async Task ListAsync(TicketsListRequest request) + { + var _query = new Dictionary() { }; + if (request.AccountId != null) + { + _query["account_id"] = request.AccountId; + } + if (request.AssigneeIds != null) + { + _query["assignee_ids"] = request.AssigneeIds; + } + if (request.CollectionIds != null) + { + _query["collection_ids"] = request.CollectionIds; + } + if (request.CompletedAfter != null) + { + _query["completed_after"] = request.CompletedAfter; + } + if (request.CompletedBefore != null) + { + _query["completed_before"] = request.CompletedBefore; + } + if (request.ContactId != null) + { + _query["contact_id"] = request.ContactId; + } + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.DueAfter != null) + { + _query["due_after"] = request.DueAfter; + } + if (request.DueBefore != null) + { + _query["due_before"] = request.DueBefore; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.ParentTicketId != null) + { + _query["parent_ticket_id"] = request.ParentTicketId; + } + if (request.Priority != null) + { + _query["priority"] = request.Priority; + } + if (request.RemoteCreatedAfter != null) + { + _query["remote_created_after"] = request.RemoteCreatedAfter; + } + if (request.RemoteCreatedBefore != null) + { + _query["remote_created_before"] = request.RemoteCreatedBefore; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + if (request.RemoteUpdatedAfter != null) + { + _query["remote_updated_after"] = request.RemoteUpdatedAfter; + } + if (request.RemoteUpdatedBefore != null) + { + _query["remote_updated_before"] = request.RemoteUpdatedBefore; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + if (request.Status != null) + { + _query["status"] = request.Status; + } + if (request.Tags != null) + { + _query["tags"] = request.Tags; + } + if (request.TicketType != null) + { + _query["ticket_type"] = request.TicketType; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/tickets", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void Retrieve(){ + + /// + /// Creates a `Ticket` object with the given values. + /// + public async Task CreateAsync(TicketEndpointRequest request) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/tickets", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void PartialUpdate(){ + + /// + /// Returns a `Ticket` object with the given `id`. + /// + public async Task RetrieveAsync(string id, TicketsRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.IncludeRemoteFields != null) + { + _query["include_remote_fields"] = request.IncludeRemoteFields; + } + if (request.RemoteFields != null) + { + _query["remote_fields"] = request.RemoteFields; + } + if (request.ShowEnumOrigins != null) + { + _query["show_enum_origins"] = request.ShowEnumOrigins; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/tickets/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void CollaboratorsList(){ + + /// + /// Updates a `Ticket` object with the given `id`. + /// + public async Task PartialUpdateAsync( + string id, + PatchedTicketEndpointRequest request + ) + { + var _query = new Dictionary() { }; + if (request.IsDebugMode != null) + { + _query["is_debug_mode"] = request.IsDebugMode; + } + if (request.RunAsync != null) + { + _query["run_async"] = request.RunAsync; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Patch, + Path = $"/ticketing/v1/tickets/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPatchRetrieve(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task CollaboratorsListAsync( + string parentId, + TicketsCollaboratorsListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/tickets/{parentId}/collaborators", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void MetaPostRetrieve(){ + + /// + /// Returns metadata for `Ticket` PATCHs. + /// + public async Task MetaPatchRetrieveAsync(string id) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/tickets/meta/patch/{id}" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } - public async void RemoteFieldClassesList(){ + + /// + /// Returns metadata for `Ticket` POSTs. + /// + public async Task MetaPostRetrieveAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/tickets/meta/post" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a list of `RemoteFieldClass` objects. + /// + public async Task RemoteFieldClassesListAsync( + TicketsRemoteFieldClassesListRequest request + ) + { + var _query = new Dictionary() { }; + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/tickets/remote-field-classes", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Tickets/requests/PatchedTicketEndpointRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/PatchedTicketEndpointRequest.cs new file mode 100644 index 00000000..926cc632 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/PatchedTicketEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class PatchedTicketEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public PatchedTicketRequest Model { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/requests/TicketEndpointRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/TicketEndpointRequest.cs new file mode 100644 index 00000000..1e5fb532 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/TicketEndpointRequest.cs @@ -0,0 +1,18 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketEndpointRequest +{ + /// + /// Whether to include debug fields (such as log file links) in the response. + /// + public bool? IsDebugMode { get; init; } + + /// + /// Whether or not third-party updates should be run asynchronously. + /// + public bool? RunAsync { get; init; } + + public TicketRequest Model { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/requests/TicketsCollaboratorsListRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/TicketsCollaboratorsListRequest.cs new file mode 100644 index 00000000..592f3363 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/TicketsCollaboratorsListRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketsCollaboratorsListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TicketsCollaboratorsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/requests/TicketsListRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/TicketsListRequest.cs new file mode 100644 index 00000000..a6bcd1e2 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/TicketsListRequest.cs @@ -0,0 +1,166 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketsListRequest +{ + /// + /// If provided, will only return tickets for this account. + /// + public string? AccountId { get; init; } + + /// + /// If provided, will only return tickets assigned to the assignee_ids; multiple assignee_ids can be separated by commas. + /// + public string? AssigneeIds { get; init; } + + /// + /// If provided, will only return tickets assigned to the collection_ids; multiple collection_ids can be separated by commas. + /// + public string? CollectionIds { get; init; } + + /// + /// If provided, will only return tickets completed after this datetime. + /// + public DateTime? CompletedAfter { get; init; } + + /// + /// If provided, will only return tickets completed before this datetime. + /// + public DateTime? CompletedBefore { get; init; } + + /// + /// If provided, will only return tickets for this contact. + /// + public string? ContactId { get; init; } + + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return tickets due after this datetime. + /// + public DateTime? DueAfter { get; init; } + + /// + /// If provided, will only return tickets due before this datetime. + /// + public DateTime? DueBefore { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TicketsListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// If provided, will only return sub tickets of the parent_ticket_id. + /// + public string? ParentTicketId { get; init; } + + /// + /// If provided, will only return tickets of this priority. + /// + /// - `URGENT` - URGENT + /// - `HIGH` - HIGH + /// - `NORMAL` - NORMAL + /// - `LOW` - LOW + /// + public TicketsListRequestPriority? Priority { get; init; } + + /// + /// If provided, will only return tickets created in the third party platform after this datetime. + /// + public DateTime? RemoteCreatedAfter { get; init; } + + /// + /// If provided, will only return tickets created in the third party platform before this datetime. + /// + public DateTime? RemoteCreatedBefore { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public TicketsListRequestRemoteFields? RemoteFields { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } + + /// + /// If provided, will only return tickets updated in the third party platform after this datetime. + /// + public DateTime? RemoteUpdatedAfter { get; init; } + + /// + /// If provided, will only return tickets updated in the third party platform before this datetime. + /// + public DateTime? RemoteUpdatedBefore { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public TicketsListRequestShowEnumOrigins? ShowEnumOrigins { get; init; } + + /// + /// If provided, will only return tickets of this status. + /// + /// - `OPEN` - OPEN + /// - `CLOSED` - CLOSED + /// - `IN_PROGRESS` - IN_PROGRESS + /// - `ON_HOLD` - ON_HOLD + /// + public TicketsListRequestStatus? Status { get; init; } + + /// + /// If provided, will only return tickets matching the tags; multiple tags can be separated by commas. + /// + public string? Tags { get; init; } + + /// + /// If provided, will only return tickets of this type. + /// + public string? TicketType { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/requests/TicketsRemoteFieldClassesListRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/TicketsRemoteFieldClassesListRequest.cs new file mode 100644 index 00000000..de6bca4d --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/TicketsRemoteFieldClassesListRequest.cs @@ -0,0 +1,24 @@ +namespace Merge.Client.Ticketing; + +public class TicketsRemoteFieldClassesListRequest +{ + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Tickets/requests/TicketsRetrieveRequest.cs b/src/Merge.Client/Ticketing/Tickets/requests/TicketsRetrieveRequest.cs new file mode 100644 index 00000000..4b92f213 --- /dev/null +++ b/src/Merge.Client/Ticketing/Tickets/requests/TicketsRetrieveRequest.cs @@ -0,0 +1,31 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class TicketsRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public TicketsRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// Whether to include all remote fields, including fields that Merge did not map to common models, in a normalized format. + /// + public bool? IncludeRemoteFields { get; init; } + + /// + /// Deprecated. Use show_enum_origins. + /// + public TicketsRetrieveRequestRemoteFields? RemoteFields { get; init; } + + /// + /// A comma separated list of enum field names for which you'd like the original values to be returned, instead of Merge's normalized enum values. [Learn more](https://help.merge.dev/en/articles/8950958-show_enum_origins-query-parameter) + /// + public TicketsRetrieveRequestShowEnumOrigins? ShowEnumOrigins { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/Account.cs b/src/Merge.Client/Ticketing/Types/Account.cs index f1957729..b53c6417 100644 --- a/src/Merge.Client/Ticketing/Types/Account.cs +++ b/src/Merge.Client/Ticketing/Types/Account.cs @@ -14,6 +14,15 @@ public class Account [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The account's name. /// @@ -32,15 +41,6 @@ public class Account [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/AccountDetailsAndActions.cs b/src/Merge.Client/Ticketing/Types/AccountDetailsAndActions.cs index 892625f0..afd8ca80 100644 --- a/src/Merge.Client/Ticketing/Types/AccountDetailsAndActions.cs +++ b/src/Merge.Client/Ticketing/Types/AccountDetailsAndActions.cs @@ -26,6 +26,12 @@ public class AccountDetailsAndActions [JsonPropertyName("end_user_email_address")] public string EndUserEmailAddress { get; init; } + /// + /// The tenant or domain the customer has provided access to. + /// + [JsonPropertyName("subdomain")] + public string? Subdomain { get; init; } + [JsonPropertyName("webhook_listener_url")] public string WebhookListenerUrl { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/AccountIntegration.cs b/src/Merge.Client/Ticketing/Types/AccountIntegration.cs index 14c7334e..c67eed8e 100644 --- a/src/Merge.Client/Ticketing/Types/AccountIntegration.cs +++ b/src/Merge.Client/Ticketing/Types/AccountIntegration.cs @@ -38,12 +38,6 @@ public class AccountIntegration [JsonPropertyName("slug")] public string? Slug { get; init; } - /// - /// If checked, this integration will not appear in the linking flow, and will appear elsewhere with a Beta tag. - /// - [JsonPropertyName("is_in_beta")] - public bool? IsInBeta { get; init; } - /// /// Mapping of API endpoints to documentation urls for support. Example: {'GET': [['/common-model-scopes', 'https://docs.merge.dev/accounting/common-model-scopes/#common_model_scopes_retrieve'],['/common-model-actions', 'https://docs.merge.dev/accounting/common-model-actions/#common_model_actions_retrieve']], 'POST': []} /// @@ -55,4 +49,10 @@ public class AccountIntegration /// [JsonPropertyName("webhook_setup_guide_url")] public string? WebhookSetupGuideUrl { get; init; } + + /// + /// Category or categories this integration is in beta status for. + /// + [JsonPropertyName("category_beta_status")] + public Dictionary? CategoryBetaStatus { get; init; } } diff --git a/src/Merge.Client/Ticketing/Types/AdvancedMetadata.cs b/src/Merge.Client/Ticketing/Types/AdvancedMetadata.cs new file mode 100644 index 00000000..6d3d59ef --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/AdvancedMetadata.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class AdvancedMetadata +{ + [JsonPropertyName("id")] + public string Id { get; init; } + + [JsonPropertyName("display_name")] + public string? DisplayName { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_required")] + public bool? IsRequired { get; init; } + + [JsonPropertyName("is_custom")] + public bool? IsCustom { get; init; } + + [JsonPropertyName("field_choices")] + public List? FieldChoices { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/Attachment.cs b/src/Merge.Client/Ticketing/Types/Attachment.cs index 80548207..e9d43630 100644 --- a/src/Merge.Client/Ticketing/Types/Attachment.cs +++ b/src/Merge.Client/Ticketing/Types/Attachment.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -15,6 +15,15 @@ public class Attachment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The attachment's name. It is required to include the file extension in the attachment's name. /// @@ -54,15 +63,6 @@ public class Attachment [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/AttachmentRequest.cs b/src/Merge.Client/Ticketing/Types/AttachmentRequest.cs index c9406033..49dff497 100644 --- a/src/Merge.Client/Ticketing/Types/AttachmentRequest.cs +++ b/src/Merge.Client/Ticketing/Types/AttachmentRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; diff --git a/src/Merge.Client/Ticketing/Types/AuditLogEvent.cs b/src/Merge.Client/Ticketing/Types/AuditLogEvent.cs index d1a59c9f..54429de7 100644 --- a/src/Merge.Client/Ticketing/Types/AuditLogEvent.cs +++ b/src/Merge.Client/Ticketing/Types/AuditLogEvent.cs @@ -22,7 +22,7 @@ public class AuditLogEvent /// /// Designates the role of the user (or SYSTEM/API if action not taken by a user) at the time of this Event occurring. - /// + /// /// - `ADMIN` - ADMIN /// - `DEVELOPER` - DEVELOPER /// - `MEMBER` - MEMBER @@ -38,7 +38,7 @@ public class AuditLogEvent /// /// Designates the type of event that occurred. - /// + /// /// - `CREATED_REMOTE_PRODUCTION_API_KEY` - CREATED_REMOTE_PRODUCTION_API_KEY /// - `DELETED_REMOTE_PRODUCTION_API_KEY` - DELETED_REMOTE_PRODUCTION_API_KEY /// - `CREATED_TEST_API_KEY` - CREATED_TEST_API_KEY @@ -50,6 +50,7 @@ public class AuditLogEvent /// - `DELETED_LINKED_ACCOUNT` - DELETED_LINKED_ACCOUNT /// - `CREATED_DESTINATION` - CREATED_DESTINATION /// - `DELETED_DESTINATION` - DELETED_DESTINATION + /// - `CHANGED_DESTINATION` - CHANGED_DESTINATION /// - `CHANGED_SCOPES` - CHANGED_SCOPES /// - `CHANGED_PERSONAL_INFORMATION` - CHANGED_PERSONAL_INFORMATION /// - `CHANGED_ORGANIZATION_SETTINGS` - CHANGED_ORGANIZATION_SETTINGS @@ -69,6 +70,9 @@ public class AuditLogEvent /// - `CHANGED_LINKED_ACCOUNT_FIELD_MAPPING` - CHANGED_LINKED_ACCOUNT_FIELD_MAPPING /// - `DELETED_INTEGRATION_WIDE_FIELD_MAPPING` - DELETED_INTEGRATION_WIDE_FIELD_MAPPING /// - `DELETED_LINKED_ACCOUNT_FIELD_MAPPING` - DELETED_LINKED_ACCOUNT_FIELD_MAPPING + /// - `FORCED_LINKED_ACCOUNT_RESYNC` - FORCED_LINKED_ACCOUNT_RESYNC + /// - `MUTED_ISSUE` - MUTED_ISSUE + /// - `GENERATED_MAGIC_LINK` - GENERATED_MAGIC_LINK /// [JsonPropertyName("event_type")] public EventTypeEnum EventType { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/Collection.cs b/src/Merge.Client/Ticketing/Types/Collection.cs index 7cb92ce1..008e8512 100644 --- a/src/Merge.Client/Ticketing/Types/Collection.cs +++ b/src/Merge.Client/Ticketing/Types/Collection.cs @@ -15,6 +15,15 @@ public class Collection [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The collection's name. /// @@ -29,7 +38,7 @@ public class Collection /// /// The collection's type. - /// + /// /// - `LIST` - LIST /// - `PROJECT` - PROJECT /// @@ -50,7 +59,7 @@ public class Collection /// /// The level of access a User has to the Collection and its sub-objects. - /// + /// /// - `PRIVATE` - PRIVATE /// - `COMPANY` - COMPANY /// - `PUBLIC` - PUBLIC @@ -58,15 +67,6 @@ public class Collection [JsonPropertyName("access_level")] public AccessLevelEnum? AccessLevel { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/Comment.cs b/src/Merge.Client/Ticketing/Types/Comment.cs index 10b47185..b5d959ce 100644 --- a/src/Merge.Client/Ticketing/Types/Comment.cs +++ b/src/Merge.Client/Ticketing/Types/Comment.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -15,6 +15,15 @@ public class Comment [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The author of the Comment, if the author is a User. /// @@ -60,15 +69,6 @@ public class Comment [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/CommentRequest.cs b/src/Merge.Client/Ticketing/Types/CommentRequest.cs index 7119a8e1..2a9f3c91 100644 --- a/src/Merge.Client/Ticketing/Types/CommentRequest.cs +++ b/src/Merge.Client/Ticketing/Types/CommentRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; diff --git a/src/Merge.Client/Ticketing/Types/CommonModelScopeApi.cs b/src/Merge.Client/Ticketing/Types/CommonModelScopeApi.cs new file mode 100644 index 00000000..f370bfbc --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/CommonModelScopeApi.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class CommonModelScopeApi +{ + /// + /// The common models you want to update the scopes for + /// + [JsonPropertyName("common_models")] + public List CommonModels { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/ConditionSchema.cs b/src/Merge.Client/Ticketing/Types/ConditionSchema.cs index 08376956..a68fb709 100644 --- a/src/Merge.Client/Ticketing/Types/ConditionSchema.cs +++ b/src/Merge.Client/Ticketing/Types/ConditionSchema.cs @@ -17,15 +17,9 @@ public class ConditionSchema [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } @@ -37,7 +31,7 @@ public class ConditionSchema /// /// The type of value(s) that can be set for this condition. - /// + /// /// - `BOOLEAN` - BOOLEAN /// - `DATE` - DATE /// - `DATE_TIME` - DATE_TIME diff --git a/src/Merge.Client/Ticketing/Types/Contact.cs b/src/Merge.Client/Ticketing/Types/Contact.cs index 3f205717..1e88bd73 100644 --- a/src/Merge.Client/Ticketing/Types/Contact.cs +++ b/src/Merge.Client/Ticketing/Types/Contact.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -15,6 +15,15 @@ public class Contact [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The contact's name. /// @@ -51,15 +60,6 @@ public class Contact [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/DataPassthroughRequest.cs b/src/Merge.Client/Ticketing/Types/DataPassthroughRequest.cs index d3046548..1195b23e 100644 --- a/src/Merge.Client/Ticketing/Types/DataPassthroughRequest.cs +++ b/src/Merge.Client/Ticketing/Types/DataPassthroughRequest.cs @@ -8,12 +8,21 @@ public class DataPassthroughRequest [JsonPropertyName("method")] public MethodEnum Method { get; init; } + /// + /// The path of the request in the third party's platform. + /// [JsonPropertyName("path")] public string Path { get; init; } + /// + /// An optional override of the third party's base url for the request. + /// [JsonPropertyName("base_url_override")] public string? BaseUrlOverride { get; init; } + /// + /// The data with the request. You must include a `request_format` parameter matching the data's format + /// [JsonPropertyName("data")] public string? Data { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/EventTypeEnum.cs b/src/Merge.Client/Ticketing/Types/EventTypeEnum.cs index dda7afb1..364ff1ee 100644 --- a/src/Merge.Client/Ticketing/Types/EventTypeEnum.cs +++ b/src/Merge.Client/Ticketing/Types/EventTypeEnum.cs @@ -37,6 +37,9 @@ public enum EventTypeEnum [EnumMember(Value = "DELETED_DESTINATION")] DeletedDestination, + [EnumMember(Value = "CHANGED_DESTINATION")] + ChangedDestination, + [EnumMember(Value = "CHANGED_SCOPES")] ChangedScopes, @@ -92,5 +95,14 @@ public enum EventTypeEnum DeletedIntegrationWideFieldMapping, [EnumMember(Value = "DELETED_LINKED_ACCOUNT_FIELD_MAPPING")] - DeletedLinkedAccountFieldMapping + DeletedLinkedAccountFieldMapping, + + [EnumMember(Value = "FORCED_LINKED_ACCOUNT_RESYNC")] + ForcedLinkedAccountResync, + + [EnumMember(Value = "MUTED_ISSUE")] + MutedIssue, + + [EnumMember(Value = "GENERATED_MAGIC_LINK")] + GeneratedMagicLink } diff --git a/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApi.cs b/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApi.cs new file mode 100644 index 00000000..9ceb2cc2 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApi.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class ExternalTargetFieldApi +{ + [JsonPropertyName("name")] + public string? Name { get; init; } + + [JsonPropertyName("description")] + public string? Description { get; init; } + + [JsonPropertyName("is_mapped")] + public string? IsMapped { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApiResponse.cs b/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApiResponse.cs new file mode 100644 index 00000000..01511ae5 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/ExternalTargetFieldApiResponse.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class ExternalTargetFieldApiResponse +{ + [JsonPropertyName("Ticket")] + public List? Ticket { get; init; } + + [JsonPropertyName("Comment")] + public List? Comment { get; init; } + + [JsonPropertyName("Project")] + public List? Project { get; init; } + + [JsonPropertyName("Collection")] + public List? Collection { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Role")] + public List? Role { get; init; } + + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingApiInstance.cs b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstance.cs new file mode 100644 index 00000000..dfd263cb --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstance.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class FieldMappingApiInstance +{ + [JsonPropertyName("id")] + public string? Id { get; init; } + + [JsonPropertyName("is_integration_wide")] + public bool? IsIntegrationWide { get; init; } + + [JsonPropertyName("target_field")] + public FieldMappingApiInstanceTargetField? TargetField { get; init; } + + [JsonPropertyName("remote_field")] + public FieldMappingApiInstanceRemoteField? RemoteField { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteField.cs b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteField.cs new file mode 100644 index 00000000..ebb7dff1 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteField.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class FieldMappingApiInstanceRemoteField +{ + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo RemoteEndpointInfo { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs new file mode 100644 index 00000000..22d2d184 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class FieldMappingApiInstanceRemoteFieldRemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string? Method { get; init; } + + [JsonPropertyName("url_path")] + public string? UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List? FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceResponse.cs b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceResponse.cs new file mode 100644 index 00000000..26d98989 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceResponse.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class FieldMappingApiInstanceResponse +{ + [JsonPropertyName("Ticket")] + public List? Ticket { get; init; } + + [JsonPropertyName("Comment")] + public List? Comment { get; init; } + + [JsonPropertyName("Project")] + public List? Project { get; init; } + + [JsonPropertyName("Collection")] + public List? Collection { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Role")] + public List? Role { get; init; } + + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceTargetField.cs b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceTargetField.cs new file mode 100644 index 00000000..4c4eaad1 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingApiInstanceTargetField.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class FieldMappingApiInstanceTargetField +{ + [JsonPropertyName("name")] + public string Name { get; init; } + + [JsonPropertyName("description")] + public string Description { get; init; } + + [JsonPropertyName("is_organization_wide")] + public bool IsOrganizationWide { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldMappingInstanceResponse.cs b/src/Merge.Client/Ticketing/Types/FieldMappingInstanceResponse.cs new file mode 100644 index 00000000..9e5b1f48 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldMappingInstanceResponse.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class FieldMappingInstanceResponse +{ + [JsonPropertyName("model")] + public FieldMappingApiInstance Model { get; init; } + + [JsonPropertyName("warnings")] + public List Warnings { get; init; } + + [JsonPropertyName("errors")] + public List Errors { get; init; } + + [JsonPropertyName("logs")] + public List? Logs { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializer.cs b/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializer.cs new file mode 100644 index 00000000..d84a7309 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializer.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class FieldPermissionDeserializer +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializerRequest.cs b/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializerRequest.cs new file mode 100644 index 00000000..d39dc223 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/FieldPermissionDeserializerRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class FieldPermissionDeserializerRequest +{ + [JsonPropertyName("enabled")] + public List? Enabled { get; init; } + + [JsonPropertyName("disabled")] + public List? Disabled { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializer.cs b/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializer.cs new file mode 100644 index 00000000..c4c4adce --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializer.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class IndividualCommonModelScopeDeserializer +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializer? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializerRequest.cs b/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializerRequest.cs new file mode 100644 index 00000000..052caf78 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/IndividualCommonModelScopeDeserializerRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class IndividualCommonModelScopeDeserializerRequest +{ + [JsonPropertyName("model_name")] + public string ModelName { get; init; } + + [JsonPropertyName("model_permissions")] + public Dictionary? ModelPermissions { get; init; } + + [JsonPropertyName("field_permissions")] + public FieldPermissionDeserializerRequest? FieldPermissions { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/Issue.cs b/src/Merge.Client/Ticketing/Types/Issue.cs index 0f38c7ab..7f565669 100644 --- a/src/Merge.Client/Ticketing/Types/Issue.cs +++ b/src/Merge.Client/Ticketing/Types/Issue.cs @@ -10,7 +10,7 @@ public class Issue /// /// Status of the issue. Options: ('ONGOING', 'RESOLVED') - /// + /// /// - `ONGOING` - ONGOING /// - `RESOLVED` - RESOLVED /// diff --git a/src/Merge.Client/Ticketing/Types/LinkedAccountCondition.cs b/src/Merge.Client/Ticketing/Types/LinkedAccountCondition.cs index 44ed8ae7..1c6c642d 100644 --- a/src/Merge.Client/Ticketing/Types/LinkedAccountCondition.cs +++ b/src/Merge.Client/Ticketing/Types/LinkedAccountCondition.cs @@ -16,9 +16,6 @@ public class LinkedAccountCondition [JsonPropertyName("common_model")] public string? CommonModel { get; init; } - /// - /// User-facing _native condition_ name. e.g. "Skip Manager". - /// [JsonPropertyName("native_name")] public string? NativeName { get; init; } @@ -31,9 +28,6 @@ public class LinkedAccountCondition [JsonPropertyName("value")] public object? Value { get; init; } - /// - /// The name of the field on the common model that this condition corresponds to, if they conceptually match. e.g. "location_type". - /// [JsonPropertyName("field_name")] public string? FieldName { get; init; } } diff --git a/src/Merge.Client/Ticketing/Types/LinkedAccountConditionRequest.cs b/src/Merge.Client/Ticketing/Types/LinkedAccountConditionRequest.cs index 586c4733..de6ced22 100644 --- a/src/Merge.Client/Ticketing/Types/LinkedAccountConditionRequest.cs +++ b/src/Merge.Client/Ticketing/Types/LinkedAccountConditionRequest.cs @@ -4,6 +4,12 @@ namespace Merge.Client.Ticketing; public class LinkedAccountConditionRequest { + /// + /// The ID indicating which Linked Account Condition this is. + /// + [JsonPropertyName("id")] + public string? Id { get; init; } + /// /// The ID indicating which condition schema to use for a specific condition. /// diff --git a/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializer.cs b/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializer.cs new file mode 100644 index 00000000..c4e56a79 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializer.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class ModelPermissionDeserializer +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializerRequest.cs b/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializerRequest.cs new file mode 100644 index 00000000..7a1a1e33 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/ModelPermissionDeserializerRequest.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class ModelPermissionDeserializerRequest +{ + [JsonPropertyName("is_enabled")] + public bool? IsEnabled { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/MultipartFormFieldRequest.cs b/src/Merge.Client/Ticketing/Types/MultipartFormFieldRequest.cs index 89ac42d5..be14e6a9 100644 --- a/src/Merge.Client/Ticketing/Types/MultipartFormFieldRequest.cs +++ b/src/Merge.Client/Ticketing/Types/MultipartFormFieldRequest.cs @@ -19,7 +19,7 @@ public class MultipartFormFieldRequest /// /// The encoding of the value of `data`. Defaults to `RAW` if not defined. - /// + /// /// - `RAW` - RAW /// - `BASE64` - BASE64 /// - `GZIP_BASE64` - GZIP_BASE64 diff --git a/src/Merge.Client/Ticketing/Types/PatchedTicketRequest.cs b/src/Merge.Client/Ticketing/Types/PatchedTicketRequest.cs index ea767aef..a18fedee 100644 --- a/src/Merge.Client/Ticketing/Types/PatchedTicketRequest.cs +++ b/src/Merge.Client/Ticketing/Types/PatchedTicketRequest.cs @@ -28,7 +28,7 @@ public class PatchedTicketRequest /// /// The current status of the ticket. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// - `IN_PROGRESS` - IN_PROGRESS @@ -47,7 +47,7 @@ public class PatchedTicketRequest public List? Collections { get; init; } /// - /// The ticket's type. + /// The sub category of the ticket within the 3rd party system. Examples include incident, task, subtask or to-do. /// [JsonPropertyName("ticket_type")] public string? TicketType { get; init; } @@ -87,7 +87,7 @@ public class PatchedTicketRequest /// /// The priority or urgency of the Ticket. - /// + /// /// - `URGENT` - URGENT /// - `HIGH` - HIGH /// - `NORMAL` - NORMAL diff --git a/src/Merge.Client/Ticketing/Types/Project.cs b/src/Merge.Client/Ticketing/Types/Project.cs index 155308b3..fabe1cb5 100644 --- a/src/Merge.Client/Ticketing/Types/Project.cs +++ b/src/Merge.Client/Ticketing/Types/Project.cs @@ -14,6 +14,15 @@ public class Project [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The project's name. /// @@ -32,15 +41,6 @@ public class Project [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/RemoteEndpointInfo.cs b/src/Merge.Client/Ticketing/Types/RemoteEndpointInfo.cs new file mode 100644 index 00000000..2e4249d0 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/RemoteEndpointInfo.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Merge.Client.Ticketing; + +public class RemoteEndpointInfo +{ + [JsonPropertyName("method")] + public string Method { get; init; } + + [JsonPropertyName("url_path")] + public string UrlPath { get; init; } + + [JsonPropertyName("field_traversal_path")] + public List FieldTraversalPath { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/RemoteField.cs b/src/Merge.Client/Ticketing/Types/RemoteField.cs index afaa9d06..e0af87f1 100644 --- a/src/Merge.Client/Ticketing/Types/RemoteField.cs +++ b/src/Merge.Client/Ticketing/Types/RemoteField.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; diff --git a/src/Merge.Client/Ticketing/Types/RemoteFieldApi.cs b/src/Merge.Client/Ticketing/Types/RemoteFieldApi.cs new file mode 100644 index 00000000..0fb95616 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/RemoteFieldApi.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class RemoteFieldApi +{ + [JsonPropertyName("schema")] + public Dictionary Schema { get; init; } + + [JsonPropertyName("remote_key_name")] + public string RemoteKeyName { get; init; } + + [JsonPropertyName("remote_endpoint_info")] + public RemoteEndpointInfo RemoteEndpointInfo { get; init; } + + [JsonPropertyName("example_values")] + public List ExampleValues { get; init; } + + [JsonPropertyName("advanced_metadata")] + public AdvancedMetadata? AdvancedMetadata { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/RemoteFieldApiResponse.cs b/src/Merge.Client/Ticketing/Types/RemoteFieldApiResponse.cs new file mode 100644 index 00000000..0fabe198 --- /dev/null +++ b/src/Merge.Client/Ticketing/Types/RemoteFieldApiResponse.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class RemoteFieldApiResponse +{ + [JsonPropertyName("Ticket")] + public List? Ticket { get; init; } + + [JsonPropertyName("Comment")] + public List? Comment { get; init; } + + [JsonPropertyName("Project")] + public List? Project { get; init; } + + [JsonPropertyName("Collection")] + public List? Collection { get; init; } + + [JsonPropertyName("User")] + public List? User { get; init; } + + [JsonPropertyName("Role")] + public List? Role { get; init; } + + [JsonPropertyName("Account")] + public List? Account { get; init; } + + [JsonPropertyName("Team")] + public List? Team { get; init; } + + [JsonPropertyName("Attachment")] + public List? Attachment { get; init; } + + [JsonPropertyName("Tag")] + public List? Tag { get; init; } + + [JsonPropertyName("Contact")] + public List? Contact { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Types/RemoteFieldRequest.cs b/src/Merge.Client/Ticketing/Types/RemoteFieldRequest.cs index bb4adb1a..7b6f4b21 100644 --- a/src/Merge.Client/Ticketing/Types/RemoteFieldRequest.cs +++ b/src/Merge.Client/Ticketing/Types/RemoteFieldRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; diff --git a/src/Merge.Client/Ticketing/Types/Role.cs b/src/Merge.Client/Ticketing/Types/Role.cs index c23f0413..57d77a8e 100644 --- a/src/Merge.Client/Ticketing/Types/Role.cs +++ b/src/Merge.Client/Ticketing/Types/Role.cs @@ -14,6 +14,15 @@ public class Role [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The name of the Role. /// @@ -28,7 +37,7 @@ public class Role /// /// The level of Ticket access that a User with this Role can perform. - /// + /// /// - `ALL` - ALL /// - `ASSIGNED_ONLY` - ASSIGNED_ONLY /// - `TEAM_ONLY` - TEAM_ONLY @@ -42,15 +51,6 @@ public class Role [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/Tag.cs b/src/Merge.Client/Ticketing/Types/Tag.cs index 84b91502..4d4aa360 100644 --- a/src/Merge.Client/Ticketing/Types/Tag.cs +++ b/src/Merge.Client/Ticketing/Types/Tag.cs @@ -11,6 +11,15 @@ public class Tag [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The tag's name. /// @@ -23,15 +32,6 @@ public class Tag [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/Team.cs b/src/Merge.Client/Ticketing/Types/Team.cs index 85998edd..a677a02f 100644 --- a/src/Merge.Client/Ticketing/Types/Team.cs +++ b/src/Merge.Client/Ticketing/Types/Team.cs @@ -14,6 +14,15 @@ public class Team [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The team's name. /// @@ -32,15 +41,6 @@ public class Team [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/Ticket.cs b/src/Merge.Client/Ticketing/Types/Ticket.cs index 3b29c2e9..c842e7f4 100644 --- a/src/Merge.Client/Ticketing/Types/Ticket.cs +++ b/src/Merge.Client/Ticketing/Types/Ticket.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -15,6 +15,15 @@ public class Ticket [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The ticket's name. /// @@ -38,7 +47,7 @@ public class Ticket /// /// The current status of the ticket. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// - `IN_PROGRESS` - IN_PROGRESS @@ -57,7 +66,7 @@ public class Ticket public List?>? Collections { get; init; } /// - /// The ticket's type. + /// The sub category of the ticket within the 3rd party system. Examples include incident, task, subtask or to-do. /// [JsonPropertyName("ticket_type")] public string? TicketType { get; init; } @@ -115,7 +124,7 @@ public class Ticket /// /// The priority or urgency of the Ticket. - /// + /// /// - `URGENT` - URGENT /// - `HIGH` - HIGH /// - `NORMAL` - NORMAL @@ -124,15 +133,6 @@ public class Ticket [JsonPropertyName("priority")] public PriorityEnum? Priority { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Types/TicketRequest.cs b/src/Merge.Client/Ticketing/Types/TicketRequest.cs index 72503351..fe65d6fe 100644 --- a/src/Merge.Client/Ticketing/Types/TicketRequest.cs +++ b/src/Merge.Client/Ticketing/Types/TicketRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -29,7 +29,7 @@ public class TicketRequest /// /// The current status of the ticket. - /// + /// /// - `OPEN` - OPEN /// - `CLOSED` - CLOSED /// - `IN_PROGRESS` - IN_PROGRESS @@ -48,7 +48,7 @@ public class TicketRequest public List?>? Collections { get; init; } /// - /// The ticket's type. + /// The sub category of the ticket within the 3rd party system. Examples include incident, task, subtask or to-do. /// [JsonPropertyName("ticket_type")] public string? TicketType { get; init; } @@ -91,7 +91,7 @@ public class TicketRequest /// /// The priority or urgency of the Ticket. - /// + /// /// - `URGENT` - URGENT /// - `HIGH` - HIGH /// - `NORMAL` - NORMAL diff --git a/src/Merge.Client/Ticketing/Types/User.cs b/src/Merge.Client/Ticketing/Types/User.cs index 861922b6..66ce7d48 100644 --- a/src/Merge.Client/Ticketing/Types/User.cs +++ b/src/Merge.Client/Ticketing/Types/User.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -using OneOf; using Merge.Client.Ticketing; +using OneOf; namespace Merge.Client.Ticketing; @@ -15,6 +15,15 @@ public class User [JsonPropertyName("remote_id")] public string? RemoteId { get; init; } + [JsonPropertyName("created_at")] + public DateTime? CreatedAt { get; init; } + + /// + /// This is the datetime that this object was last updated by Merge + /// + [JsonPropertyName("modified_at")] + public DateTime? ModifiedAt { get; init; } + /// /// The user's name. /// @@ -51,15 +60,6 @@ public class User [JsonPropertyName("remote_was_deleted")] public bool? RemoteWasDeleted { get; init; } - [JsonPropertyName("created_at")] - public DateTime? CreatedAt { get; init; } - - /// - /// This is the datetime that this object was last updated by Merge - /// - [JsonPropertyName("modified_at")] - public DateTime? ModifiedAt { get; init; } - [JsonPropertyName("field_mappings")] public Dictionary? FieldMappings { get; init; } diff --git a/src/Merge.Client/Ticketing/Users/UsersClient.cs b/src/Merge.Client/Ticketing/Users/UsersClient.cs index 547cc9b8..9949f65c 100644 --- a/src/Merge.Client/Ticketing/Users/UsersClient.cs +++ b/src/Merge.Client/Ticketing/Users/UsersClient.cs @@ -1,9 +1,111 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class UsersClient { - public async void List(){ + private RawClient _client; + + public UsersClient(RawClient client) + { + _client = client; } - public async void Retrieve(){ + + /// + /// Returns a list of `User` objects. + /// + public async Task ListAsync(UsersListRequest request) + { + var _query = new Dictionary() { }; + if (request.CreatedAfter != null) + { + _query["created_after"] = request.CreatedAfter; + } + if (request.CreatedBefore != null) + { + _query["created_before"] = request.CreatedBefore; + } + if (request.Cursor != null) + { + _query["cursor"] = request.Cursor; + } + if (request.EmailAddress != null) + { + _query["email_address"] = request.EmailAddress; + } + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeDeletedData != null) + { + _query["include_deleted_data"] = request.IncludeDeletedData; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + if (request.ModifiedAfter != null) + { + _query["modified_after"] = request.ModifiedAfter; + } + if (request.ModifiedBefore != null) + { + _query["modified_before"] = request.ModifiedBefore; + } + if (request.PageSize != null) + { + _query["page_size"] = request.PageSize; + } + if (request.RemoteId != null) + { + _query["remote_id"] = request.RemoteId; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/users", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); + } + + /// + /// Returns a `User` object with the given `id`. + /// + public async Task RetrieveAsync(string id, UsersRetrieveRequest request) + { + var _query = new Dictionary() { }; + if (request.Expand != null) + { + _query["expand"] = request.Expand; + } + if (request.IncludeRemoteData != null) + { + _query["include_remote_data"] = request.IncludeRemoteData; + } + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = $"/ticketing/v1/users/{id}", + Query = _query + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/Users/requests/UsersListRequest.cs b/src/Merge.Client/Ticketing/Users/requests/UsersListRequest.cs new file mode 100644 index 00000000..6bcdc14a --- /dev/null +++ b/src/Merge.Client/Ticketing/Users/requests/UsersListRequest.cs @@ -0,0 +1,61 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class UsersListRequest +{ + /// + /// If provided, will only return objects created after this datetime. + /// + public DateTime? CreatedAfter { get; init; } + + /// + /// If provided, will only return objects created before this datetime. + /// + public DateTime? CreatedBefore { get; init; } + + /// + /// The pagination cursor value. + /// + public string? Cursor { get; init; } + + /// + /// If provided, will only return users with emails equal to this value (case insensitive). + /// + public string? EmailAddress { get; init; } + + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public UsersListRequestExpand? Expand { get; init; } + + /// + /// Whether to include data that was marked as deleted by third party webhooks. + /// + public bool? IncludeDeletedData { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } + + /// + /// If provided, only objects synced by Merge after this date time will be returned. + /// + public DateTime? ModifiedAfter { get; init; } + + /// + /// If provided, only objects synced by Merge before this date time will be returned. + /// + public DateTime? ModifiedBefore { get; init; } + + /// + /// Number of results to return per page. + /// + public int? PageSize { get; init; } + + /// + /// The API provider's ID for the given object. + /// + public string? RemoteId { get; init; } +} diff --git a/src/Merge.Client/Ticketing/Users/requests/UsersRetrieveRequest.cs b/src/Merge.Client/Ticketing/Users/requests/UsersRetrieveRequest.cs new file mode 100644 index 00000000..a3b79c10 --- /dev/null +++ b/src/Merge.Client/Ticketing/Users/requests/UsersRetrieveRequest.cs @@ -0,0 +1,16 @@ +using Merge.Client.Ticketing; + +namespace Merge.Client.Ticketing; + +public class UsersRetrieveRequest +{ + /// + /// Which relations should be returned in expanded form. Multiple relation names should be comma separated without spaces. + /// + public UsersRetrieveRequestExpand? Expand { get; init; } + + /// + /// Whether to include the original data Merge fetched from the third-party to produce these models. + /// + public bool? IncludeRemoteData { get; init; } +} diff --git a/src/Merge.Client/Ticketing/WebhookReceivers/WebhookReceiversClient.cs b/src/Merge.Client/Ticketing/WebhookReceivers/WebhookReceiversClient.cs index d58ec33a..10c7e3d4 100644 --- a/src/Merge.Client/Ticketing/WebhookReceivers/WebhookReceiversClient.cs +++ b/src/Merge.Client/Ticketing/WebhookReceivers/WebhookReceiversClient.cs @@ -1,9 +1,56 @@ +using System.Text.Json; +using Merge.Client; +using Merge.Client.Ticketing; + namespace Merge.Client.Ticketing; public class WebhookReceiversClient { - public async void List(){ + private RawClient _client; + + public WebhookReceiversClient(RawClient client) + { + _client = client; } - public async void Create(){ + + /// + /// Returns a list of `WebhookReceiver` objects. + /// + public async Task> ListAsync() + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Get, + Path = "/ticketing/v1/webhook-receivers" + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize>(responseBody); + } + throw new Exception(); + } + + /// + /// Creates a `WebhookReceiver` object with the given values. + /// + public async Task CreateAsync(WebhookReceiverRequest request) + { + var response = await _client.MakeRequestAsync( + new RawClient.ApiRequest + { + Method = HttpMethod.Post, + Path = "/ticketing/v1/webhook-receivers", + Body = request + } + ); + string responseBody = await response.Raw.Content.ReadAsStringAsync(); + if (response.StatusCode >= 200 && response.StatusCode < 400) + { + return JsonSerializer.Deserialize(responseBody); + } + throw new Exception(); } } diff --git a/src/Merge.Client/Ticketing/WebhookReceivers/requests/WebhookReceiverRequest.cs b/src/Merge.Client/Ticketing/WebhookReceivers/requests/WebhookReceiverRequest.cs new file mode 100644 index 00000000..0da0a8b3 --- /dev/null +++ b/src/Merge.Client/Ticketing/WebhookReceivers/requests/WebhookReceiverRequest.cs @@ -0,0 +1,10 @@ +namespace Merge.Client.Ticketing; + +public class WebhookReceiverRequest +{ + public string Event { get; init; } + + public bool IsActive { get; init; } + + public string? Key { get; init; } +}